Quick reference code snippets you can copy and adapt for your project.
import { useState } from 'react'
function SearchPage() {
const [cart, setCart] = useState([])
const addToCart = (medicine) => {
// Check if already in cart
const existingItem = cart.find(item => item.id === medicine.id)
if (existingItem) {
// Update quantity
setCart(cart.map(item =>
item.id === medicine.id
? { ...item, qty: item.qty + 1 }
: item
))
} else {
// Add new item
setCart([...cart, { ...medicine, qty: 1 }])
}
}
return (
<button
className="btn-add-cart"
onClick={() => addToCart(med)}
>
Add To Cart
</button>
)
}const removeFromCart = (id) => {
setCartItems(cartItems.filter(item => item.id !== id))
}
// In JSX:
<button
className="cart-item-delete"
onClick={() => removeFromCart(item.id)}
>
<i className="bi bi-trash3"></i>
</button>const updateQuantity = (id, newQty) => {
setCartItems(cartItems.map(item =>
item.id === id ? { ...item, selectedQty: parseInt(newQty) } : item
))
}
// In JSX:
<select
className="qty-select"
value={item.selectedQty}
onChange={(e) => updateQuantity(item.id, e.target.value)}
>
{[1, 2, 3, 4, 5].map((n) => (
<option key={n} value={n}>Qty {n}</option>
))}
</select>import { useEffect } from 'react'
const [total, setTotal] = useState(0)
useEffect(() => {
const calculateTotal = () => {
const sum = cartItems.reduce((acc, item) => {
return acc + (item.currentPrice * item.selectedQty)
}, 0)
setTotal(sum.toFixed(2))
}
calculateTotal()
}, [cartItems])
// Display:
<span className="cart-total-amount">₹{total}</span>// Save cart whenever it changes
useEffect(() => {
localStorage.setItem('medrover_cart', JSON.stringify(cartItems))
}, [cartItems])
// Load cart on page load
useEffect(() => {
const savedCart = localStorage.getItem('medrover_cart')
if (savedCart) {
try {
setCartItems(JSON.parse(savedCart))
} catch (error) {
console.error('Error loading cart:', error)
}
}
}, [])import { useState, useEffect } from 'react'
const [searchQuery, setSearchQuery] = useState('')
const [filteredMedicines, setFilteredMedicines] = useState(medicines)
useEffect(() => {
const timer = setTimeout(() => {
if (searchQuery.trim()) {
const filtered = medicines.filter(med =>
med.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
med.brand.toLowerCase().includes(searchQuery.toLowerCase())
)
setFilteredMedicines(filtered)
} else {
setFilteredMedicines(medicines)
}
}, 300) // Wait 300ms after user stops typing
return () => clearTimeout(timer) // Cleanup
}, [searchQuery])
// In JSX:
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search for Medicines..."
/>// Create: src/lib/supabaseClient.js
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseKey)import { useState, useEffect } from 'react'
import { supabase } from '../lib/supabaseClient'
function SearchPage() {
const [medicines, setMedicines] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
const fetchMedicines = async () => {
try {
setLoading(true)
const { data, error } = await supabase
.from('medicines')
.select('*')
.order('name')
if (error) throw error
setMedicines(data || [])
} catch (err) {
setError(err.message)
console.error('Error fetching medicines:', err)
} finally {
setLoading(false)
}
}
fetchMedicines()
}, [])
if (loading) return <div>Loading medicines...</div>
if (error) return <div>Error: {error}</div>
return (
// Your JSX here
)
}const searchMedicines = async (query) => {
try {
const { data, error } = await supabase
.from('medicines')
.select('*')
.ilike('name', `%${query}%`)
.limit(20)
if (error) throw error
return data
} catch (error) {
console.error('Search error:', error)
return []
}
}const createOrder = async (orderData) => {
try {
const { data, error } = await supabase
.from('orders')
.insert([{
medicines: orderData.cartItems,
delivery_room: orderData.selectedRoom,
total_amount: orderData.total,
status: 'pending',
created_at: new Date().toISOString()
}])
.select()
.single()
if (error) throw error
return data
} catch (error) {
console.error('Error creating order:', error)
throw error
}
}
// Usage:
const handlePlaceOrder = async () => {
try {
setLoading(true)
const order = await createOrder({
cartItems,
selectedRoom,
total: calculateTotal()
})
// Clear cart
setCartItems([])
localStorage.removeItem('medrover_cart')
// Navigate to success page or show message
alert(`Order placed! Order ID: ${order.id}`)
navigate('/')
} catch (error) {
alert('Failed to place order. Please try again.')
} finally {
setLoading(false)
}
}import { useEffect } from 'react'
import { supabase } from '../lib/supabaseClient'
function OrderTracking() {
const [orderStatus, setOrderStatus] = useState('pending')
useEffect(() => {
const channel = supabase
.channel('order-updates')
.on('postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'orders',
filter: `id=eq.${orderId}`
},
(payload) => {
setOrderStatus(payload.new.status)
console.log('Order status updated:', payload.new.status)
}
)
.subscribe()
return () => {
supabase.removeChannel(channel)
}
}, [orderId])
return (
<div>
<p>Status: {orderStatus}</p>
{orderStatus === 'pending' && <span>⏳ Waiting for robot...</span>}
{orderStatus === 'in_transit' && <span>🚚 Robot is delivering...</span>}
{orderStatus === 'delivered' && <span>✅ Delivered!</span>}
</div>
)
}const [selectedRoom, setSelectedRoom] = useState('')
const [error, setError] = useState('')
const handlePlaceOrder = () => {
// Reset error
setError('')
// Validate room selection
if (!selectedRoom) {
setError('Please select a delivery room')
return
}
// Validate cart is not empty
if (cartItems.length === 0) {
setError('Your cart is empty')
return
}
// Check prescription requirements
const hasPrescriptionMedicines = cartItems.some(item => item.rx)
if (hasPrescriptionMedicines && !hasPrescription) {
setError('Prescription required for some medicines in your cart')
return
}
// All validations passed
createOrder()
}
// Display error:
{error && (
<div className="alert alert-danger" role="alert">
{error}
</div>
)}const [loading, setLoading] = useState(false)
const handlePlaceOrder = async () => {
setLoading(true)
try {
await createOrder()
// Success
} catch (error) {
// Error handling
} finally {
setLoading(false)
}
}
// In JSX:
<button
className="btn-place-order-final"
onClick={handlePlaceOrder}
disabled={loading}
>
{loading ? (
<>
<span className="spinner-border spinner-border-sm me-2"></span>
Placing Order...
</>
) : (
<>
<i className="bi bi-send-fill me-2"></i>
Place Order
</>
)}
</button>const [loading, setLoading] = useState(true)
useEffect(() => {
const loadData = async () => {
setLoading(true)
// Fetch data
setLoading(false)
}
loadData()
}, [])
if (loading) {
return (
<div className="text-center py-5">
<div className="spinner-border text-primary" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<p className="mt-3">Loading medicines...</p>
</div>
)
}// Create: src/context/CartContext.jsx
import { createContext, useContext, useState, useEffect } from 'react'
const CartContext = createContext()
export const CartProvider = ({ children }) => {
const [cartItems, setCartItems] = useState([])
// Load from localStorage
useEffect(() => {
const saved = localStorage.getItem('medrover_cart')
if (saved) {
setCartItems(JSON.parse(saved))
}
}, [])
// Save to localStorage
useEffect(() => {
localStorage.setItem('medrover_cart', JSON.stringify(cartItems))
}, [cartItems])
const addToCart = (medicine) => {
const existing = cartItems.find(item => item.id === medicine.id)
if (existing) {
setCartItems(cartItems.map(item =>
item.id === medicine.id
? { ...item, qty: item.qty + 1 }
: item
))
} else {
setCartItems([...cartItems, { ...medicine, qty: 1 }])
}
}
const removeFromCart = (id) => {
setCartItems(cartItems.filter(item => item.id !== id))
}
const updateQuantity = (id, qty) => {
setCartItems(cartItems.map(item =>
item.id === id ? { ...item, qty: parseInt(qty) } : item
))
}
const getCartCount = () => {
return cartItems.reduce((sum, item) => sum + item.qty, 0)
}
const getCartTotal = () => {
return cartItems.reduce((sum, item) => sum + (item.price * item.qty), 0)
}
const clearCart = () => {
setCartItems([])
localStorage.removeItem('medrover_cart')
}
return (
<CartContext.Provider value={{
cartItems,
addToCart,
removeFromCart,
updateQuantity,
getCartCount,
getCartTotal,
clearCart
}}>
{children}
</CartContext.Provider>
)
}
export const useCart = () => {
const context = useContext(CartContext)
if (!context) {
throw new Error('useCart must be used within CartProvider')
}
return context
}// In App.jsx
import { CartProvider } from './context/CartContext'
function App() {
return (
<CartProvider>
<Router>
<Navbar />
<Routes>
{/* Your routes */}
</Routes>
<Footer />
</Router>
</CartProvider>
)
}// In SearchPage.jsx
import { useCart } from '../context/CartContext'
function SearchPage() {
const { addToCart, getCartCount } = useCart()
return (
<>
<button onClick={() => addToCart(med)}>Add To Cart</button>
<p>Items in cart: {getCartCount()}</p>
</>
)
}
// In Navbar.jsx
import { useCart } from '../context/CartContext'
function Navbar() {
const { getCartCount } = useCart()
const cartCount = getCartCount()
return (
<Link to="/cart" className="nav-top-action nav-cart-action">
<i className="bi bi-cart3"></i>
<span>Cart</span>
{cartCount > 0 && <span className="cart-badge">{cartCount}</span>}
</Link>
)
}# In web_portal/.env
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key# Already in your .gitignore, but verify:
.env
.env.local
.env*.local// src/utils/format.js
export const formatCurrency = (amount) => {
return `₹${parseFloat(amount).toFixed(2)}`
}
// Usage:
<span>{formatCurrency(item.price)}</span>export const calculateDiscount = (original, current) => {
const discount = ((original - current) / original) * 100
return Math.round(discount)
}
// Usage:
<span>{calculateDiscount(med.original, med.price)}% OFF</span>const [error, setError] = useState(null)
const [success, setSuccess] = useState(null)
const handleAction = async () => {
try {
setError(null)
setSuccess(null)
// Your action here
await someAsyncOperation()
setSuccess('Operation completed successfully!')
} catch (err) {
setError(err.message || 'Something went wrong')
console.error('Error:', err)
}
}
// In JSX:
{error && (
<div className="alert alert-danger alert-dismissible fade show" role="alert">
{error}
<button
type="button"
className="btn-close"
onClick={() => setError(null)}
></button>
</div>
)}
{success && (
<div className="alert alert-success alert-dismissible fade show" role="alert">
{success}
<button
type="button"
className="btn-close"
onClick={() => setSuccess(null)}
></button>
</div>
)}# Install Supabase client
npm install @supabase/supabase-js
# Already installed:
# - react, react-dom
# - react-router-dom
# - bootstrap, bootstrap-iconsTip: Copy these examples and adapt them to your project structure. Start with cart management, then move to Supabase integration!