Skip to content

Commit

Permalink
feat: add support for create team
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkPhoenix2704 committed Apr 20, 2024
1 parent 51b9029 commit bbed79e
Show file tree
Hide file tree
Showing 17 changed files with 373 additions and 149 deletions.
31 changes: 31 additions & 0 deletions app/api/users/[githubID]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { db } from "@/utils/db";
import { validateRequest } from "@/utils/lucia";
import type { NextRequest } from "next/server";

export async function GET(
_request: NextRequest,
{ params }: { params: { githubID: string } },
): Promise<Response> {
const { session } = await validateRequest();

if (!session) {
return new Response(null, {
status: 401,
headers: {
Location: "/auth/login",
},
});
}

const user = await db.user.findUnique({
where: {
githubId: params.githubID ?? "",
},
select: {
githubId: true,
},
});
return new Response(JSON.stringify(user), {
status: user ? 200 : 404,
});
}
2 changes: 1 addition & 1 deletion app/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const Button = ({
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
strokeWidth="4"
/>
<path
className="opacity-75"
Expand Down
13 changes: 7 additions & 6 deletions app/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import type { InputHTMLAttributes } from "react";
import { forwardRef, type InputHTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";

export const Input = ({
className,
...rest
}: InputHTMLAttributes<HTMLInputElement>) => {
export const Input = forwardRef<
HTMLInputElement,
InputHTMLAttributes<HTMLInputElement>
>(({ className, ...rest }, ref) => {
return (
<input
ref={ref}
className={twMerge(
"w-full h-11 px-4 placeholder-text-black/25 bg-white/15 focus-within:ring-0 focus:border-primary/15 focus:shadow-primary/15 hover:bg-white/25 focus:bg-white/25 focus:border-1 text-white ring-0 outline-transparent rounded-[10px] border-gray-300",
className,
)}
{...rest}
/>
);
};
});
1 change: 1 addition & 0 deletions app/events/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const EventsPage = async ({ searchParams }: SearchParamProps) => {

const { user } = await validateRequest();
const currentEvent = await getCurrentEvent(user);

const events = await getEvents();

return (
Expand Down
19 changes: 15 additions & 4 deletions app/events/results/[eventID]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,27 @@ import { db } from "@/utils/db";
import { EventStatus, ProjectStatus } from "@/utils/types";
import {
getResultsParamsSchema,
validateRequest,
validateRequestSchema,
} from "@/utils/validateRequest";
import type { NextRequest } from "next/server";

export async function GET(
_request: NextRequest,
{ params }: { params: { eventID: string } },
): Promise<Response> {
const data = validateRequest(getResultsParamsSchema, params);
if (data instanceof Response) return data;
) {
const validation = validateRequestSchema(
getResultsParamsSchema,
params,
true,
);

if (validation instanceof Response || !validation.success) {
if (validation instanceof Response) {
return validation;
}
return;
}
const data = validation.data;

const event = await db.event.findUnique({
where: {
Expand Down
39 changes: 20 additions & 19 deletions app/events/ui/CurrentEvent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable @next/next/no-img-element */
import Link from "next/link";
import Image from "next/image";
import { Calendar } from "lucide-react";
Expand All @@ -7,6 +6,7 @@ import { isProfileComplete as isProfileCompleteFn } from "@/utils/user";
import dayjs from "dayjs";
import { redirect } from "next/navigation";
import { CreateTeamModal } from "./modal/CreateTeamModal";
import { EventStatus, TeamMemberRole } from "@/utils/types";

export const CurrentEvent = ({
user,
Expand All @@ -28,7 +28,7 @@ export const CurrentEvent = ({
date: Date;
location: string;
} | null;
registeredTeam: {
team: {
id: string;
repo: string;
eventId: string;
Expand All @@ -41,11 +41,12 @@ export const CurrentEvent = ({
}) => {
const isProfileComplete = isProfileCompleteFn(user);

const { event, registeredTeam } = data;
const { event, team } = data;

const isEditable = registeredTeam
? registeredTeam.members.some((member) => member.userId === user?.id)
: !!user;
const isEditable = team?.members.some(
(member) =>
member.userId === user?.id && member.role === TeamMemberRole.LEADER,
);

if (!event) {
redirect("/");
Expand All @@ -61,14 +62,14 @@ export const CurrentEvent = ({
} = event;

const url = user
? registeredTeam
? team
? isEditable
? status === "REGISTRATION"
? status === EventStatus.REGISTRATION
? `/events/?update=true&eventId=${event.id}`
: `/events/?view=true&eventId=${event.id}`
: `/events/?view=true&eventId=${event.id}`
: isProfileComplete
? status === "REGISTRATION"
? status === EventStatus.REGISTRATION
? `/events/?register=true&eventId=${event.id}`
: ""
: `/events/?register=true&eventId=${event.id}`
Expand All @@ -77,9 +78,9 @@ export const CurrentEvent = ({
return (
<div className="flex flex-col lg:flex-row w-full items-start gap-4">
{/* Modals (you'll likely need to keep these as React components due to state management) */}
{/* {registeredTeam && isOpenUpdateModal && (
{/* {team && isOpenUpdateModal && (
<UpdateTeamModal
teamId={registeredTeam.teamID}
teamId={team.teamID}
isOpen={isOpenUpdateModal}
onClose={onCloseUpdateModal}
image={imageWhite}
Expand Down Expand Up @@ -119,13 +120,13 @@ export const CurrentEvent = ({

<div
className={`flex items-center justify-center py-2 rounded-b-md ${
registeredTeam ? "bg-primary" : "bg-red-500"
team ? "bg-primary" : "bg-red"
}`}
>
<span className="font-medium text-black text-base">
{registeredTeam
{team
? "Registered 🎉"
: status === "REGISTRATION"
: status === EventStatus.REGISTRATION
? "Register Now"
: "Registration Closed"}
</span>
Expand All @@ -142,22 +143,22 @@ export const CurrentEvent = ({
type="button"
className={`bg-white hover:bg-primary active:bg-primary active:ring-2 active:ring-primary transition-all font-medium text-sm px-6 py-3 rounded-md ${
user &&
registeredTeam &&
team &&
isEditable &&
status === "REGISTRATION"
status === EventStatus.REGISTRATION
? ""
: "bg-gray-400 cursor-not-allowed"
}`}
>
{user
? registeredTeam
? team
? isEditable
? status === "REGISTRATION"
? status === EventStatus.REGISTRATION
? "Update Team"
: "View Team"
: "View Team"
: isProfileComplete
? status === "REGISTRATION"
? status === EventStatus.REGISTRATION
? "Register Team"
: "Closed"
: "Register Team"
Expand Down
74 changes: 74 additions & 0 deletions app/events/ui/Member.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"use client";
import React from "react";
import { Controller, useFieldArray, useFormContext } from "react-hook-form";
import { Input } from "@/app/components/Input";
import { twMerge } from "tailwind-merge";

interface MemberProps {
loading: boolean;
isEditable: boolean;
}

const Member = ({ loading, isEditable }: MemberProps) => {
const { control } = useFormContext();
const { fields, append, remove } = useFieldArray({
control,
name: "members",
});

return (
<div className="flex flex-col">
<div>
<label htmlFor="name" className="pb-2">
Team Members
</label>
{fields.map((member: Record<"id", string>, index: number) => (
<Controller
name={`members[${index}]`}
key={member.id}
control={control}
render={({ field }) => (
<div className="w-full flex mt-2">
<Input
ref={field.ref}
className="rounded-r-none"
disabled={loading || !isEditable}
placeholder="Github Username"
onChange={field.onChange}
onBlur={field.onBlur}
name={`members.${index}.value`}
value={field.value}
/>
<span
className={twMerge(
loading || !isEditable
? "cursor-not-allowed"
: "cursor-pointer bg-white/25",
"text-red font-semibold bg-white/15 flex items-center px-2 border-l border-l-white/15 rounded-r-md",
)}
onKeyDown={() => !loading && isEditable && remove(index)}
onClick={() => !loading && isEditable && remove(index)}
>
Remove
</span>
</div>
)}
/>
))}
</div>

{fields.length < 3 && (
<div
className="flex items-center mt-4 text-primary gap-2 py-1 justify-center border-1 pb-1 transition-all duration-200 ease-in-out border-primary rounded-md bg-primary/15 hover:bg-primary/15 cursor-pointer hover:border-dashed"
onClick={() => (loading || !isEditable ? null : append(""))}
onKeyDown={() => (loading || !isEditable ? null : append(""))}
>
<img className="h-10 w-10" src="/images/add-square.svg" alt="add" />
<span>ADD TEAM MEMBER</span>
</div>
)}
</div>
);
};

export { Member };
Loading

0 comments on commit bbed79e

Please sign in to comment.