From cd06a71a9e3e59d5a86a3a4d29beefdf9f95726a Mon Sep 17 00:00:00 2001
From: Hafid Nur <73023445+hafidnrzs@users.noreply.github.com>
Date: Thu, 27 Nov 2025 15:42:18 +0700
Subject: [PATCH] feat(hackathon): change "edit profile" to modal dialog
- Add "edit profile" modal dialog that can be triggered from dashboard
- Update background overlay for dark mode
- Update dark mode for auth callback
---
apps/hackathon/src/app/auth/callback/page.tsx | 6 +-
apps/hackathon/src/app/dashboard/page.tsx | 453 ++++++++++--------
apps/hackathon/src/app/page.tsx | 8 +-
apps/hackathon/src/app/profile/page.tsx | 438 ++++++++---------
.../hackathon/src/app/teams/[teamId]/page.tsx | 2 +-
5 files changed, 479 insertions(+), 428 deletions(-)
diff --git a/apps/hackathon/src/app/auth/callback/page.tsx b/apps/hackathon/src/app/auth/callback/page.tsx
index 0453894..1144c72 100644
--- a/apps/hackathon/src/app/auth/callback/page.tsx
+++ b/apps/hackathon/src/app/auth/callback/page.tsx
@@ -176,13 +176,13 @@ const CallbackPage: FC = (): ReactElement => {
}
return (
-
+
-
+
Completing login...
-
Please wait
+
Please wait
);
diff --git a/apps/hackathon/src/app/dashboard/page.tsx b/apps/hackathon/src/app/dashboard/page.tsx
index a3cf454..f12d389 100644
--- a/apps/hackathon/src/app/dashboard/page.tsx
+++ b/apps/hackathon/src/app/dashboard/page.tsx
@@ -1,4 +1,4 @@
-import { FC, ReactElement } from 'react';
+import { FC, ReactElement, useEffect, useState } from 'react';
import { Link } from 'react-router';
import {
useMyTeams,
@@ -9,16 +9,49 @@ import {
import { toast } from 'sonner';
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { Icon } from '@iconify/react';
+import ProfilePage from '../profile/page';
+
+type Invitation = {
+ id: string;
+ team: {
+ id?: string;
+ name?: string;
+ logo?: string;
+ banner?: string;
+ description?: string;
+ city?: string;
+ visibility?: string;
+ leader_id?: string;
+ };
+ inviter: {
+ id?: string;
+ fullname?: string;
+ email?: string;
+ avatar?: string;
+ };
+};
const DashboardPage: FC = (): ReactElement => {
const { session } = useAuthStore();
+ const [showProfileModal, setShowProfileModal] = useState(false);
+ // Lock background scroll when profile modal is open
+ useEffect(() => {
+ if (showProfileModal) {
+ const originalOverflow = document.body.style.overflow;
+ document.body.style.overflow = 'hidden';
+ return () => {
+ document.body.style.overflow = originalOverflow || '';
+ };
+ }
+ }, [showProfileModal]);
const { data: teamsData } = useMyTeams();
const { data: invitationsData } = useMyInvitations();
const { mutateAsync: respondToInvitation } = useRespondToInvitation();
const user = session?.user;
const myTeams = teamsData?.data || [];
- const invitations = invitationsData?.data || [];
+ const invitations: Invitation[] = (invitationsData?.data ||
+ []) as Invitation[];
const handleAcceptInvitation = async (invitationId: string) => {
try {
@@ -41,225 +74,233 @@ const DashboardPage: FC = (): ReactElement => {
};
return (
-
-
-
- Welcome, {user?.fullname || user?.email?.split('@')[0] || 'User'}!
-
- {user?.location && (
-
-
- {user.location}
-
- )}
-
-
- {invitations.length > 0 && (
-
-
- Team Invitations ({invitations.length})
-
-
- {invitations.map((invitation) => (
-
-
-
- {invitation.team.name}
-
-
- Invited by {invitation.inviter.fullname}
-
-
-
-
-
-
-
- ))}
-
+ <>
+
+
+
+ Welcome, {user?.fullname || user?.email?.split('@')[0] || 'User'}!
+
+ {user?.location && (
+
+
+ {user.location}
+
+ )}
- )}
- {myTeams.length > 0 ? (
-
-
- My Team
-
-
- {myTeams.map((team) => (
-
- {team.banner && (
-
-

+ {invitations.length > 0 && (
+
+
+ Team Invitations ({invitations.length})
+
+
+ {invitations.map((invitation) => (
+
+
+
+ {invitation.team?.name ?? 'Unnamed Team'}
+
+
+ Invited by{' '}
+ {invitation.inviter?.fullname ?? 'Unknown User'}
+
+
+
+
+
+
+
+ ))}
+
+
+ )}
+
+ {myTeams.length > 0 ? (
+
+
+ My Team
+
+
+ {myTeams.map((team) => (
+
+ {team.banner && (
+
+

+
+ )}
+
+
+ {team.logo && (
+

+ )}
+
+
+ {team.name}
+
+
+
+ {team.city}
+
+
+
+
+ {team.description}
+
+
+
+ ))}
+
+
+ ) : (
+
+
+
👋
+
+ You are not in a team yet
+
+
+ Use the sidebar to browse teams or create your own
+
+
+
+ )}
+
+
+
+
+
+
+ {user?.avatar ? (
+

+ ) : (
+
+
+ U
+
)}
-
-
- {team.logo && (
-

- )}
-
-
- {team.name}
-
-
-
- {team.city}
-
-
-
-
- {team.description}
-
-
-
- ))}
-
-
- ) : (
-
-
-
👋
-
- You are not in a team yet
-
-
- Use the sidebar to browse teams or create your own
-
-
-
- )}
+
+
+ {user?.fullname ||
+ user?.email?.split('@')[0] ||
+ 'Unnamed User'}
+
-
-
-
-
-
- {user?.avatar ? (
-

- ) : (
-
-
- U
-
+ {user?.location ? (
+
+
+ {user.location}
+
+ ) : (
+
+
Complete your profile
+
+
+ )}
+
+
+ {user?.location && (
+
+ )}
+
+
+ {user?.bio && (
+
+
+ About
+
+
+ {user.bio}
+
)}
-
-
- {user?.fullname ||
- user?.email?.split('@')[0] ||
- 'Unnamed User'}
-
-
- {user?.location ? (
-
-
- {user.location}
-
- ) : (
-
-
Complete your profile
-
-
- )}
-
-
- {user?.location && (
-
- Edit Profile
-
- )}
-
-
- {user?.bio && (
-
-
- About
-
-
- {user.bio}
-
-
- )}
-
-
- Contact
-
-
-
- {user?.email}
-
-
-
- {user?.skills && user.skills.length > 0 && (
- Skills
+ Contact
-
- {user.skills.map((skill: string) => (
-
- {skill}
-
- ))}
+
+
+ {user?.email}
+
- )}
+ {user?.skills && user.skills.length > 0 && (
+
+
+ Skills
+
+
+ {user.skills.map((skill: string) => (
+
+ {skill}
+
+ ))}
+
+
+ )}
+
-
+
setShowProfileModal(false)}
+ />
+ >
);
};
diff --git a/apps/hackathon/src/app/page.tsx b/apps/hackathon/src/app/page.tsx
index ca496fe..69b4ac5 100644
--- a/apps/hackathon/src/app/page.tsx
+++ b/apps/hackathon/src/app/page.tsx
@@ -187,12 +187,12 @@ export default function HomePage() {
) : (
<>
- navigate('/auth/login')}
+ className="ms-3 text-gray-600 dark:text-gray-200 hover:text-gray-900 dark:hover:text-white cursor-pointer"
>
Masuk
-
+