Changes
This commit is contained in:
@@ -9,6 +9,7 @@ import { useCart } from '@/contexts/CartContext';
|
||||
import { toast } from '@/hooks/use-toast';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { formatIDR } from '@/lib/format';
|
||||
import { Video } from 'lucide-react';
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
@@ -21,27 +22,45 @@ interface Product {
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
interface ConsultingSettings {
|
||||
is_consulting_enabled: boolean;
|
||||
consulting_block_price: number;
|
||||
consulting_block_duration_minutes: number;
|
||||
}
|
||||
|
||||
export default function Products() {
|
||||
const [products, setProducts] = useState<Product[]>([]);
|
||||
const [consultingSettings, setConsultingSettings] = useState<ConsultingSettings | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { addItem, items } = useCart();
|
||||
|
||||
useEffect(() => {
|
||||
fetchProducts();
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const fetchProducts = async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('products')
|
||||
.select('*')
|
||||
.eq('is_active', true)
|
||||
.order('created_at', { ascending: false });
|
||||
const fetchData = async () => {
|
||||
const [productsRes, consultingRes] = await Promise.all([
|
||||
supabase
|
||||
.from('products')
|
||||
.select('*')
|
||||
.eq('is_active', true)
|
||||
.order('created_at', { ascending: false }),
|
||||
supabase
|
||||
.from('consulting_settings')
|
||||
.select('is_consulting_enabled, consulting_block_price, consulting_block_duration_minutes')
|
||||
.single(),
|
||||
]);
|
||||
|
||||
if (error) {
|
||||
if (productsRes.error) {
|
||||
toast({ title: 'Error', description: 'Gagal memuat produk', variant: 'destructive' });
|
||||
} else {
|
||||
setProducts(data || []);
|
||||
setProducts(productsRes.data || []);
|
||||
}
|
||||
|
||||
if (consultingRes.data) {
|
||||
setConsultingSettings(consultingRes.data);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
@@ -87,12 +106,42 @@ export default function Products() {
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
) : products.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-muted-foreground">Belum ada produk tersedia.</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{/* Consulting Card - Only show when enabled */}
|
||||
{consultingSettings?.is_consulting_enabled && (
|
||||
<Card className="border-2 border-primary shadow-sm hover:shadow-md transition-shadow bg-primary/5">
|
||||
<CardHeader>
|
||||
<div className="flex justify-between items-start">
|
||||
<CardTitle className="text-xl flex items-center gap-2">
|
||||
<Video className="w-5 h-5" />
|
||||
Konsultasi 1-on-1
|
||||
</CardTitle>
|
||||
<Badge className="bg-primary">Konsultasi</Badge>
|
||||
</div>
|
||||
<CardDescription className="line-clamp-2">
|
||||
Sesi konsultasi pribadi dengan mentor. Pilih waktu dan durasi sesuai kebutuhan Anda.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<span className="text-2xl font-bold">
|
||||
{formatIDR(consultingSettings.consulting_block_price)}
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
/ {consultingSettings.consulting_block_duration_minutes} menit
|
||||
</span>
|
||||
</div>
|
||||
<Link to="/consulting">
|
||||
<Button className="w-full shadow-sm">
|
||||
Booking Sekarang
|
||||
</Button>
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Regular Products */}
|
||||
{products.map((product) => (
|
||||
<Card key={product.id} className="border-2 border-border shadow-sm hover:shadow-md transition-shadow">
|
||||
<CardHeader>
|
||||
@@ -128,6 +177,12 @@ export default function Products() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
|
||||
{products.length === 0 && !consultingSettings?.is_consulting_enabled && (
|
||||
<div className="col-span-full text-center py-12">
|
||||
<p className="text-muted-foreground">Belum ada produk tersedia.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { WorkhoursTab } from '@/components/admin/settings/WorkhoursTab';
|
||||
import { NotifikasiTab } from '@/components/admin/settings/NotifikasiTab';
|
||||
import { KonsultasiTab } from '@/components/admin/settings/KonsultasiTab';
|
||||
import { BrandingTab } from '@/components/admin/settings/BrandingTab';
|
||||
import { IntegrasiTab } from '@/components/admin/settings/IntegrasiTab';
|
||||
import { Clock, Bell, Video, Palette, Puzzle } from 'lucide-react';
|
||||
|
||||
export default function AdminSettings() {
|
||||
@@ -51,11 +53,11 @@ export default function AdminSettings() {
|
||||
<Video className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Konsultasi</span>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="branding" className="flex items-center gap-2" disabled>
|
||||
<TabsTrigger value="branding" className="flex items-center gap-2">
|
||||
<Palette className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Branding</span>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="integrasi" className="flex items-center gap-2" disabled>
|
||||
<TabsTrigger value="integrasi" className="flex items-center gap-2">
|
||||
<Puzzle className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Integrasi</span>
|
||||
</TabsTrigger>
|
||||
@@ -74,15 +76,11 @@ export default function AdminSettings() {
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="branding">
|
||||
<div className="text-center py-12 text-muted-foreground">
|
||||
Fitur Branding akan segera hadir
|
||||
</div>
|
||||
<BrandingTab />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="integrasi">
|
||||
<div className="text-center py-12 text-muted-foreground">
|
||||
Fitur Integrasi akan segera hadir
|
||||
</div>
|
||||
<IntegrasiTab />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user