diff --git a/src/components/reviews/ConsultingHistory.tsx b/src/components/reviews/ConsultingHistory.tsx index 739756b..938cbd1 100644 --- a/src/components/reviews/ConsultingHistory.tsx +++ b/src/components/reviews/ConsultingHistory.tsx @@ -87,6 +87,12 @@ export function ConsultingHistory({ userId }: ConsultingHistoryProps) { } }; + // Check if session has passed + const isSessionPassed = (session: ConsultingSession) => { + const sessionEndDateTime = new Date(`${session.session_date}T${session.end_time}`); + return new Date() > sessionEndDateTime; + }; + const openReviewModal = (session: ConsultingSession) => { const dateLabel = format(new Date(session.session_date), 'd MMMM yyyy', { locale: id }); const timeLabel = `${session.start_time.substring(0, 5)} - ${session.end_time.substring(0, 5)}`; @@ -128,7 +134,8 @@ export function ConsultingHistory({ userId }: ConsultingHistoryProps) { }; const doneSessions = sessions.filter(s => s.status === 'done' || s.status === 'completed'); - const upcomingSessions = sessions.filter(s => s.status === 'confirmed'); + const upcomingSessions = sessions.filter(s => s.status === 'confirmed' && !isSessionPassed(s)); + const passedSessions = sessions.filter(s => s.status === 'confirmed' && isSessionPassed(s)); if (loading) { return ( @@ -212,6 +219,33 @@ export function ConsultingHistory({ userId }: ConsultingHistoryProps) { )} + {/* Passed confirmed sessions (waiting for admin action) */} + {passedSessions.length > 0 && ( +
+

Sesi Terlewat

+ {passedSessions.map((session) => ( +
+
+ +
+

+ {format(new Date(session.session_date), 'd MMM yyyy', { locale: id })} +

+

+ {session.start_time.substring(0, 5)} - {session.end_time.substring(0, 5)} + {session.topic_category && ` • ${session.topic_category}`} +

+
+
+
+ {getStatusBadge(session.status)} + Menunggu konfirmasi admin +
+
+ ))} +
+ )} + {/* Completed sessions */} {doneSessions.length > 0 && (
diff --git a/src/pages/admin/AdminConsulting.tsx b/src/pages/admin/AdminConsulting.tsx index 813ed38..055968d 100644 --- a/src/pages/admin/AdminConsulting.tsx +++ b/src/pages/admin/AdminConsulting.tsx @@ -323,6 +323,12 @@ export default function AdminConsulting() { } }; + // Helper function to check if session has passed + const isSessionPassed = (session: ConsultingSession) => { + const sessionEndDateTime = new Date(`${session.session_date}T${session.end_time}`); + return new Date() > sessionEndDateTime; + }; + const updateSessionStatus = async (sessionId: string, newStatus: string) => { // If cancelling and session has a calendar event, delete it first if (newStatus === 'cancelled') { @@ -389,6 +395,7 @@ export default function AdminConsulting() { const upcomingSessions = filteredSessions.filter(s => s.session_date >= today && (s.status === 'confirmed' || s.status === 'pending_payment')); const pastSessions = filteredSessions.filter(s => s.session_date < today || s.status === 'completed' || s.status === 'cancelled'); const todaySessions = filteredSessions.filter(s => isToday(parseISO(s.session_date)) && s.status === 'confirmed'); + const passedConfirmedSessions = filteredSessions.filter(s => s.status === 'confirmed' && isSessionPassed(s)); return ( @@ -401,6 +408,50 @@ export default function AdminConsulting() { Kelola jadwal dan link Google Meet untuk sesi konsultasi

+ {/* Passed Confirmed Sessions Alert */} + {passedConfirmedSessions.length > 0 && ( + + +

+ + Sesi Terlewat ({passedConfirmedSessions.length}) +

+

+ Sesi berikut telah berakhir namun masih berstatus "Dikonfirmasi". Silakan update statusnya. +

+
+ {passedConfirmedSessions.map((session) => ( +
+ + {format(parseISO(session.session_date), 'd MMM yyyy', { locale: id })} • {session.start_time.substring(0, 5)} - {session.end_time.substring(0, 5)} • {session.profiles?.name || 'N/A'} ({session.topic_category}) + +
+ + +
+
+ ))} +
+
+
+ )} + {/* Today's Sessions Alert */} {todaySessions.length > 0 && ( @@ -451,10 +502,10 @@ export default function AdminConsulting() {

Perlu Link Meet

- + -
{pastSessions.filter(s => s.status === 'completed').length}
-

Selesai

+
{passedConfirmedSessions.length}
+

Perlu Update

diff --git a/src/pages/member/OrderDetail.tsx b/src/pages/member/OrderDetail.tsx index 3000c74..cada77c 100644 --- a/src/pages/member/OrderDetail.tsx +++ b/src/pages/member/OrderDetail.tsx @@ -75,6 +75,13 @@ export default function OrderDetail() { (item: OrderItem) => item.products.type === "consulting" ) || false; + // Check if consulting session has passed + const isConsultingSessionPassed = consultingSlots.length > 0 ? (() => { + const slot = consultingSlots[0]; + const sessionEndDateTime = new Date(`${slot.session_date}T${slot.end_time}`); + return new Date() > sessionEndDateTime; + })() : false; + // Memoized fetchOrder to avoid recreating on every render const fetchOrder = useCallback(async () => { if (!user || !id) return; @@ -758,12 +765,21 @@ export default function OrderDetail() { {/* Status Alert */} {order.payment_status === "paid" ? ( - - + isConsultingSessionPassed ? ( + + + + Sesi konsultasi telah berakhir. Menunggu konfirmasi admin. + + + ) : ( + + + ) ) : order.status !== "cancelled" && order.payment_status === "pending" && !isQrExpired ? (