Skip to content

Commit

Permalink
Merge pull request #15 from farhackxyz/cleanup-server-only-functions
Browse files Browse the repository at this point in the history
fix: clean up various functions and add new homepage design
  • Loading branch information
dylsteck authored Oct 15, 2024
2 parents d85e3e4 + c3a05fd commit a214bb3
Show file tree
Hide file tree
Showing 33 changed files with 2,224 additions and 4,306 deletions.
4 changes: 2 additions & 2 deletions app/admin/hackathons/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ export default async function HackathonsPage() {
const adminHackathonIds = user?.admin_hackathons?.split(',').map(Number);

if (!Array.isArray(adminHackathonIds)) {
console.log(`Invalid admin_hackathons: ${user?.admin_hackathons}`);
console.error(`Invalid admin_hackathons: ${user?.admin_hackathons}`);
return false;
}

console.log(`Checking hackathon ID ${hackathon.id} against admin IDs:`, adminHackathonIds);
console.error(`Checking hackathon ID ${hackathon.id} against admin IDs:`, adminHackathonIds);
return adminHackathonIds.includes(hackathon.id);
})
.map(hackathon => (
Expand Down
1 change: 0 additions & 1 deletion app/components/buy-ticket-transaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ export default function BuyTicketTransaction({ userId, ticketType }: { userId: s

return txHash ? <p>You have already purchased a ticket</p> : address ? (
<Transaction
address={address}
chainId={base.id}
contracts={contracts as any}
onSuccess={(response) => handleTxnSuccess(response)}
Expand Down
10 changes: 6 additions & 4 deletions app/components/delete-or-leave-team-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@ import React, { useState } from 'react';
export default function DeleteOrLeaveTeamButton({
teamId,
userId,
hackathonSlug,
teamMembers,
handleDeleteTeam,
handleLeaveTeam
}: {
teamId: number,
userId: number,
hackathonSlug: string,
teamMembers: any[],
handleDeleteTeam: () => void,
handleLeaveTeam: () => void
handleDeleteTeam: (team_id: number, hackathon_slug: string) => Promise<void>,
handleLeaveTeam: (user_id: number, team_id: number, hackathon_slug: string) => Promise<void>
}) {
const [showModal, setShowModal] = useState(false);
const [action, setAction] = useState<"delete" | "leave" | null>(null);

const handleAction = () => {
if (action === "delete") {
handleDeleteTeam();
handleDeleteTeam(teamId, hackathonSlug);
} else if (action === "leave") {
handleLeaveTeam();
handleLeaveTeam(userId, teamId, hackathonSlug);
}
setShowModal(false);
};
Expand Down
9 changes: 9 additions & 0 deletions app/components/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use client";

export default function Error({ message = 'An error occured.' }: { message?: string }){
return(
<div className="flex items-center justify-center min-h-screen text-white text-2xl">
<p>{message} <a href="/" className="underline">Return to home</a></p>
</div>
)
}
4 changes: 2 additions & 2 deletions app/components/hackathon-bounties.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default async function HackathonBounties({ slug }: { slug: string }) {
const bounties = hackathon.bounties as unknown as Bounty[];

return (
<div className="pt-5">
<div className="text-white flex flex-col gap-1 items-start pl-[7.5%] md:pl-[4.5%]">
<div className="">
<div className="text-white flex flex-col gap-1 items-start pl-[2.5%] ml-2 md:ml-0">
<HackathonNav hackathon={hackathon} />
{bounties ?
<>
Expand Down
9 changes: 3 additions & 6 deletions app/components/hackathon-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ function HackthonNavItem({ name, slug }: { name: string, slug: string }) {
export default function HackathonNav({ hackathon }: { hackathon: any }) {
return(
<div>
<div className="text-white flex flex-col gap-1 items-start pt-5">
<div className="flex flex-row gap-3 items-center mt-[7.5%] md:mt-[3.5%] ml-2 md:ml-0">
<img src={hackathon.square_image} alt={`${hackathon?.name} Hackathon`} loading="lazy" className="rounded w-[8%] md:w-[5%]" />
<p className="text-4xl">{hackathon.name ? hackathon.name : "Hackathon"}</p>
</div>
<div className="flex flex-row gap-2 md:gap-4 items-center mt-3.5 ml-2 md:ml-0 overflow-x-clip scrollbar-hide">
<div className="text-white flex flex-col gap-1 items-start">
<p className="text-4xl">{hackathon.name ? hackathon.name : "Hackathon"}</p>
<div className="flex flex-row gap-2 md:gap-4 items-center mt-3.5 overflow-x-clip scrollbar-hide">
{hackathonPages.map((page) =>
<HackthonNavItem key={page.slug} name={page.name} slug={page.slug} />
)}
Expand Down
4 changes: 2 additions & 2 deletions app/components/hackathon-schedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export default async function HackathonSchedule({ slug }: { slug: string }) {
const schedule = hackathon.schedule as unknown as ScheduleItem[];

return (
<div className="pt-5">
<div className="text-white flex flex-col gap-1 items-start pl-[7.5%] md:pl-[4.5%]">
<div className="">
<div className="text-white flex flex-col gap-1 items-start pl-[2.5%] ml-2 md:ml-0">
<HackathonNav hackathon={hackathon} />
{schedule ?
<>
Expand Down
4 changes: 2 additions & 2 deletions app/components/hackathon-teams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export default async function HackathonTeams({ slug }: { slug: string }) {
}

return (
<div className="pt-5">
<div className="text-white flex flex-col gap-1 items-start pl-[4.5%]">
<div className="">
<div className="text-white flex flex-col gap-1 items-start pl-[2.5%]">
<HackathonNav hackathon={hackathon} />
{teams ?
<>
Expand Down
4 changes: 2 additions & 2 deletions app/components/hackathon-tracks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export default async function HackathonTracks({ slug }: { slug: string }) {
const tracks = hackathon.tracks as unknown as Track[];

return (
<div className="pt-5">
<div className="text-white flex flex-col gap-1 items-start pl-[7.5%] md:pl-[4.5%]">
<div>
<div className="text-white flex flex-col gap-1 items-start pl-[2.5%] ml-2 md:ml-0">
<HackathonNav hackathon={hackathon} />
{tracks ?
<>
Expand Down
6 changes: 3 additions & 3 deletions app/components/hackathons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ export default async function Hackathons() {
if (hackathons) {
hackathons.sort((a, b) => new Date(b.start_date).getTime() - new Date(a.start_date).getTime());
return (
<div className="pt-7 md:pt-12">
<div className="flex flex-col md:flex-row md:flex-wrap justify-center md:justify-start items-center md:items-start gap-10">
<div className="pt-5 md:pt-8">
<p className="pb-4 text-2xl font-medium">Hackathons</p>
<div className="flex flex-col md:flex-row justify-center md:justify-start items-center md:items-start gap-10">
{hackathons.map((hackathon) => (
<HackathonListItem key={hackathon.id} hackathon={hackathon} />
))}
</div>
</div>
);
}
// TODO: change all static loading so some sort of icon at least
return <div>Loading...</div>;
}
7 changes: 2 additions & 5 deletions app/components/onchain-providers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';
import { ReactNode } from 'react';
import { base } from 'viem/chains';
import { base } from 'wagmi/chains';
import { OnchainKitProvider } from '@coinbase/onchainkit';
import { WagmiProvider } from 'wagmi';
import { wagmiConfig } from '../lib/wagmi';
Expand All @@ -17,10 +17,7 @@ function OnchainProviders({ children }: Props) {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<OnchainKitProvider
apiKey={process.env.NEXT_PUBLIC_ONCHAINKIT_API_KEY}
chain={base}
>
<OnchainKitProvider apiKey={process.env.NEXT_PUBLIC_ONCHAINKIT_API_KEY} chain={base as any}>
<RainbowKitProvider modalSize="compact">
{children}
</RainbowKitProvider>
Expand Down
13 changes: 13 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,17 @@
body {
@apply bg-background text-foreground;
}
}

.fc-authkit-qrcode-dialog{
color: #27272a;
}

.fc-authkit-signin-button button{
padding-left: 15px;
padding-right: 15px;
padding-top: 6px;
padding-bottom: 6px;
border-radius: 36px !important;
font-family: __Karla_f3a0e4, __Karla_Fallback_f3a0e4, sans-serif;
}
4 changes: 2 additions & 2 deletions app/hackathons/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export default async function HackathonBySlugPage() {
const endDate = new Date(hackathon.end_date).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' });

return (
<div className="pt-10 md:pt-5">
<div className="text-white flex flex-col gap-1 items-start pl-[7.5%] md:pl-[4.5%]">
<div className="pt-0">
<div className="text-white flex flex-col gap-1 items-start pl-[2.5%] ml-2 md:ml-0">
<HackathonNav hackathon={hackathon} />
<div className="flex flex-row flex-wrap md:flex-nowrap justify-between w-full mt-8 ml-1 mr-1">
<div className="flex flex-col md:w-1/2 gap-2">
Expand Down
3 changes: 2 additions & 1 deletion app/hackathons/[slug]/teams/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @next/next/no-img-element */
import React from 'react';
import { headers } from 'next/headers';
import { db, sql, createInvite } from '@/kysely';
import { db, sql } from '@/kysely';
import { auth } from '@/auth';
import HackathonNav from '@/app/components/hackathon-nav';
import InviteButton from '@/app/components/invite-button';
Expand All @@ -12,6 +12,7 @@ import { redirect } from 'next/navigation';
import { BASE_URL } from '@/app/lib/utils';
import SubmitTeamButton from '@/app/components/submit-team-button';
import { getHackathon, getTeam } from '@/app/lib/fetchers';
import { createInvite } from '@/app/lib/server/invites';

export default async function TeamByIdPage() {
const headerList = headers();
Expand Down
3 changes: 2 additions & 1 deletion app/hackathons/[slug]/teams/accept-invite/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable @next/next/no-img-element */
import React from 'react';
import { headers } from 'next/headers';
import { db, acceptInvite } from '@/kysely';
import { db } from '@/kysely';
import { auth } from '@/auth';
import { acceptInvite } from '@/app/lib/server/invites';

export default async function AcceptInvitePage() {
const headerList = headers();
Expand Down
100 changes: 15 additions & 85 deletions app/hackathons/[slug]/your-team/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @next/next/no-img-element */
import React from 'react';
import { headers } from 'next/headers';
import { db, sql, createInvite } from '@/kysely';
import { db, sql } from '@/kysely';
import { auth } from '@/auth';
import HackathonNav from '@/app/components/hackathon-nav';
import InviteButton from '@/app/components/invite-button';
Expand All @@ -11,44 +11,22 @@ import EditTeamButton from '@/app/components/edit-team-button';
import { redirect } from 'next/navigation';
import { BASE_URL } from '@/app/lib/utils';
import SubmitTeamButton from '@/app/components/submit-team-button';
import { getHackathon } from '@/app/lib/fetchers';
import Error from '@/app/components/error';
import { createTeam, handleDeleteTeam, handleGenerateInvite, handleLeaveTeam, handleSaveTeam, handleSubmitTeam } from '@/app/lib/server/teams';

export default async function YourTeamPage() {
const headerList = headers();
const pathname = headerList.get("x-current-path") as string;
const pathnameParts = pathname.split('/');
const slug = pathnameParts[2];
const slug = (headerList.get("x-current-path") as string).split('/')[2];
const session = await auth();

if (!session?.user) {
return (
<div className="flex items-center justify-center min-h-screen text-white text-2xl">
<p>You are not logged in. Log in above or <a href="/" className="underline">click here to return home</a></p>
</div>
);
}
if (!session?.user) return <Error message={`You are not logged in.`} />

const user = await db.selectFrom('users').selectAll().where('name', '=', session.user.name ?? "").executeTakeFirst();
if (!user) return <Error message={`You are not logged in.`} />

if (!user) {
return (
<div className="flex items-center justify-center min-h-screen text-white text-2xl">
<p>You are not logged in. Log in above or <a href="/" className="underline">click here to return home</a></p>
</div>
);
}

const hackathon = await db.selectFrom('hackathons')
.selectAll()
.where('slug', '=', slug)
.executeTakeFirst();

if (!hackathon) {
return (
<div className="flex items-center justify-center min-h-screen text-white text-2xl">
<p>No data found. <a href="/" className="underline">Return to home</a></p>
</div>
);
}
const hackathon = await getHackathon(slug);
if (!hackathon) return <Error message={`Hackathon with slug ${slug} not found.`} />

const team = await db.selectFrom('teams')
.selectAll()
Expand All @@ -71,62 +49,13 @@ export default async function YourTeamPage() {
const hoursRemaining = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutesRemaining = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));

async function createTeam(name: string, description: string = '') {
'use server';
const emptyJsonArray = JSON.stringify([]);
await db.insertInto('teams').values({
name: name,
description: description,
hackathon_id: hackathon?.id ?? 0,
fids: [user?.id ?? 0],
wallet_address: '',
embeds: sql`${emptyJsonArray}::jsonb`
}).execute();
}

async function handleGenerateInvite(): Promise<string> {
'use server';
const token = await createInvite(user?.id ?? 0, team?.id ?? 0);
const shareLink = `${BASE_URL}/hackathons/${hackathon?.slug}/teams/share-invite?token=${token}`;
redirect(shareLink);
}

async function handleDeleteTeam() {
'use server';
await db.deleteFrom('teams').where('id', '=', team?.id ?? 0).execute();
redirect('/hackathons/' + hackathon?.slug + '/your-team');
}

async function handleLeaveTeam() {
'use server';
await db.updateTable('teams')
.set({ fids: sql`array_remove(fids, ${user?.id ?? 0})` })
.where('id', '=', team?.id ?? 0)
.execute();
redirect('/hackathons/' + hackathon?.slug + '/your-team');
}

async function handleSaveTeam(name: string, description: string, walletAddress: string, embeds: any) {
'use server';
await db.updateTable('teams')
.set({ name, description, wallet_address: walletAddress, embeds: sql`${JSON.stringify(embeds)}::jsonb` })
.where('id', '=', team?.id ?? 0)
.execute();
redirect('/hackathons/' + hackathon?.slug + '/your-team');
}

async function handleSubmitTeam(name: string, description: string, walletAddress: string, embeds: any) {
'use server';
await db.updateTable('teams')
.set({ name, description, wallet_address: walletAddress, embeds: sql`${JSON.stringify(embeds)}::jsonb`, submitted_at: new Date() })
.where('id', '=', team?.id ?? 0)
.execute();
redirect('/hackathons/' + hackathon?.slug + '/your-team');
const callHandleGenerateInvite = async() => {
return await handleGenerateInvite(user?.id, team?.id ?? 0, hackathon.slug);
}

return (
<div className="pt-5">
<div className="text-white flex flex-col gap-1 items-start pl-[4.5%] pr-[4.5%]">
<div className="">
<div className="text-white flex flex-col gap-1 items-start pl-[2.5%] pr-[4.5%]">
<HackathonNav hackathon={hackathon} />
<div className="mt-5 mb-3 flex flex-col items-start">
<p className="text-2xl font-semibold">Your Team</p>
Expand Down Expand Up @@ -159,7 +88,7 @@ export default async function YourTeamPage() {
<p className="text-2xl">Actions</p>
{!team.submitted_at ? (
<div className="flex flex-col md:flex-row items-start md:items-center gap-2 mb-3">
<InviteButton handleGenerateInvite={handleGenerateInvite} />
<InviteButton handleGenerateInvite={callHandleGenerateInvite} />
{team.submitted_at ? (
<p className="text-sm mt-3">Submitted at: {new Date(team.submitted_at).toLocaleString()}</p>
) : (
Expand All @@ -181,6 +110,7 @@ export default async function YourTeamPage() {
<DeleteOrLeaveTeamButton
teamId={team.id}
userId={user.id}
hackathonSlug={hackathon.slug}
teamMembers={teamMembers}
handleDeleteTeam={handleDeleteTeam}
handleLeaveTeam={handleLeaveTeam}
Expand Down
Loading

0 comments on commit a214bb3

Please sign in to comment.