This commit is contained in:
gpt-engineer-app[bot]
2025-12-21 15:09:52 +00:00
parent d3f7544536
commit 8a1ccb7acc
6 changed files with 739 additions and 179 deletions

View File

@@ -7,9 +7,10 @@ import { Card, CardContent } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { toast } from '@/hooks/use-toast';
import { formatDuration } from '@/lib/format';
import { ChevronLeft, ChevronRight, Check, Play, BookOpen, Clock, Menu, X } from 'lucide-react';
import { ChevronLeft, ChevronRight, Check, Play, BookOpen, Clock, Menu, Star, CheckCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
import { ReviewModal } from '@/components/reviews/ReviewModal';
interface Product {
id: string;
@@ -51,6 +52,8 @@ export default function Bootcamp() {
const [loading, setLoading] = useState(true);
const [sidebarOpen, setSidebarOpen] = useState(true);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [hasReviewed, setHasReviewed] = useState(false);
const [reviewModalOpen, setReviewModalOpen] = useState(false);
useEffect(() => {
if (!authLoading && !user) {
@@ -129,6 +132,16 @@ export default function Bootcamp() {
setProgress(progressData);
}
// Check if user has already reviewed this bootcamp
const { data: reviewData } = await supabase
.from('reviews')
.select('id')
.eq('user_id', user!.id)
.eq('product_id', productData.id)
.limit(1);
setHasReviewed(!!(reviewData && reviewData.length > 0));
setLoading(false);
};
@@ -212,6 +225,7 @@ export default function Bootcamp() {
const completedCount = progress.length;
const totalLessons = modules.reduce((sum, m) => sum + m.lessons.length, 0);
const isBootcampCompleted = totalLessons > 0 && completedCount >= totalLessons;
const renderSidebarContent = () => (
<div className="p-4">
@@ -411,6 +425,31 @@ export default function Bootcamp() {
<ChevronRight className="w-4 h-4 ml-2" />
</Button>
</div>
{/* Bootcamp completion review prompt */}
{isBootcampCompleted && (
<Card className="border-2 border-primary/20 mt-6">
<CardContent className="py-4">
{hasReviewed ? (
<div className="flex items-center gap-2 text-muted-foreground">
<CheckCircle className="w-5 h-5 text-accent" />
<span>Terima kasih atas ulasan Anda (menunggu moderasi)</span>
</div>
) : (
<div className="flex items-center justify-between gap-4 flex-wrap">
<div>
<p className="font-medium">🎉 Selamat menyelesaikan bootcamp!</p>
<p className="text-sm text-muted-foreground">Bagikan pengalaman Anda</p>
</div>
<Button onClick={() => setReviewModalOpen(true)} variant="outline" className="border-2">
<Star className="w-4 h-4 mr-2" />
Beri ulasan
</Button>
</div>
)}
</CardContent>
</Card>
)}
</div>
) : (
<div className="flex items-center justify-center h-full">
@@ -426,6 +465,19 @@ export default function Bootcamp() {
)}
</main>
</div>
{/* Review Modal */}
{user && product && (
<ReviewModal
open={reviewModalOpen}
onOpenChange={setReviewModalOpen}
userId={user.id}
productId={product.id}
type="bootcamp"
contextLabel={product.title}
onSuccess={() => setHasReviewed(true)}
/>
)}
</div>
);
}