Skip to content

Commit

Permalink
Merge pull request #177 from DNDACADEMY/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
saseungmin authored Aug 23, 2024
2 parents b35d836 + 6f14fed commit 9b782af
Show file tree
Hide file tree
Showing 14 changed files with 1,030 additions and 943 deletions.
894 changes: 0 additions & 894 deletions .yarn/releases/yarn-4.3.1.cjs

This file was deleted.

925 changes: 925 additions & 0 deletions .yarn/releases/yarn-4.4.0.cjs

Large diffs are not rendered by default.

12 changes: 1 addition & 11 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,4 @@ enableGlobalCache: false

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.3.1.cjs

packageExtensions:
"react-responsive-masonry@*":
peerDependencies:
"prop-types": "*"

"@storybook/nextjs@*":
peerDependencies:
sass: "*"
sass-loader: "*"
yarnPath: .yarn/releases/yarn-4.4.0.cjs
2 changes: 2 additions & 0 deletions apps/admin/@types/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ namespace NodeJS {
GOOGLE_CLIENT_EMAIL: string;
GOOGLE_PRIVATE_KEY: string;
CRON_SECRET: string;
REVALIDATION_TOKEN: string;
WEB_ORIGIN: string;
}
}
38 changes: 4 additions & 34 deletions apps/admin/src/actions/count.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import { revalidatePath } from 'next/cache';

import { put } from '@vercel/blob';

import { revalidateWebPath } from '@/app/api/handler';

type CountStateType = {
message: string;
messageType?: 'error' | 'success';
};

// eslint-disable-next-line import/prefer-default-export
export async function totalCountStatusAction(
_: CountStateType | null,
formData: FormData,
Expand All @@ -31,6 +34,7 @@ export async function totalCountStatusAction(
addRandomSuffix: false,
});

await revalidateWebPath(['/', '/dnd/about']);
revalidatePath('/total-count-status');

return {
Expand All @@ -44,37 +48,3 @@ export async function totalCountStatusAction(
};
}
}

export async function currentApplicantCountAction(
_: CountStateType | null,
formData: FormData,
): Promise<CountStateType> {
try {
const requestForm = {
designerApplicantCount: formData.get('designerApplicantCount'),
developerApplicantCount: formData.get('developerApplicantCount'),
};

const jsonString = JSON.stringify(requestForm);

const requestBlob = new Blob([jsonString], { type: 'application/json' });

await put('current_applicant_count.json', requestBlob, {
access: 'public',
token: process.env.DND_ACADEMY_V2_BLOB_READ_WRITE_TOKEN,
addRandomSuffix: false,
});

revalidatePath('/current-applicant-count');

return {
message: '수정사항이 반영되었습니다. 캐시 적용으로 실제 적용까지는 최대 5분정도 소요됩니다.',
messageType: 'success',
};
} catch (error) {
return {
message: '수정사항이 반영되지 않았습니다. 잠시 후 다시 시도해주세요.',
messageType: 'error',
};
}
}
12 changes: 11 additions & 1 deletion apps/admin/src/app/api/cron/current-applicant-count/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

import { updateCurrentApplicantCount } from '@/app/api/handler';
import { revalidateWebPath, updateCurrentApplicantCount } from '@/app/api/handler';

export const dynamic = 'force-dynamic';

Expand All @@ -17,6 +18,15 @@ export async function PUT(request: NextRequest) {

const currentApplicantCountForm = await updateCurrentApplicantCount();

revalidatePath('/current-applicant-count');
const response = await revalidateWebPath('/');

if (!response.revalidated) {
return NextResponse.json(currentApplicantCountForm, {
status: 400,
});
}

return NextResponse.json(currentApplicantCountForm, {
status: 200,
});
Expand Down
12 changes: 11 additions & 1 deletion apps/admin/src/app/api/current-applicant-count/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { revalidatePath } from 'next/cache';
import { NextResponse } from 'next/server';

import { updateCurrentApplicantCount } from '@/app/api/handler';
import { revalidateWebPath, updateCurrentApplicantCount } from '@/app/api/handler';

export const dynamic = 'force-dynamic';

Expand All @@ -9,6 +10,15 @@ export const runtime = 'nodejs';
export async function PUT() {
const currentApplicantCountForm = await updateCurrentApplicantCount();

revalidatePath('/current-applicant-count');
const response = await revalidateWebPath('/');

if (!response.revalidated) {
return NextResponse.json(currentApplicantCountForm, {
status: 400,
});
}

return NextResponse.json(currentApplicantCountForm, {
status: 200,
});
Expand Down
22 changes: 22 additions & 0 deletions apps/admin/src/app/api/handler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { api, type FetchError } from '@dnd-academy/core';
import { put } from '@vercel/blob';
import { JWT } from 'google-auth-library';
import { GoogleSpreadsheet } from 'google-spreadsheet';
Expand Down Expand Up @@ -37,3 +38,24 @@ export const updateCurrentApplicantCount = async () => {

return currentApplicantCountForm;
};

export async function revalidateWebPath(paths: string | string[]) {
try {
const response = await api<{
revalidated: boolean; message?: string; now?: number;
}, { secret: string; paths: string | string[]; }>({
method: 'GET',
url: `${process.env.WEB_ORIGIN}/api/revalidate`,
params: {
secret: process.env.REVALIDATION_TOKEN,
paths,
},
});

return response;
} catch (error) {
const errorResponse = error as FetchError;

return { revalidated: false, message: 'Error revalidating', status: errorResponse.response?.status || 500 };
}
}
5 changes: 4 additions & 1 deletion apps/admin/src/app/current-applicant-count/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ async function page() {
<>
<PageTitle
title="현재 지원자 수"
subTitle="캐시 적용으로 실제 적용까지는 최대 5분정도 소요됩니다."
subTitle="현재 지원자 수는 google form의 spreadsheet를 통해 실시간으로 업데이트 됩니다."
/>
<div className={styles.counter}>
오늘까지&nbsp;
<Counter count={currentApplicantCount} />
명이 지원했어요!
</div>
<CurrentApplicantCountAction />
<strong>
기본적으로 매일 00:00에 자동으로 반영되지만, 클릭시에는 즉시 반영할 수 있습니다.
</strong>
</>
);
}
Expand Down
2 changes: 2 additions & 0 deletions apps/web/@types/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ namespace NodeJS {
NEXT_PUBLIC_VERCEL_BLOB_HOST: string;
NEXT_PUBLIC_GA_MEASUREMENT_ID: string;
NEXT_PUBLIC_CHANNEL_IO_PLUGIN_KEY: string;
REVALIDATION_TOKEN: string;
ADMIN_ORIGIN: string;
}
}
25 changes: 25 additions & 0 deletions apps/web/src/app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

// eslint-disable-next-line import/prefer-default-export
export async function GET(request: NextRequest) {
const secret = request.nextUrl.searchParams.get('secret');
const paths = request.nextUrl.searchParams.get('paths');

if (secret !== process.env.REVALIDATION_TOKEN) {
return NextResponse.json({ revalidated: false, message: 'Invalid token' }, { status: 401 });
}

if (!paths) {
return NextResponse.json({ revalidated: false, message: 'Path is required' }, { status: 400 });
}

try {
paths.split(',').forEach((path) => {
revalidatePath(path);
});
return NextResponse.json({ revalidated: true, now: Date.now() });
} catch (err) {
return NextResponse.json({ revalidated: false, message: 'Error revalidating' }, { status: 500 });
}
}
2 changes: 2 additions & 0 deletions apps/web/src/lib/constants/time.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/* eslint-disable import/prefer-default-export */
export const ONE_HOUR = 3600;

export const ONE_DAY = 86400;
20 changes: 20 additions & 0 deletions apps/web/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
const response = NextResponse.next();

if (request.nextUrl.pathname.startsWith('/api/revalidate')) {
response.headers.set('Access-Control-Allow-Origin', process.env.ADMIN_ORIGIN);
response.headers.set('Access-Control-Allow-Methods', 'GET,OPTIONS');
response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}

return response;
}

export const config = {
matcher: [
'/api/revalidate/:path*',
],
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@
"email": "[email protected]",
"url": "https://github.com/DNDACADEMY/dnd-academy-v2/issues"
},
"packageManager": "yarn@4.3.1"
"packageManager": "yarn@4.4.0"
}

0 comments on commit 9b782af

Please sign in to comment.