mirror of
http://88.130.71.182:3000/BlitTech/badoHair_fe.git
synced 2026-06-13 10:41:11 +00:00
Update May 21 by Elvis
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useState, useEffect, useCallback, startTransition } from "react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -34,7 +34,7 @@ export default function AdminClients() {
|
||||
}
|
||||
}, [query]);
|
||||
|
||||
useEffect(() => { load(); }, [load]);
|
||||
useEffect(() => { startTransition(() => load()); }, [load]);
|
||||
|
||||
const handleSearch = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useState, useEffect, useCallback, startTransition } from "react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -56,7 +56,7 @@ export default function AdminCommandes() {
|
||||
}
|
||||
}, [filter]);
|
||||
|
||||
useEffect(() => { load(); }, [load]);
|
||||
useEffect(() => { startTransition(() => load()); }, [load]);
|
||||
|
||||
const handleStatus = async (id: string, status: string) => {
|
||||
setUpdating(id);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect, useState, startTransition } from "react";
|
||||
import { Package, CalendarCheck, Clock, TrendingUp, ShoppingBag, Users, AlertTriangle, Euro } from "lucide-react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -8,6 +8,41 @@ import { useAdmin } from "@/contexts/AdminContext";
|
||||
import { useLanguage } from "@/contexts/LanguageContext";
|
||||
import { getDashboardStats, DashboardStats } from "@/lib/api/admin";
|
||||
|
||||
function Skeleton() {
|
||||
return (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{Array.from({ length: 4 }).map((_, i) => (
|
||||
<Card key={i}>
|
||||
<CardContent className="p-5">
|
||||
<div className="h-4 bg-muted animate-pulse rounded w-2/3 mb-3" />
|
||||
<div className="h-7 bg-muted animate-pulse rounded w-1/3" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function StatGrid({ cards }: { cards: { label: string; value: string | number; icon: React.ElementType; color: string; bg: string }[] }) {
|
||||
return (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{cards.map((s) => (
|
||||
<Card key={s.label}>
|
||||
<CardContent className="p-5 flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">{s.label}</p>
|
||||
<p className="text-2xl font-semibold mt-1">{s.value}</p>
|
||||
</div>
|
||||
<div className={`h-10 w-10 rounded-full ${s.bg} flex items-center justify-center`}>
|
||||
<s.icon className={`h-5 w-5 ${s.color}`} />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AdminOverview() {
|
||||
const { reservations } = useAdmin();
|
||||
const { t, locale } = useLanguage();
|
||||
@@ -40,37 +75,6 @@ export default function AdminOverview() {
|
||||
]
|
||||
: [];
|
||||
|
||||
const Skeleton = () => (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{Array.from({ length: 4 }).map((_, i) => (
|
||||
<Card key={i}>
|
||||
<CardContent className="p-5">
|
||||
<div className="h-4 bg-muted animate-pulse rounded w-2/3 mb-3" />
|
||||
<div className="h-7 bg-muted animate-pulse rounded w-1/3" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
const StatGrid = ({ cards }: { cards: { label: string; value: string | number; icon: React.ElementType; color: string; bg: string }[] }) => (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{cards.map((s) => (
|
||||
<Card key={s.label}>
|
||||
<CardContent className="p-5 flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">{s.label}</p>
|
||||
<p className="text-2xl font-semibold mt-1">{s.value}</p>
|
||||
</div>
|
||||
<div className={`h-10 w-10 rounded-full ${s.bg} flex items-center justify-center`}>
|
||||
<s.icon className={`h-5 w-5 ${s.color}`} />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useState, useEffect, useCallback, startTransition } from "react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -263,7 +263,7 @@ function CalendarTab() {
|
||||
.finally(() => setLoadingSlots(false));
|
||||
}, [year, month]);
|
||||
|
||||
useEffect(() => { loadSlots(); }, [loadSlots]);
|
||||
useEffect(() => { startTransition(() => loadSlots()); }, [loadSlots]);
|
||||
|
||||
const prevMonth = () => {
|
||||
if (month === 0) { setYear((y) => y - 1); setMonth(11); }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, startTransition } from "react";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -54,7 +54,7 @@ export default function AdminServices() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => { load(); }, []);
|
||||
useEffect(() => { startTransition(() => load()); }, []);
|
||||
|
||||
const openCreate = () => {
|
||||
setEditing(null);
|
||||
|
||||
Reference in New Issue
Block a user