feat: implement tailwind v4 and shadcn

This commit is contained in:
2025-12-02 12:00:16 +01:00
parent 274ac8afa5
commit a1a5fb502d
27 changed files with 3051 additions and 1601 deletions

View File

@@ -3,6 +3,28 @@
import React, { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import Link from 'next/link'
import { ArrowLeft, Plus, Loader2 } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table'
interface Resident {
id: number
@@ -69,7 +91,16 @@ export default function OrdersListPage() {
}
const getStatusBadge = (status: string) => {
return <span className={`badge badge--${status}`}>{status.charAt(0).toUpperCase() + status.slice(1)}</span>
switch (status) {
case 'pending':
return <Badge variant="outline" className="bg-yellow-50 text-yellow-700 border-yellow-200">Pending</Badge>
case 'preparing':
return <Badge variant="outline" className="bg-blue-50 text-blue-700 border-blue-200">Preparing</Badge>
case 'prepared':
return <Badge variant="outline" className="bg-green-50 text-green-700 border-green-200">Prepared</Badge>
default:
return <Badge variant="outline">{status}</Badge>
}
}
const getResidentName = (resident: Resident | number) => {
@@ -80,89 +111,99 @@ export default function OrdersListPage() {
}
return (
<>
<header className="header">
<div className="header__content">
<Link href="/caregiver/dashboard" className="btn btn--secondary">
&larr; Back
</Link>
<h1 className="header__title">Meal Orders</h1>
<Link href="/caregiver/orders/new" className="btn btn--primary">
+ New Order
</Link>
<div className="min-h-screen bg-muted/50">
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="container flex h-16 items-center justify-between">
<div className="flex items-center gap-4">
<Button variant="ghost" size="sm" asChild>
<Link href="/caregiver/dashboard">
<ArrowLeft className="mr-2 h-4 w-4" />
Back
</Link>
</Button>
<h1 className="text-xl font-semibold">Meal Orders</h1>
</div>
<Button asChild>
<Link href="/caregiver/orders/new">
<Plus className="mr-2 h-4 w-4" />
New Order
</Link>
</Button>
</div>
</header>
<main className="container">
<div className="card">
<div className="card__header">
<h2>Filter Orders</h2>
</div>
<div className="card__body">
<div className="grid grid--2">
<div className="form-group">
<label htmlFor="date">Date</label>
<input
<main className="container py-6">
<Card className="mb-6">
<CardHeader>
<CardTitle>Filter Orders</CardTitle>
</CardHeader>
<CardContent>
<div className="grid gap-4 sm:grid-cols-2">
<div className="space-y-2">
<Label htmlFor="date">Date</Label>
<Input
type="date"
id="date"
className="input"
value={dateFilter}
onChange={(e) => setDateFilter(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="mealType">Meal Type</label>
<select
id="mealType"
className="select"
value={mealTypeFilter}
onChange={(e) => setMealTypeFilter(e.target.value)}
>
<option value="all">All Types</option>
<option value="breakfast">Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
</select>
<div className="space-y-2">
<Label htmlFor="mealType">Meal Type</Label>
<Select value={mealTypeFilter} onValueChange={setMealTypeFilter}>
<SelectTrigger>
<SelectValue placeholder="Select meal type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All Types</SelectItem>
<SelectItem value="breakfast">Breakfast</SelectItem>
<SelectItem value="lunch">Lunch</SelectItem>
<SelectItem value="dinner">Dinner</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
<div className="card" style={{ marginTop: '1rem' }}>
<div className="card__body" style={{ padding: 0, overflowX: 'auto' }}>
<Card>
<CardContent className="p-0">
{loading ? (
<div style={{ padding: '2rem', textAlign: 'center' }}>
<div className="spinner" style={{ margin: '0 auto' }} />
<div className="flex items-center justify-center p-8">
<Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
</div>
) : orders.length === 0 ? (
<div style={{ padding: '2rem', textAlign: 'center', color: 'var(--gray-500)' }}>
No orders found for the selected criteria.
<div className="flex flex-col items-center justify-center p-8 text-center">
<p className="text-muted-foreground">No orders found for the selected criteria.</p>
<Button asChild className="mt-4">
<Link href="/caregiver/orders/new">Create New Order</Link>
</Button>
</div>
) : (
<table className="table">
<thead>
<tr>
<th>Resident</th>
<th>Date</th>
<th>Meal</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<Table>
<TableHeader>
<TableRow>
<TableHead>Resident</TableHead>
<TableHead>Date</TableHead>
<TableHead>Meal</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{orders.map((order) => (
<tr key={order.id}>
<td>{getResidentName(order.resident)}</td>
<td>{order.date}</td>
<td>{getMealTypeLabel(order.mealType)}</td>
<td>{getStatusBadge(order.status)}</td>
</tr>
<TableRow key={order.id}>
<TableCell className="font-medium">{getResidentName(order.resident)}</TableCell>
<TableCell>{order.date}</TableCell>
<TableCell>{getMealTypeLabel(order.mealType)}</TableCell>
<TableCell>{getStatusBadge(order.status)}</TableCell>
</TableRow>
))}
</tbody>
</table>
</TableBody>
</Table>
)}
</div>
</div>
</CardContent>
</Card>
</main>
</>
</div>
)
}