Skip to content

Commit

Permalink
feat(join): redirect to setting page after join
Browse files Browse the repository at this point in the history
  • Loading branch information
jsun969 committed Feb 16, 2024
1 parent c50f138 commit 62834ab
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 29 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"react-icons": "^4.12.0",
"redis": "^4.6.13",
"square": "^34.0.1",
"swr": "^2.2.5",
"zod": "^3.22.4",
"zustand": "^4.4.7"
},
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 16 additions & 10 deletions src/app/(account)/join/steps/StepFour.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Button from '@/components/Button';
import Field from '@/components/Field';
import { fetcher } from '@/lib/fetcher';
import React, { useState } from 'react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import useSWRMutation from 'swr/mutation';
import { useJoinUsStep, useJoinUsStudentInfo, useSetJoinUsHeading } from '../store';

export default function StepFour() {
Expand All @@ -16,19 +18,23 @@ export default function StepFour() {
const { prevStep } = useJoinUsStep();
const { studentInfo } = useJoinUsStudentInfo();

const handleSignUp = async (e: React.ChangeEvent<any>) => {
const router = useRouter();
const createMember = useSWRMutation('member', fetcher.post, {
onError: () => {
setAgreementError('Server error.');
},
onSuccess: () => {
router.push('/settings');
},
});

const handleSignUp = async () => {
setAgreementError(null);
if (!agreement) {
setAgreementError('Please agree to the terms');
return;
}
// TODO(#17): Payment
try {
const res = await fetcher.post('member', { json: studentInfo }).json();
console.log(res);
} catch {
setAgreementError('Server error.');
}
createMember.trigger(studentInfo);
};

const toggleAgreement = () => setAgreement(!agreement);
Expand All @@ -48,7 +54,7 @@ export default function StepFour() {
<Button onClick={prevStep} colour="orange">
Back
</Button>
<Button onClick={handleSignUp} colour="purple">
<Button onClick={handleSignUp} colour="purple" loading={createMember.isMutating}>
Sign up
</Button>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/app/api/member/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { db } from '@/db';
import { members } from '@/db/schema';
import { memberTable } from '@/db/schema';
import { currentUser } from '@clerk/nextjs';
import { createInsertSchema } from 'drizzle-zod';
import { z } from 'zod';

export async function POST(request: Request) {
const req = await request.json();
const schema = createInsertSchema(members, {
const schema = createInsertSchema(memberTable, {
clerkId: z.undefined(),
email: z.undefined(),
});
Expand All @@ -21,7 +21,7 @@ export async function POST(request: Request) {
return new Response(JSON.stringify(reqBody.error.format()), { status: 400 });
}

await db.insert(members).values({
await db.insert(memberTable).values({
clerkId: user.id,
email: user.emailAddresses[0].emailAddress,
...reqBody.data,
Expand Down
19 changes: 7 additions & 12 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,24 @@ interface ButtonProps {
children: React.ReactNode;
colour: Colour;
href?: string;
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void | Promise<void>;
onClick?: () => void;
type?: 'button' | 'submit' | 'reset';
width?: string;
loading?: boolean;
}

const Button = ({ children, colour, href, onClick, width, type }: ButtonProps) => {
const Button = ({ children, colour, href, onClick, width, type, loading }: ButtonProps) => {
const isAnchor = !!href;
const Component = isAnchor ? 'a' : 'button';

const buttonStyles = `whitespace-nowrap py-4 px-12 md:py-1 md:px-2 lg:py-2 lg:px-6 border-2 border-black font-bold hover:bg-yellow transition-colors duration-300 ${BG_COLOURS[colour]} text-lg md:text-base`;
const buttonClasses = width ? `${buttonStyles} ${width}` : buttonStyles;

return (
<FancyRectangle colour="black" offset="4" filled={true}>
<FancyRectangle colour="black" offset="4" filled>
<Component
href={isAnchor ? href : undefined}
onClick={
onClick as (
e: React.MouseEvent<HTMLButtonElement> | React.MouseEvent<HTMLAnchorElement>
) => void | Promise<void>
}
onClick={onClick}
type={isAnchor ? undefined : type}
className={buttonClasses}
className={`${width} ${BG_COLOURS[colour]} ${isAnchor ? 'hover:bg-yellow' : 'hover:enabled:bg-yellow'} whitespace-nowrap border-2 border-black px-12 py-4 text-lg font-bold transition-colors duration-300 disabled:cursor-wait disabled:grayscale md:px-2 md:py-1 md:text-base lg:px-6 lg:py-2`}
disabled={loading}
>
{children}
</Component>
Expand Down
6 changes: 3 additions & 3 deletions src/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { sql } from 'drizzle-orm';
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { nanoid } from 'nanoid';

export const members = sqliteTable('members', {
export const memberTable = sqliteTable('members', {
id: text('id')
.$defaultFn(() => nanoid())
.primaryKey(),
Expand All @@ -23,8 +23,8 @@ export const members = sqliteTable('members', {
studentId: text('student_id'),
gender: text('gender', { enum: GENDERS }).notNull(),
ageBracket: text('age_bracket', { enum: AGE_BRACKETS }).notNull(),
degree: text('degree', { enum: DEGREES }),
studentType: text('student_type', { enum: STUDENT_TYPES }),
degree: text('degree', { enum: [...DEGREES, ''] }),
studentType: text('student_type', { enum: [...STUDENT_TYPES, ''] }),

emailPreferences: text('email_preferences', { mode: 'json' }),

Expand Down
9 changes: 8 additions & 1 deletion src/lib/fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import ky from 'ky';

export const fetcher = ky.create({ prefixUrl: '/api' });
const kyInstance = ky.create({ prefixUrl: '/api' });

export const fetcher = {
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,
};

0 comments on commit 62834ab

Please sign in to comment.