Skip to content

Commit

Permalink
fix(header): fetch data more fluently & hide join button when user ex…
Browse files Browse the repository at this point in the history
…ists
  • Loading branch information
jsun969 committed Feb 16, 2024
1 parent 62834ab commit fc5c6c5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 79 deletions.
26 changes: 7 additions & 19 deletions src/app/api/check-user-exists/route.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
import { db } from '@/db';
import { members } from '@/db/schema';
import { memberTable } from '@/db/schema';
import { currentUser } from '@clerk/nextjs';
import { eq } from 'drizzle-orm';

export async function GET(request: Request) {
export async function GET() {
const user = await currentUser();
if (!user) {
return new Response(null, { status: 401 });
}

try {
const existingUser = await db
.select({
id: members.id,
})
.from(members)
.where(eq(members.clerkId, user.id));

if (existingUser.length > 0) {
return new Response(JSON.stringify({ exists: true }), { status: 200 });
} else {
return new Response(JSON.stringify({ exists: false }), { status: 404 });
}
} catch (error) {
console.error('Error checking user existence:', error);
return new Response(null, { status: 500 });
}
const existingUser = await db
.select({ id: memberTable.id })
.from(memberTable)
.where(eq(memberTable.clerkId, user.id));
return Response.json({ exists: existingUser.length > 0 });
}
68 changes: 39 additions & 29 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,31 @@
import FancyRectangle from '@/components/FancyRectangle';
import { BREAKPOINTS } from '@/constants/breakpoints';
import { useMount } from '@/hooks/use-mount';
import { fetcher } from '@/lib/fetcher';
import { useUser } from '@clerk/nextjs';
import Image from 'next/image';
import Link from 'next/link';
import { useRef, useState } from 'react';
import { useState } from 'react';
import { IoMdClose, IoMdMenu } from 'react-icons/io';
import useSWR from 'swr';
import Button from './Button';
import UserButton from './UserButton';

export default function Header() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const headerRef = useRef<HTMLDivElement>(null);
const [isScrolled, setIsScrolled] = useState(false);
const { isSignedIn } = useUser();

const toggleMenu = () => {
setIsMenuOpen(!isMenuOpen);
};
const closeMenu = () => {
setIsMenuOpen(false);
};

const clerkUser = useUser();
const checkUserExists = useSWR<{ exists: boolean }>('check-user-exists', fetcher.get, {
isPaused: () => clerkUser.isLoaded && !clerkUser.isSignedIn,
});

const [isScrolled, setIsScrolled] = useState(false);
useMount(() => {
window.addEventListener('scroll', handleScroll);
window.addEventListener('resize', handleResize);
Expand All @@ -30,22 +37,17 @@ export default function Header() {
window.removeEventListener('resize', handleResize);
};
});

const closeMenu = () => {
setIsMenuOpen(false);
};

const handleResize = () => {
if (window.innerWidth >= BREAKPOINTS.md) {
setIsMenuOpen(false);
}
};

const handleScroll = () => {
const scrollPosition = window.scrollY;
setIsScrolled(scrollPosition > 0);
};

const isLoading = !clerkUser.isLoaded || checkUserExists.isLoading;
return (
<header className="z-[9999] w-full">
<div
Expand All @@ -56,7 +58,6 @@ export default function Header() {

<div className="flex w-full justify-center">
<div
ref={headerRef}
className={`fixed z-[9999] md:left-auto ${
isMenuOpen
? 'h-full w-full flex-col bg-white'
Expand Down Expand Up @@ -139,23 +140,32 @@ export default function Header() {
isMenuOpen ? '' : 'hidden'
} space-y-8 md:flex md:space-x-4 md:space-y-0 lg:space-x-8`}
>
{isSignedIn ? (
<>
<Button colour="purple" href="/join" onClick={closeMenu}>
Continue Signing Up
</Button>
<UserButton />
</>
) : (
<>
<Button colour="orange" href="/signin" onClick={closeMenu}>
Sign In
</Button>
<Button colour="purple" href="/join" onClick={closeMenu}>
Join Us
</Button>
</>
)}
{!isLoading &&
(clerkUser.isSignedIn ? (
<>
{!checkUserExists.data?.exists && (
<Button
colour="purple"
href="/join"
onClick={closeMenu}
>
Continue Signing Up
</Button>
)}
<UserButton
userExists={Boolean(checkUserExists.data?.exists)}
/>
</>
) : (
<>
<Button colour="orange" href="/signin" onClick={closeMenu}>
Sign In
</Button>
<Button colour="purple" href="/join" onClick={closeMenu}>
Join Us
</Button>
</>
))}
</div>
</nav>
</div>
Expand Down
34 changes: 4 additions & 30 deletions src/components/UserButton.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,15 @@
import Button from '@/components/Button';
import { useMount } from '@/hooks/use-mount';
import { useClerk, useUser } from '@clerk/clerk-react';
import Image from 'next/image';
import Link from 'next/link';
import { useRef, useState } from 'react';
import { useState } from 'react';
import FancyRectangle from './FancyRectangle';

export default function UserButton() {
export default function UserButton({ userExists }: { userExists: boolean }) {
const { user } = useUser();
const [isPopupOpen, setPopupOpen] = useState(false);
const [userFound, setUserFound] = useState(false);
const popupRef = useRef(null);
const { signOut } = useClerk();

useMount(() => {
const checkUserExists = async () => {
try {
const response = await fetch('/api/check-user-exists');
if (response.ok) {
const data = await response.json();
const userExists = data.exists;
setUserFound(userExists);
console.log('User exists:', userExists);
} else {
console.error('Failed to fetch user existence status:', response.status);
}
} catch (error) {
console.error('Error checking user existence:', error);
}
};

checkUserExists();
});

const handleButtonClick = () => {
setPopupOpen(!isPopupOpen);
};
Expand All @@ -53,12 +30,9 @@ export default function UserButton() {

{/* Popup menu */}
{isPopupOpen && (
<div
ref={popupRef}
className="absolute right-0 top-10 z-10 flex w-52 flex-col gap-y-4 border-4 border-black bg-white p-4 text-xl md:w-44 md:text-base"
>
<div className="absolute right-0 top-10 z-10 flex w-52 flex-col gap-y-4 border-4 border-black bg-white p-4 text-xl md:w-44 md:text-base">
{/* Only show options if finished sign up */}
{userFound && (
{userExists && (
<>
{/* TODO(#16): Link to CS Club Drive */}
<a
Expand Down
2 changes: 1 addition & 1 deletion src/lib/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ky from 'ky';
const kyInstance = ky.create({ prefixUrl: '/api' });

export const fetcher = {
get: async (args: Parameters<typeof kyInstance.get>) =>
get: async (...args: Parameters<typeof kyInstance.get>) =>
(await kyInstance.get(...args).json()) as any,
post: async (url: string, { arg }: { arg: unknown }) =>
(await kyInstance.post(url, { json: arg }).json()) as any,
Expand Down

0 comments on commit fc5c6c5

Please sign in to comment.