From 79e1bd82fc195e3dcee83f7c0f13ed2068e3f34c Mon Sep 17 00:00:00 2001 From: dwindown Date: Sat, 27 Dec 2025 23:47:53 +0700 Subject: [PATCH] fix: consulting slots display and auth reload redirect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Group consulting slots by date in admin order detail modal - Show time range from first slot start to last slot end - Display session count badge for multi-slot orders - Fix page reload redirecting to main page by ensuring loading state is properly synchronized with Supabase session initialization - Add mounted flag to prevent state updates after unmount 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/hooks/useAuth.tsx | 45 +++++--- src/pages/admin/AdminOrders.tsx | 179 ++++++++++++++++++-------------- 2 files changed, 131 insertions(+), 93 deletions(-) diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx index 69d1371..da3bc3c 100644 --- a/src/hooks/useAuth.tsx +++ b/src/hooks/useAuth.tsx @@ -21,31 +21,46 @@ export function AuthProvider({ children }: { children: ReactNode }) { const [isAdmin, setIsAdmin] = useState(false); useEffect(() => { - const { data: { subscription } } = supabase.auth.onAuthStateChange( - (event, session) => { - setSession(session); - setUser(session?.user ?? null); - - if (session?.user) { - setTimeout(() => { - checkAdminRole(session.user.id); - }, 0); - } else { - setIsAdmin(false); - } - } - ); + let mounted = true; + // First, get the initial session supabase.auth.getSession().then(({ data: { session } }) => { + if (!mounted) return; + setSession(session); setUser(session?.user ?? null); + if (session?.user) { checkAdminRole(session.user.id); } + + // Only set loading to false after initial session is loaded setLoading(false); }); - return () => subscription.unsubscribe(); + // Then listen for auth state changes + const { data: { subscription } } = supabase.auth.onAuthStateChange( + (event, session) => { + if (!mounted) return; + + setSession(session); + setUser(session?.user ?? null); + + if (session?.user) { + checkAdminRole(session.user.id); + } else { + setIsAdmin(false); + } + + // Ensure loading is false after auth state changes + setLoading(false); + } + ); + + return () => { + mounted = false; + subscription.unsubscribe(); + }; }, []); const checkAdminRole = async (userId: string) => { diff --git a/src/pages/admin/AdminOrders.tsx b/src/pages/admin/AdminOrders.tsx index cd5210b..b09a9d2 100644 --- a/src/pages/admin/AdminOrders.tsx +++ b/src/pages/admin/AdminOrders.tsx @@ -508,87 +508,110 @@ export default function AdminOrders() { )} - {/* Consulting Slots */} - {consultingSlots.length > 0 && ( -
-

-

-
- {consultingSlots.map((slot) => ( -
-
-
-
- - {slot.status === "confirmed" ? "Terkonfirmasi" : slot.status} - - {slot.topic_category && ( - - {slot.topic_category} - - )} - {/* Meet Link Status */} - {slot.meet_link ? ( - - - Meet Link Ready - - ) : ( - - - Belum ada Meet Link - - )} -
-

- {new Date(slot.date).toLocaleDateString("id-ID", { - weekday: "short", - day: "numeric", - month: "short", - year: "numeric" - })} -

-

- {slot.start_time.substring(0, 5)} - {slot.end_time.substring(0, 5)} WIB -

- {slot.notes && ( -

- Catatan: {slot.notes} -

- )} -
-
- {slot.meet_link && ( - + )} + - )} - + + {meetLink ? "Update" : "Buat"} Link + +
+
-
-
- ))} + ); + })} + - - )} + ); + })()}
{canRefundOrder(selectedOrder.payment_status, selectedOrder.refunded_at) && (