46setState(prev => ({ ...prev, loading: true, error: null }));
47
48let url = '/api/products';
49if (state.searchQuery) {
50url = `/api/products/search/${encodeURIComponent(state.searchQuery)}`;
51} else if (state.selectedCategory) {
52url = `/api/products/category/${encodeURIComponent(state.selectedCategory)}`;
53}
54
68const loadCart = async () => {
69try {
70const response = await fetch(`/api/cart/${state.sessionId}`);
71const result = await response.json();
72
81const addToCart = async (productId: number, quantity: number = 1) => {
82try {
83const response = await fetch(`/api/cart/${state.sessionId}/add`, {
84method: 'POST',
85headers: { 'Content-Type': 'application/json' },
102const updateCartItem = async (productId: number, quantity: number) => {
103try {
104const response = await fetch(`/api/cart/${state.sessionId}/update`, {
105method: 'PUT',
106headers: { 'Content-Type': 'application/json' },
121const removeFromCart = async (productId: number) => {
122try {
123const response = await fetch(`/api/cart/${state.sessionId}/remove/${productId}`, {
124method: 'DELETE'
125});
139const completeOrder = async (orderData: any) => {
140try {
141const response = await fetch('/api/orders', {
142method: 'POST',
143headers: { 'Content-Type': 'application/json' },
6getAllChatRooms
7} from "../database/queries.ts";
8import type { ApiResponse, ChatMessage, ChatRoom } from "../../shared/types.ts";
910const app = new Hono();
21const messages = await getChatMessages(roomId, limit);
22
23const response: ApiResponse<ChatMessage[]> = {
24success: true,
25data: messages.reverse() // Reverse to show oldest first
27return c.json(response);
28} catch (error) {
29const response: ApiResponse<ChatMessage[]> = {
30success: false,
31error: "Failed to fetch messages"
42
43if (!roomId || !senderName || !senderType || !message) {
44const response: ApiResponse<ChatMessage> = {
45success: false,
46error: "Room ID, sender name, sender type, and message are required"
5051if (!['customer', 'admin'].includes(senderType)) {
52const response: ApiResponse<ChatMessage> = {
53success: false,
54error: "Sender type must be 'customer' or 'admin'"
80}
8182const response: ApiResponse<ChatMessage> = {
83success: true,
84data: newMessage
87} catch (error) {
88console.error("Chat message error:", error);
89const response: ApiResponse<ChatMessage> = {
90success: false,
91error: "Failed to send message"
128const room = await getChatRoom(roomId);
129
130const response: ApiResponse<ChatRoom | null> = {
131success: true,
132data: room
134return c.json(response);
135} catch (error) {
136const response: ApiResponse<ChatRoom> = {
137success: false,
138error: "Failed to fetch chat room"
147const rooms = await getAllChatRooms();
148
149const response: ApiResponse<ChatRoom[]> = {
150success: true,
151data: rooms
153return c.json(response);
154} catch (error) {
155const response: ApiResponse<ChatRoom[]> = {
156success: false,
157error: "Failed to fetch chat rooms"
8clearCart
9} from "../database/queries.ts";
10import type { ApiResponse, Order, OrderItem, CheckoutData } from "../../shared/types.ts";
1112const app = new Hono();
21// Validate required fields
22if (!customerName || !customerEmail || !customerAddress) {
23const response: ApiResponse<Order> = {
24success: false,
25error: "Customer name, email, and address are required"
2930if (!cartItems || cartItems.length === 0) {
31const response: ApiResponse<Order> = {
32success: false,
33error: "Cart is empty"
54const order = await getOrderById(orderId);
55
56const response: ApiResponse<Order> = {
57success: true,
58data: order!
61} catch (error) {
62console.error("Order creation error:", error);
63const response: ApiResponse<Order> = {
64success: false,
65error: "Failed to create order"
74const id = parseInt(c.req.param("id"));
75if (isNaN(id)) {
76const response: ApiResponse<Order> = {
77success: false,
78error: "Invalid order ID"
83const order = await getOrderById(id);
84if (!order) {
85const response: ApiResponse<Order> = {
86success: false,
87error: "Order not found"
90}
9192const response: ApiResponse<Order> = {
93success: true,
94data: order
96return c.json(response);
97} catch (error) {
98const response: ApiResponse<Order> = {
99success: false,
100error: "Failed to fetch order"
109const id = parseInt(c.req.param("id"));
110if (isNaN(id)) {
111const response: ApiResponse<OrderItem[]> = {
112success: false,
113error: "Invalid order ID"
118const items = await getOrderItems(id);
119
120const response: ApiResponse<OrderItem[]> = {
121success: true,
122data: items
124return c.json(response);
125} catch (error) {
126const response: ApiResponse<OrderItem[]> = {
127success: false,
128error: "Failed to fetch order items"
7clearCart
8} from "../database/queries.ts";
9import type { ApiResponse, CartSummary, CartItem } from "../../shared/types.ts";
1011const app = new Hono();
27};
2829const response: ApiResponse<CartSummary> = {
30success: true,
31data: cartSummary
33return c.json(response);
34} catch (error) {
35const response: ApiResponse<CartSummary> = {
36success: false,
37error: "Failed to fetch cart"
50
51if (!productId || typeof productId !== "number") {
52const response: ApiResponse<void> = {
53success: false,
54error: "Product ID is required"
5859if (quantity <= 0) {
60const response: ApiResponse<void> = {
61success: false,
62error: "Quantity must be greater than 0"
67await addToCart(sessionId, productId, quantity);
68
69const response: ApiResponse<void> = {
70success: true
71};
72return c.json(response);
73} catch (error) {
74const response: ApiResponse<void> = {
75success: false,
76error: "Failed to add item to cart"
89
90if (!productId || typeof productId !== "number") {
91const response: ApiResponse<void> = {
92success: false,
93error: "Product ID is required"
9798if (typeof quantity !== "number" || quantity < 0) {
99const response: ApiResponse<void> = {
100success: false,
101error: "Valid quantity is required"
106await updateCartItem(sessionId, productId, quantity);
107
108const response: ApiResponse<void> = {
109success: true
110};
111return c.json(response);
112} catch (error) {
113const response: ApiResponse<void> = {
114success: false,
115error: "Failed to update cart item"
126
127if (isNaN(productId)) {
128const response: ApiResponse<void> = {
129success: false,
130error: "Invalid product ID"
135await removeFromCart(sessionId, productId);
136
137const response: ApiResponse<void> = {
138success: true
139};
140return c.json(response);
141} catch (error) {
142const response: ApiResponse<void> = {
143success: false,
144error: "Failed to remove item from cart"
154await clearCart(sessionId);
155
156const response: ApiResponse<void> = {
157success: true
158};
159return c.json(response);
160} catch (error) {
161const response: ApiResponse<void> = {
162success: false,
163error: "Failed to clear cart"
Appproducts.ts12 matches
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { getAllProducts, getProductById, getProductsByCategory, searchProducts } from "../database/queries.ts";
3import type { ApiResponse, Product } from "../../shared/types.ts";
45const app = new Hono();
9try {
10const products = await getAllProducts();
11const response: ApiResponse<Product[]> = {
12success: true,
13data: products
15return c.json(response);
16} catch (error) {
17const response: ApiResponse<Product[]> = {
18success: false,
19error: "Failed to fetch products"
28const id = parseInt(c.req.param("id"));
29if (isNaN(id)) {
30const response: ApiResponse<Product> = {
31success: false,
32error: "Invalid product ID"
37const product = await getProductById(id);
38if (!product) {
39const response: ApiResponse<Product> = {
40success: false,
41error: "Product not found"
44}
4546const response: ApiResponse<Product> = {
47success: true,
48data: product
50return c.json(response);
51} catch (error) {
52const response: ApiResponse<Product> = {
53success: false,
54error: "Failed to fetch product"
64const products = await getProductsByCategory(category);
65
66const response: ApiResponse<Product[]> = {
67success: true,
68data: products
70return c.json(response);
71} catch (error) {
72const response: ApiResponse<Product[]> = {
73success: false,
74error: "Failed to fetch products by category"
83const query = c.req.param("query");
84if (!query || query.trim().length < 2) {
85const response: ApiResponse<Product[]> = {
86success: false,
87error: "Search query must be at least 2 characters"
92const products = await searchProducts(query.trim());
93
94const response: ApiResponse<Product[]> = {
95success: true,
96data: products
98return c.json(response);
99} catch (error) {
100const response: ApiResponse<Product[]> = {
101success: false,
102error: "Failed to search products"
26โ โ โโโ queries.ts # Database query functions
27โ โโโ routes/
28โ โ โโโ products.ts # Product API endpoints
29โ โ โโโ cart.ts # Shopping cart endpoints
30โ โ โโโ orders.ts # Order management
31โ โ โโโ chat.ts # Chat API endpoints
32โ โ โโโ static.ts # Static file serving
33โ โโโ index.ts # Main Hono server
48## Tech Stack
4950- **Backend**: Hono (TypeScript API framework)
51- **Frontend**: React with TypeScript
52- **Database**: SQLite
56## Getting Started
5758The app will be available at the HTTP endpoint once deployed. The backend serves both the API and the frontend files.
5960## API Endpoints
6162### Products
63- `GET /api/products` - Get all products
64- `GET /api/products/:id` - Get product by ID
65- `GET /api/products/category/:category` - Get products by category
6667### Cart
68- `GET /api/cart/:sessionId` - Get cart contents
69- `POST /api/cart/:sessionId/add` - Add item to cart
70- `PUT /api/cart/:sessionId/update` - Update cart item
71- `DELETE /api/cart/:sessionId/remove/:productId` - Remove item from cart
7273### Orders
74- `POST /api/orders` - Create new order
75- `GET /api/orders/:id` - Get order details
7677### Chat
78- `GET /api/chat/messages/:roomId` - Get chat messages
79- `POST /api/chat/messages` - Send chat message
80- `GET /api/chat/stream/:roomId` - SSE stream for real-time messages
RobbieChatBox.tsx1 match
39};
4041const response = await fetch('/api/chat', {
42method: 'POST',
43headers: {
RobbiePredictionForm.tsx1 match
44};
4546const response = await fetch('/api/predictions', {
47method: 'POST',
48headers: {
45const loadCryptos = async () => {
46try {
47const response = await fetch('/api/crypto');
48if (response.ok) {
49const data = await response.json();
57const loadPredictions = async () => {
58try {
59const response = await fetch('/api/predictions');
60if (response.ok) {
61const data = await response.json();
69const loadChatMessages = async () => {
70try {
71const response = await fetch('/api/chat');
72if (response.ok) {
73const data = await response.json();