Skip to content

Commit

Permalink
Change Redux to Zustand and RTK Query to Server Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
seheon99 committed Apr 22, 2024
1 parent 0e285f6 commit 0ee8a06
Show file tree
Hide file tree
Showing 106 changed files with 2,617 additions and 3,042 deletions.
337 changes: 180 additions & 157 deletions .pnp.cjs

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"eslint.nodePath": ".yarn/sdks",
"typescript.tsdk": ".yarn/sdks/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"prettier.prettierPath": ".yarn/sdks/prettier/index.cjs"
}
"prettier.prettierPath": ".yarn/sdks/prettier/index.cjs",
"svg.preview.background": "dark-transparent"
}
324 changes: 162 additions & 162 deletions .yarn/releases/yarn-4.1.0.cjs → .yarn/releases/yarn-4.1.1.cjs

Large diffs are not rendered by default.

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

nodeLinker: pnp

yarnPath: .yarn/releases/yarn-4.1.0.cjs
yarnPath: .yarn/releases/yarn-4.1.1.cjs
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint:css": "stylelint 'src/**/*.tsx'",
"lint:style": "stylelint 'src/**/*.tsx'",
"postinstall": "husky install",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@reduxjs/toolkit": "^1.9.7",
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"next": "^14.1.0",
"react": "^18",
"react-dom": "^18",
"react-redux": "^8.1.3",
"return-fetch": "^0.4.5",
"swiper": "^11.0.5"
"swiper": "^11.0.5",
"zustand": "^4.5.2"
},
"devDependencies": {
"@emotion/babel-plugin": "^11.11.0",
Expand All @@ -37,6 +37,7 @@
"@storybook/react": "^8.0.0-alpha.8",
"@storybook/test": "^8.0.0-alpha.8",
"@svgr/webpack": "^8.1.0",
"@types/jsonwebtoken": "^9",
"@types/lodash": "^4",
"@types/node": "^20",
"@types/react": "^18",
Expand All @@ -60,7 +61,7 @@
"typescript": "5.3.2",
"webpack": "^5.89.0"
},
"packageManager": "[email protected].0",
"packageManager": "[email protected].1",
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
Expand Down
Binary file removed public/fonts/SpoqaHanSansNeo-Bold.woff2
Binary file not shown.
Binary file removed public/fonts/SpoqaHanSansNeo-Light.woff2
Binary file not shown.
Binary file removed public/fonts/SpoqaHanSansNeo-Medium.woff2
Binary file not shown.
Binary file removed public/fonts/SpoqaHanSansNeo-Regular.woff2
Binary file not shown.
Binary file removed public/fonts/SpoqaHanSansNeo-Thin.woff2
Binary file not shown.
1 change: 0 additions & 1 deletion public/next.svg

This file was deleted.

1 change: 0 additions & 1 deletion public/vercel.svg

This file was deleted.

33 changes: 26 additions & 7 deletions src/actions/auth.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
'use server';

import { headers } from 'next/headers';

import { SocialPlatform } from '#/entities/socialPlatform';
import { AuthTokens } from '#/types/auth-tokens';
import { fitFetch } from '#/utilities/fetch';

interface GetLoginPageResponse {
loginPageUrl: string;
}

export async function getLoginPage(platform: SocialPlatform): Promise<string> {
const response = await fetch(`/v1/auth/social/${platform}/login-page`);
const host = headers().get('host');
const response = await fitFetch(`/v1/auth/social/${platform}/login-page`, {
headers: {
Origin: `http://${host}`,
},
});
const json = (await response.json()) as GetLoginPageResponse;
return json.loginPageUrl;
}
Expand All @@ -22,14 +31,24 @@ interface AcquireTokenProps {
code: string;
}

export async function acquireToken({
platform,
code,
}: AcquireTokenProps): Promise<AcquireTokenResponse> {
const response = await fetch(`/v1/auth/social/${platform}/login`, {
export async function acquireToken({ platform, code }: AcquireTokenProps): Promise<AuthTokens> {
const host = headers().get('host');
const response = await fitFetch(`/v1/auth/social/${platform}/login`, {
method: 'POST',
body: JSON.stringify({ code }),
headers: {
Origin: `http://${host}`,
},
});
if (!response.ok) {
throw new Error(
`Failed to acquire token: (${response.status}) ${JSON.stringify(await response.json())}`
);
}

const json = (await response.json()) as AcquireTokenResponse;
return json;
return {
accessToken: json.accessToken,
refreshToken: json.refreshToken,
} satisfies AuthTokens;
}
7 changes: 5 additions & 2 deletions src/actions/region.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
'use server';

import { Region } from '#/entities/region';
import { fitFetch } from '#/utilities/fetch';

interface GetRegionsResponse {
regionList: {
Expand All @@ -8,7 +11,7 @@ interface GetRegionsResponse {
}

export async function getRegions(): Promise<Region[]> {
const response = await fetch(`/v1/region`);
const response = await fitFetch(`/v1/region`);
const json = (await response.json()) as GetRegionsResponse;
return json.regionList;
}
Expand All @@ -23,7 +26,7 @@ interface CreateRegionResponse {
}

export async function createRegion({ displayName }: CreateRegionRequest): Promise<Region> {
const response = await fetch(`/v1/region`, {
const response = await fitFetch(`/v1/region`, {
method: 'POST',
body: JSON.stringify({ displayName }),
});
Expand Down
65 changes: 65 additions & 0 deletions src/actions/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use server';

import { cookies } from 'next/headers';

// import jwt from 'jsonwebtoken';

import { AuthTokens } from '#/types/auth-tokens';
// import { fitFetch } from '../utilities/fetch';

const SESSION_KEY = 'session';

// async function refreshTokens(refreshToken: string): Promise<AuthTokens> {
// const response = await fitFetch('/v1/auth/refresh', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({ refreshToken }),
// });
// const json = await response.json();
// return json;
// }

// function checkTokenExpiration(token: string): boolean {
// try {
// const decoded = jwt.decode(token) as { exp: number };
// return decoded.exp * 1000 > Date.now() + 60 * 1000; // 60 second buffer
// } catch {
// return false;
// }
// }

export async function getToken(): Promise<string | null> {
const sessionData = cookies().get(SESSION_KEY)?.value;
if (!sessionData) {
return null;
}

try {
const { accessToken, refreshToken } = JSON.parse(atob(sessionData));
// if (checkTokenExpiration(accessToken)) {
// const newTokens = await refreshTokens(refreshToken);
// setTokens(newTokens);
// return newTokens.accessToken;
// }
return accessToken;
} catch {
return null;
}
}

export async function setTokens(tokens: AuthTokens | null) {
if (!tokens) {
cookies().delete(SESSION_KEY);
return;
}

const sessionData = btoa(JSON.stringify(tokens));
cookies().set(SESSION_KEY, sessionData, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 60 * 60 * 24 * 7, // One week
path: '/',
});
}
10 changes: 7 additions & 3 deletions src/actions/skill-set.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
'use server';

import { Position } from '#/entities/position';
import { Skill } from '#/entities/skill';
import { fitFetch } from '#/utilities/fetch';

interface GetPositionsResponse {
positionList: {
id: number;
displayName: string;
imageUrl: string;
skillList: {
id: number;
displayName: string;
Expand All @@ -13,7 +17,7 @@ interface GetPositionsResponse {
}

export async function getPositions(): Promise<Position[]> {
const response = await fetch(`/v1/skill-set/position`);
const response = await fitFetch(`/v1/skill-set/position`);
const json = (await response.json()) as GetPositionsResponse;
return json.positionList;
}
Expand All @@ -26,7 +30,7 @@ interface GetSkillsResponse {
}

export async function getSkills(): Promise<Skill[]> {
const response = await fetch(`/v1/skill-set/skill`);
const response = await fitFetch(`/v1/skill-set/skill`);
const json = (await response.json()) as GetSkillsResponse;
return json.skillList;
}
Expand All @@ -39,7 +43,7 @@ interface GetPositionSkillsResponse {
}

export async function getPositionSkills(positionId: number): Promise<Skill[]> {
const response = await fetch(`/v1/skill-set/position/${positionId}/skill`);
const response = await fitFetch(`/v1/skill-set/position/${positionId}/skill`);
const json = (await response.json()) as GetPositionSkillsResponse;
return json.skillList;
}
50 changes: 40 additions & 10 deletions src/actions/user.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
'use server';

import { PolicyAgreement, PolicyType } from '#/entities/policy';
import { User } from '#/entities/user';
import { User } from '#/types/user';
import { fitFetch } from '#/utilities/fetch';

export async function getMe(): Promise<User> {
const response = await fetch(`/v1/user`);
export async function getMe(): Promise<User | null> {
const response = await fitFetch(`/v1/user`);
const json = (await response.json()) as User;

if (!response.ok) {
if (response.status === 401) {
return null;
}
throw new Error(`Failed to get user: ${response.status} ${JSON.stringify(json)}`);
}
return json;
}

type UpdateMeRequest = Partial<Omit<User, 'id' | 'status'>>;
type UpdateMeResponse = Partial<Omit<User, 'id'>>;

export async function updateMe(user: UpdateMeRequest): Promise<UpdateMeResponse> {
const response = await fetch(`/v1/user`, {
const response = await fitFetch(`/v1/user`, {
method: 'PATCH',
body: JSON.stringify(user),
});
const json = (await response.json()) as Partial<Omit<User, 'id'>>;
const json = (await response.json()) as UpdateMeResponse;

if (!response.ok) {
throw new Error(`Failed to update user: ${response.status} ${JSON.stringify(json)}`);
}
return json;
}

Expand All @@ -28,10 +42,10 @@ interface GetPolicyAgreementsResponse {
}

export async function getPolicyAgreements(): Promise<PolicyAgreement[]> {
const response = await fetch(`/v1/user/policy-agreement`);
const response = await fitFetch(`/v1/user/policy-agreement`);
const json = (await response.json()) as GetPolicyAgreementsResponse;
const policyAgreements = json.policyAgreementList.map((agreement) => ({
policyType: getPolicyType(agreement.policyType),
type: getPolicyType(agreement.policyType),
version: agreement.version,
isAgree: agreement.isAgree,
}));
Expand All @@ -58,13 +72,29 @@ interface UpdatePolicyAgreementsResponse {
export async function updatePolicyAgreements(
agreements: PolicyAgreement[]
): Promise<PolicyAgreement[]> {
const response = await fetch(`/v1/user/policy-agreement`, {
if (agreements.length === 0) {
return [];
}

const response = await fitFetch(`/v1/user/policy-agreement`, {
method: 'PUT',
body: JSON.stringify({ policyAgreementList: agreements } as UpdatePolicyAgreementsRequest),
body: JSON.stringify({
policyAgreementList: agreements.map((agreement) => ({
isAgree: agreement.isAgree,
policyType: agreement.type,
version: agreement.version,
})),
} as UpdatePolicyAgreementsRequest),
});
const json = (await response.json()) as UpdatePolicyAgreementsResponse;

if (!response.ok) {
throw new Error(
`Failed to update policy agreements: ${response.status} ${JSON.stringify(json)}`
);
}
const policyAgreements = json.policyAgreementList.map((agreement) => ({
policyType: getPolicyType(agreement.policyType),
type: getPolicyType(agreement.policyType),
version: agreement.version,
isAgree: agreement.isAgree,
}));
Expand Down
14 changes: 0 additions & 14 deletions src/app/StoreProvider.tsx

This file was deleted.

26 changes: 1 addition & 25 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,27 +1,4 @@
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../../public/fonts/SpoqaHanSansNeo-Regular.woff2');
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../../public/fonts/SpoqaHanSansNeo-Bold.woff2');
font-weight: 700;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../../public/fonts/SpoqaHanSansNeo-Medium.woff2');
font-weight: 500;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../../public/fonts/SpoqaHanSansNeo-Light.woff2');
font-weight: 300;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../../public/fonts/SpoqaHanSansNeo-Thin.woff2');
font-weight: 100;
}
@import url(//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSansNeo.css);

@keyframes pulse {
0%,
Expand Down Expand Up @@ -81,7 +58,6 @@ input {
'Noto Sans KR',
'Malgun Gothic',
sans-serif;
font-size: 20px;
}

html {
Expand Down
Loading

0 comments on commit 0ee8a06

Please sign in to comment.