Handle passed consulting sessions for admin and member
Problem: Passed consulting sessions stayed in "Dikonfirmasi" status indefinitely, showing JOIN button to members even after session ended, with no admin action buttons. Solution: 1. Admin UI (AdminConsulting.tsx): - Add isSessionPassed() helper to check if session end time has passed - Add "Sesi Terlewat" alert card at top with quick action buttons - Add "Perlu Update" stat card (orange) for passed confirmed sessions - Existing action buttons (Selesai/Batal) already work for confirmed sessions 2. Member UI (ConsultingHistory.tsx): - Move passed confirmed sessions from "Sesi Mendatang" to new "Sesi Terlewat" section - Remove JOIN button for passed sessions - Show "Menunggu konfirmasi admin" status message - Display with orange styling to indicate needs attention 3. Order Detail (OrderDetail.tsx): - Add isConsultingSessionPassed check - Show orange alert for passed paid sessions: "Sesi telah berakhir. Menunggu konfirmasi admin" - Keep green alert for upcoming paid sessions Flow: - Session ends → Still shows "confirmed" status - Admin sees orange alert → Clicks Selesai or Batal - Member sees passed session → No JOIN button → Waits for admin - Admin updates status → Session moves to completed/cancelled 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Passed confirmed sessions (waiting for admin action) */}
|
||||
{passedSessions.length > 0 && (
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-sm font-medium text-orange-600 dark:text-orange-400">Sesi Terlewat</h4>
|
||||
{passedSessions.map((session) => (
|
||||
<div key={session.id} className="flex items-center justify-between p-3 border-2 border-orange-200 bg-orange-50 dark:bg-orange-950/20">
|
||||
<div className="flex items-center gap-3">
|
||||
<Clock className="w-4 h-4 text-orange-600" />
|
||||
<div>
|
||||
<p className="font-medium">
|
||||
{format(new Date(session.session_date), 'd MMM yyyy', { locale: id })}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground flex items-center gap-1">
|
||||
{session.start_time.substring(0, 5)} - {session.end_time.substring(0, 5)}
|
||||
{session.topic_category && ` • ${session.topic_category}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{getStatusBadge(session.status)}
|
||||
<span className="text-xs text-muted-foreground">Menunggu konfirmasi admin</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Completed sessions */}
|
||||
{doneSessions.length > 0 && (
|
||||
<div className="space-y-2">
|
||||
|
||||
Reference in New Issue
Block a user