From 51138940093f31828bd81b2e19cae475d9dbbcc6 Mon Sep 17 00:00:00 2001 From: Seoyeon HEO Date: Thu, 30 Oct 2025 22:03:48 +0900 Subject: [PATCH 1/8] add: automatic distribution file using aws system --- .github/workflows/cd_prac.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/cd_prac.yml diff --git a/.github/workflows/cd_prac.yml b/.github/workflows/cd_prac.yml new file mode 100644 index 0000000..9f28c1e --- /dev/null +++ b/.github/workflows/cd_prac.yml @@ -0,0 +1,34 @@ +name: deploy-client + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20.11.1' + + - name: Build & Export + run: | + yarn install + yarn build + + - name: Deploy to S3 and Invalidate Cloudfront in prod mode + env: + AWS_ACCESS_KEY_ID: AKIAUOI25NIUYLDVT6XX + AWS_SECRET_ACCESS_KEY: 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 + AWS_REGION: ap-northeast-2 + run: | + aws s3 sync ./dist s3://{s3 이름} --delete + aws cloudfront create-invalidation --distribution-id {Cloudfront 이름} --paths "/*"\ From f2844e37e77a823504491ca2d7b4160632455529 Mon Sep 17 00:00:00 2001 From: Seoyeon HEO Date: Thu, 30 Oct 2025 22:05:18 +0900 Subject: [PATCH 2/8] add: automatic distribution file using aws system --- .github/workflows/cd_prac.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd_prac.yml b/.github/workflows/cd_prac.yml index 9f28c1e..8ace293 100644 --- a/.github/workflows/cd_prac.yml +++ b/.github/workflows/cd_prac.yml @@ -26,8 +26,8 @@ jobs: - name: Deploy to S3 and Invalidate Cloudfront in prod mode env: - AWS_ACCESS_KEY_ID: AKIAUOI25NIUYLDVT6XX - AWS_SECRET_ACCESS_KEY: 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 + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: ap-northeast-2 run: | aws s3 sync ./dist s3://{s3 이름} --delete From ace9ac5a8e8a2554c313c94a3d9ed3975d547a2a Mon Sep 17 00:00:00 2001 From: Seoyeon HEO Date: Sat, 1 Nov 2025 15:16:15 +0900 Subject: [PATCH 3/8] add: automatic cd system --- .github/workflows/cd_prac.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/cd_prac.yml diff --git a/.github/workflows/cd_prac.yml b/.github/workflows/cd_prac.yml new file mode 100644 index 0000000..16bbd0d --- /dev/null +++ b/.github/workflows/cd_prac.yml @@ -0,0 +1,34 @@ +name: deploy-client + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20.11.1' + + - name: Build & Export + run: | + yarn install + yarn build + + - name: Deploy to S3 and Invalidate Cloudfront in prod mode + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: ap-northeast-2 + run: | + aws s3 sync ./dist s3://hsy-amzn-bucket-demo --delete + aws cloudfront create-invalidation --distribution-id hsy-cloudfront-demo --paths "/*"\ From 81b514955e11a07fb3428a2e4ea7ef2c289427ed Mon Sep 17 00:00:00 2001 From: Seoyeon HEO Date: Sat, 1 Nov 2025 21:21:21 +0900 Subject: [PATCH 4/8] add filter toggle --- src/Home.module.css | 21 ++++++++++++++ src/components/Home.tsx | 63 ++++++++++++++++++++++++++++++++++++++++- src/style.css | 10 +++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/Home.module.css diff --git a/src/Home.module.css b/src/Home.module.css new file mode 100644 index 0000000..5b52ddc --- /dev/null +++ b/src/Home.module.css @@ -0,0 +1,21 @@ +.accordion { + background-color: #eee; + color: #444; + cursor: pointer; + padding: 18px; + width: 100%; + text-align: left; + border: none; + outline: none; + transition: 0.4s; +} + +.active, .accordion:hover { + background-color: #ccc; +} + +.panel { + padding: 0 18px; + background-color: white; + overflow: hidden; +} \ No newline at end of file diff --git a/src/components/Home.tsx b/src/components/Home.tsx index d181c92..79829b7 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -1,8 +1,69 @@ // import React from "react"; +import { useAuth } from "../contexts/AuthContext" +import { useState } from 'react'; +import styles from "../Home.module.css" const Home = () => { + const [panelExpanded, setPanelExpanded] = useState(false); + + const expandToggle = () => { + setPanelExpanded(p => !p) + } + + return ( -
{/*

스누인턴 홈페이지 입니다

*/}
+
+ + {panelExpanded && ( +
+
+

개발

+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + + +
+
+

기획

+ + +
+
+

디자인

+ + +
+
+

마케팅

+ + +
+
+ )} + + +
+
); }; diff --git a/src/style.css b/src/style.css index 43cddc9..03ba4ef 100644 --- a/src/style.css +++ b/src/style.css @@ -20,6 +20,16 @@ body { min-height: 100vh; } +.col { + display: flex; + flex-direction: column; +} + +.row { + display: flex; + flex-direction: row; +} + main { flex: 1; display: flex; From 37cb3448178539b3a3f6df50c12a88e2853a3384 Mon Sep 17 00:00:00 2001 From: Seoyeon HEO Date: Sun, 2 Nov 2025 13:56:10 +0900 Subject: [PATCH 5/8] feat: filter modals, query state depending on filter, new context for post data --- package-lock.json | 40 +-- package.json | 1 + src/App.tsx | 19 +- src/Home.module.css | 148 ++++++++++- src/components/Home.tsx | 482 +++++++++++++++++++++++++++++++---- src/contexts/PostContext.tsx | 135 ++++++++++ src/style.css | 2 + yarn.lock | 162 ++++++------ 8 files changed, 808 insertions(+), 181 deletions(-) create mode 100644 src/contexts/PostContext.tsx diff --git a/package-lock.json b/package-lock.json index 2e2efbf..7c30293 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,10 @@ "name": "wafflestudio-2025-fe-seminar-template", "version": "0.0.0", "dependencies": { - "@types/react-router-dom": "^5.3.3", "axios": "^1.12.2", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-icons": "^5.5.0", "react-router-dom": "^7.9.4" }, "devDependencies": { @@ -1544,12 +1544,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "license": "MIT" - }, "node_modules/@types/node": { "version": "22.18.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.9.tgz", @@ -1564,6 +1558,7 @@ "version": "19.2.2", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -1579,27 +1574,6 @@ "@types/react": "^19.2.0" } }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz", @@ -1689,6 +1663,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, "license": "MIT" }, "node_modules/delayed-stream": { @@ -2368,6 +2343,15 @@ "react": "^19.2.0" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-router": { "version": "7.9.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.4.tgz", diff --git a/package.json b/package.json index 1294708..d7a7082 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "axios": "^1.12.2", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-icons": "^5.5.0", "react-router-dom": "^7.9.4" }, "devDependencies": { diff --git a/src/App.tsx b/src/App.tsx index 265231e..ec393b5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,18 +4,21 @@ import Login from './components/Login'; import Signup from './components/Signup'; import Topbar from './components/Topbar'; import { AuthProvider } from './contexts/AuthContext'; +import { PostProvider } from './contexts/postContext'; const App = () => ( - -
- - } /> - } /> - } /> - -
+ + +
+ + } /> + } /> + } /> + +
+
); diff --git a/src/Home.module.css b/src/Home.module.css index 5b52ddc..5f96a0a 100644 --- a/src/Home.module.css +++ b/src/Home.module.css @@ -1,15 +1,27 @@ +.main{ + display: flex; + flex-direction: column; + padding: 16px 30px; +} + .accordion { background-color: #eee; color: #444; cursor: pointer; - padding: 18px; + padding: 16px 24px 16px 24px; width: 100%; - text-align: left; + display: flex; + flex-direction: row; border: none; outline: none; transition: 0.4s; + justify-content: space-between; + + font-size: 18px; + font-weight: 700 } + .active, .accordion:hover { background-color: #ccc; } @@ -18,4 +30,134 @@ padding: 0 18px; background-color: white; overflow: hidden; -} \ No newline at end of file +} + +ul.chips { + margin: 30px 0 50px; + list-style: none; + display: flex; + gap: 6px; + flex-wrap: wrap; + padding: 0px 16px 16px 16px; +} + +.chip { + background-color: rgb(255, 255, 255); + display: flex; + align-items: center; + gap: 4px; + margin-right: 6px; + font-size: 12px; + float:left; + border: 1px solid #F1F2F5; + border-radius: 14px; + padding:16px 8px; + font-size: 14px; + } + + .resetChip { + background-color: rgb(255, 255, 255); + display: flex; + align-items: center; + gap: 4px; + margin-right: 6px; + font-size: 12px; + float:left; + padding:16px 8px; + font-size: 14px; + border: none; + } + + /* MODALS */ + .modalTrigger { + position: relative; + } + .modal { + position: absolute; + top: calc(100% + 8px); + left: 0; + background-color: white; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0,0,0,0.1); + padding:16px; + width: 250px; + z-index: 1000; + cursor: default; + } + + .modalOptions { + display: flex; + flex-direction: column; + gap: 12px; + padding-bottom: 16px; + } +.radioLabel { + display: inline-flex; + align-items: center; + gap: 8px; + cursor: pointer; +} +.modalOptions label { + display: inline-flex; + align-items: center; + gap: 8px; + cursor: pointer; +} + +/* If your JSX uses a plain `className="row"`, define that globally in `src/style.css`. + Prefer using `styles.row` (CSS modules) instead; see `Home.tsx` for where .row is used. */ + .modalActions { + display: flex; + justify-content: flex-end; + gap: 8px; + border-top: 1px solid #f0f0f0; + padding-top: 16px; + } +.btn { + border: none; + border-radius: 6px; + padding: 8px 16px; + font-size: 14px; + font-weight: 500; + cursor: pointer; +} +.btnReset { + background-color: #f1f2f5; + color: #555; +} +.btnApply { + background-color: #333; + color: white; +} + +.radioLabel input[type="radio"] { + display: none; +} +.radioVisual { + width: 18px; + height: 18px; + border-radius: 50%; + border: 2px solid #ccc; + display: grid; + place-items: center; + transition: all 0.2s; +} +.radioVisual::before { /* inner dot */ + content: ""; + width: 10px; + height: 10px; + border-radius: 50px; + background-color: #555; + transform: scale(0); + transition: all 0.2s; +} +.radioLabel input[type="radio"]:checked + .radioVisual { + border-color: #555; +} +.radioLabel input[type="radio"]:checked + .radioVisual::before { + transform: scale(1); +} + +/* input[type="checkbox"] { + +} */ \ No newline at end of file diff --git a/src/components/Home.tsx b/src/components/Home.tsx index 79829b7..4a4112b 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -1,69 +1,443 @@ +import { type ChangeEvent, useEffect, useState } from 'react'; +import { FaAngleDown, FaAngleUp, FaArrowRotateRight } from 'react-icons/fa6'; +import styles from '../Home.module.css'; // import React from "react"; -import { useAuth } from "../contexts/AuthContext" -import { useState } from 'react'; -import styles from "../Home.module.css" +// import { useAuth } from '../contexts/AuthContext'; +import { encodeQueryParams, usePosts } from '../contexts/postContext'; const Home = () => { + const DOMAINS: string[] = [ + 'FINTECH', + 'HEALTHTECH', + 'EDUCATION', + 'ECOMMERCE', + 'FOODTECH', + 'MOBILITY', + 'CONTENTS', + 'B2B', + 'OTHERS', + ]; + + const DEV: string[] = ['FRONT', 'APP', 'BACKEND', 'DATA', 'OTHERS']; + + const { fetchPosts } = usePosts(); const [panelExpanded, setPanelExpanded] = useState(false); + const [roles, setRoles] = useState([]); + + const [recExpanded, setRecExpanded] = useState(false); + const [isActive, setIsActive] = useState(false); + // radio selection state (temporary) + const [recStatus, setRecStatus] = useState<'all' | 'recruiting'>( + isActive ? 'recruiting' : 'all' + ); + + const [domains, setDomain] = useState(DOMAINS); + const [dmStatus, setDmStatus] = useState(domains); + const [dmExpanded, setDmExpanded] = useState(false); + + const [order, setOrder] = useState(0); + const [newExpanded, setNewExpanded] = useState(false); + const [orderStatus, setOrderStatus] = useState(0); - const expandToggle = () => { - setPanelExpanded(p => !p) - } + const [query, setQuery] = useState(''); + // make fetch api call + useEffect(() => { + fetchPosts(query); + }, [query, fetchPosts]); + + // when filter settings change, re-calculate query (leads to above useEffect, i.e fetchPosts) + useEffect(() => { + const q: string = encodeQueryParams({ + params: { + roles: `${roles.length === 0 ? null : roles}`, + isActive: `${isActive}`, + domains: `${domains.length === 0 ? null : domains}`, + order: `${order}`, + }, + }); + setQuery(q); + }, [roles, isActive, domains, order]); + // role check + const handleRoleCheck = (e: ChangeEvent) => { + const { checked, value } = e.currentTarget; + if (value === 'total') { + setRoles((p) => [...DEV, ...p.filter((v) => !DEV.includes(v))]); + } else { + setRoles((p) => { + if (checked) return [...p, value]; + return p.filter((v) => v !== value); + }); + } + }; + // domain check + const handleDomainCheck = (e: ChangeEvent) => { + const { checked, value } = e.currentTarget; + if (value === 'all') { + setDmStatus(DOMAINS); + } else { + setDmStatus((p) => { + if (checked) return [...p, value]; + return p.filter((v) => v !== value); + }); + } + }; + + const handleReset = () => { + // reset 모집 상태 selection and other filters + setIsActive(false); + setRoles([]); + setDomain(DOMAINS); + setOrder(0); + }; return ( -
- +
+ {panelExpanded && ( -
-
-

개발

- -
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- - - -
-
-

기획

- - -
-
-

디자인

- - -
-
-

마케팅

- - -
-
+
+
+

개발

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+

기획

+ + +
+ +
+

디자인

+ + +
+
+

마케팅

+ + +
+
)} +
    + {/* 모집 상태 옵션 버튼 */} +
  • { + setRecExpanded((p) => !p); + }} + > + 모집 상태 {recExpanded ? : } + {/* 모집 상태 팝업 */} + {recExpanded && ( +
    e.stopPropagation()} // prevents clicks inside from closing modal + > +
    + + + +
    +
    + + +
    +
    + )} +
  • + + {/* 업종 옵션 버튼 */} +
  • { + setDmExpanded((p) => !p); + }} + > + 업종 {dmExpanded ? : } + {/* 업종 선택 팝업 */} + {dmExpanded && ( +
    e.stopPropagation()}> +
    + + dmStatus.includes(d)) + } + onChange={handleDomainCheck} + /> + + + + + + + + + + + + + + + + + + +
    +
    + + +
    +
    + )} +
  • -
    -
+ {/* 순서 */} +
  • { + setNewExpanded((p) => !p); + }} + > + 최신순 {newExpanded ? : } + {/* 순서 선택 팝업 */} + {newExpanded && ( +
    e.stopPropagation()}> +
    + + +
    +
    + + +
    +
    + )} +
  • +
  • + 초기화 +
  • + +
    ); }; diff --git a/src/contexts/PostContext.tsx b/src/contexts/PostContext.tsx new file mode 100644 index 0000000..67a878e --- /dev/null +++ b/src/contexts/PostContext.tsx @@ -0,0 +1,135 @@ +import { type ReactNode, createContext, useContext, useState } from 'react'; +import apiClient from '../api'; + +interface Post { + companyName: string; + profileImageKey: string; + employmentEndDate: string; + positionTitle: string; + domain: string; + detailSummary: string; + positionType: string; +} + +interface ApiAuthor { + id: string; + name: string; + profileImageKey: string; +} + +interface ApiTag { + tag: string; +} + +interface ApiPost { + id: string; + author: ApiAuthor; + companyName: string; + profileImageKey: string; + location: string; + employmentEndDate: string; // ISO date string + positionTitle: string; + domain: string; + slogan: string; + detailSummary: string; + positionType: string; + headCount: number; + isBookmarked: boolean; + createdAt: string; // This is an ISO date string + updatedAt: string; // This is an ISO date string + tags: ApiTag[]; + coffeeChatCount: number; +} + +interface PostContextType { + posts: Post[] | null; + paginator: number; + isLoading: boolean; + fetchPosts: (query: string) => Promise; +} + +export const encodeQueryParams = ({ + params, +}: { + params: Record< + string, + | string + | number + | boolean + | string[] + | number[] + | boolean[] + | null + | undefined + >; +}) => { + const queryParameters = new URLSearchParams(); + + Object.entries(params).forEach(([key, value]) => { + if (value === undefined || value === null) return; // null, undefined 제외 + + if (Array.isArray(value)) { + value.forEach((v) => { + queryParameters.append(key, v.toString()); + }); + } else { + queryParameters.append(key, value.toString()); + } + }); + + return queryParameters.toString(); +}; + +const PostContext = createContext(undefined); + +interface PostProviderProps { + children: ReactNode; +} + +export const PostProvider = ({ children }: PostProviderProps) => { + const [posts, setPosts] = useState(null); + const [paginator, setPaginator] = useState(0); + const [isLoading, setIsLoading] = useState(false); + + const fetchPosts = async (query: string) => { + setIsLoading(true); + try { + const url = `/api/post?${query}`; + const response = await apiClient.get<{ + posts: ApiPost[]; + paginator: { lastpage: number }; + }>(url); + setPaginator(response.data.paginator.lastpage); + const apiPosts = response.data.posts; + const formattedPosts: Post[] = apiPosts.map((p: ApiPost) => ({ + companyName: p.companyName, + profileImageKey: p.profileImageKey, + employmentEndDate: p.employmentEndDate, + positionTitle: p.positionTitle, + domain: p.domain, + detailSummary: p.detailSummary, + positionType: p.positionType, + })); + setPosts(formattedPosts); + } catch (error) { + console.error('Failed to fetch posts:', error); + setPosts(null); + } finally { + setIsLoading(false); + } + }; + + return ( + + {children} + + ); +}; + +export const usePosts = () => { + const context = useContext(PostContext); + if (context === undefined) { + throw new Error('usePosts must be used within a PostProvider'); + } + return context; +}; diff --git a/src/style.css b/src/style.css index 03ba4ef..1f12d1b 100644 --- a/src/style.css +++ b/src/style.css @@ -28,6 +28,8 @@ body { .row { display: flex; flex-direction: row; + align-items: center; + gap: 8px; } main { diff --git a/yarn.lock b/yarn.lock index 28902c6..f085877 100644 --- a/yarn.lock +++ b/yarn.lock @@ -97,21 +97,21 @@ __metadata: linkType: hard "@emnapi/core@npm:^1.5.0": - version: 1.5.0 - resolution: "@emnapi/core@npm:1.5.0" + version: 1.6.0 + resolution: "@emnapi/core@npm:1.6.0" dependencies: "@emnapi/wasi-threads": "npm:1.1.0" tslib: "npm:^2.4.0" - checksum: 10c0/52ba3485277706d92fa27d92b37e5b4f6ef0742c03ed68f8096f294c6bfa30f0752c82d4c2bfa14bff4dc30d63c9f71a8f9fb64a92743d00807d9e468fafd5ff + checksum: 10c0/40e384f39104a9f8260e671c0110f8618961afc564afb2e626af79175717a8b5e2d8b2ae3d30194d318a71247e0fc833601666233adfeb244c46cadc06c58a51 languageName: node linkType: hard "@emnapi/runtime@npm:^1.5.0": - version: 1.5.0 - resolution: "@emnapi/runtime@npm:1.5.0" + version: 1.6.0 + resolution: "@emnapi/runtime@npm:1.6.0" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/a85c9fc4e3af49cbe41e5437e5be2551392a931910cd0a5b5d3572532786927810c9cc1db11b232ec8f9657b33d4e6f7c4f985f1a052917d7cd703b5b2a20faa + checksum: 10c0/e3d2452a8fb83bb59fe60dfcf4cff99f9680c13c07dff8ad28639ccc8790151841ef626a67014bde132939bad73dfacc440ade8c3db2ab12693ea9c8ba4d37fb languageName: node linkType: hard @@ -692,92 +692,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-darwin-arm64@npm:1.13.20" +"@swc/core-darwin-arm64@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-darwin-arm64@npm:1.13.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-darwin-x64@npm:1.13.20" +"@swc/core-darwin-x64@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-darwin-x64@npm:1.13.5" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.13.20" +"@swc/core-linux-arm-gnueabihf@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.13.5" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-linux-arm64-gnu@npm:1.13.20" +"@swc/core-linux-arm64-gnu@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-linux-arm64-gnu@npm:1.13.5" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-linux-arm64-musl@npm:1.13.20" +"@swc/core-linux-arm64-musl@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-linux-arm64-musl@npm:1.13.5" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-linux-x64-gnu@npm:1.13.20" +"@swc/core-linux-x64-gnu@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-linux-x64-gnu@npm:1.13.5" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-linux-x64-musl@npm:1.13.20" +"@swc/core-linux-x64-musl@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-linux-x64-musl@npm:1.13.5" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-win32-arm64-msvc@npm:1.13.20" +"@swc/core-win32-arm64-msvc@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-win32-arm64-msvc@npm:1.13.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-win32-ia32-msvc@npm:1.13.20" +"@swc/core-win32-ia32-msvc@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-win32-ia32-msvc@npm:1.13.5" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.13.20": - version: 1.13.20 - resolution: "@swc/core-win32-x64-msvc@npm:1.13.20" +"@swc/core-win32-x64-msvc@npm:1.13.5": + version: 1.13.5 + resolution: "@swc/core-win32-x64-msvc@npm:1.13.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.12.11": - version: 1.13.20 - resolution: "@swc/core@npm:1.13.20" - dependencies: - "@swc/core-darwin-arm64": "npm:1.13.20" - "@swc/core-darwin-x64": "npm:1.13.20" - "@swc/core-linux-arm-gnueabihf": "npm:1.13.20" - "@swc/core-linux-arm64-gnu": "npm:1.13.20" - "@swc/core-linux-arm64-musl": "npm:1.13.20" - "@swc/core-linux-x64-gnu": "npm:1.13.20" - "@swc/core-linux-x64-musl": "npm:1.13.20" - "@swc/core-win32-arm64-msvc": "npm:1.13.20" - "@swc/core-win32-ia32-msvc": "npm:1.13.20" - "@swc/core-win32-x64-msvc": "npm:1.13.20" + version: 1.13.5 + resolution: "@swc/core@npm:1.13.5" + dependencies: + "@swc/core-darwin-arm64": "npm:1.13.5" + "@swc/core-darwin-x64": "npm:1.13.5" + "@swc/core-linux-arm-gnueabihf": "npm:1.13.5" + "@swc/core-linux-arm64-gnu": "npm:1.13.5" + "@swc/core-linux-arm64-musl": "npm:1.13.5" + "@swc/core-linux-x64-gnu": "npm:1.13.5" + "@swc/core-linux-x64-musl": "npm:1.13.5" + "@swc/core-win32-arm64-msvc": "npm:1.13.5" + "@swc/core-win32-ia32-msvc": "npm:1.13.5" + "@swc/core-win32-x64-msvc": "npm:1.13.5" "@swc/counter": "npm:^0.1.3" - "@swc/types": "npm:^0.1.25" + "@swc/types": "npm:^0.1.24" peerDependencies: "@swc/helpers": ">=0.5.17" dependenciesMeta: @@ -804,7 +804,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 10c0/ef9ed965f20fe8331ef6b279b30ae2421ec9cd4105cfc0ac4645ae716844dfa9998162b132abbd6e8ccfb91deb263861792cf815fdcdcb7a011384e3505e0532 + checksum: 10c0/26efc58d2b154050a4d75b215007e2780fc02ccdd35168746e818ef58009201878d5fbe0e074ed2902858c447fd8806e52c03dd05c20ba8501573f57ef34c3be languageName: node linkType: hard @@ -815,7 +815,7 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.25": +"@swc/types@npm:^0.1.24": version: 0.1.25 resolution: "@swc/types@npm:0.1.25" dependencies: @@ -841,11 +841,11 @@ __metadata: linkType: hard "@types/node@npm:^22.15.29": - version: 22.18.10 - resolution: "@types/node@npm:22.18.10" + version: 22.18.9 + resolution: "@types/node@npm:22.18.9" dependencies: undici-types: "npm:~6.21.0" - checksum: 10c0/37b34553f1953ab8fc25b7467d44701446400f62547adb62c842cebac091350985470aeed87acd60f5295778c370d9721d477310e643677a7eab03a8dc6ed74f + checksum: 10c0/0d342e17e0b36a4475ba36f0a0b9d7e28cf85ae44b1ea1f218c8cffe8c9519820eef9b97c171b0b93d8066c8710d7660e31660678bac0842655dff2118a23248 languageName: node linkType: hard @@ -930,20 +930,6 @@ __metadata: languageName: node linkType: hard -"async-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-function@npm:1.0.0" - checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73 - languageName: node - linkType: hard - -"async-generator-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-generator-function@npm:1.0.0" - checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186 - languageName: node - linkType: hard - "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -1410,31 +1396,21 @@ __metadata: languageName: node linkType: hard -"generator-function@npm:^2.0.0": - version: 2.0.1 - resolution: "generator-function@npm:2.0.1" - checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8 - languageName: node - linkType: hard - "get-intrinsic@npm:^1.2.6": - version: 1.3.1 - resolution: "get-intrinsic@npm:1.3.1" + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" dependencies: - async-function: "npm:^1.0.0" - async-generator-function: "npm:^1.0.0" call-bind-apply-helpers: "npm:^1.0.2" es-define-property: "npm:^1.0.1" es-errors: "npm:^1.3.0" es-object-atoms: "npm:^1.1.1" function-bind: "npm:^1.1.2" - generator-function: "npm:^2.0.0" get-proto: "npm:^1.0.1" gopd: "npm:^1.2.0" has-symbols: "npm:^1.1.0" hasown: "npm:^2.0.2" math-intrinsics: "npm:^1.1.0" - checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d + checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a languageName: node linkType: hard @@ -1847,8 +1823,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 11.4.2 - resolution: "node-gyp@npm:11.4.2" + version: 11.5.0 + resolution: "node-gyp@npm:11.5.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -1862,7 +1838,7 @@ __metadata: which: "npm:^5.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/0bfd3e96770ed70f07798d881dd37b4267708966d868a0e585986baac487d9cf5831285579fd629a83dc4e434f53e6416ce301097f2ee464cb74d377e4d8bdbe + checksum: 10c0/31ff49586991b38287bb15c3d529dd689cfc32f992eed9e6997b9d712d5d21fe818a8b1bbfe3b76a7e33765c20210c5713212f4aa329306a615b87d8a786da3a languageName: node linkType: hard @@ -2048,6 +2024,15 @@ __metadata: languageName: node linkType: hard +"react-icons@npm:^5.5.0": + version: 5.5.0 + resolution: "react-icons@npm:5.5.0" + peerDependencies: + react: "*" + checksum: 10c0/a24309bfc993c19cbcbfc928157e53a137851822779977b9588f6dd41ffc4d11ebc98b447f4039b0d309a858f0a42980f6bfb4477fb19f9f2d1bc2e190fcf79c + languageName: node + linkType: hard + "react-router-dom@npm:^7.9.4": version: 7.9.4 resolution: "react-router-dom@npm:7.9.4" @@ -2339,15 +2324,15 @@ __metadata: linkType: hard "tar@npm:^7.4.3": - version: 7.5.1 - resolution: "tar@npm:7.5.1" + version: 7.5.2 + resolution: "tar@npm:7.5.2" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10c0/0dad0596a61586180981133b20c32cfd93c5863c5b7140d646714e6ea8ec84583b879e5dc3928a4d683be6e6109ad7ea3de1cf71986d5194f81b3a016c8858c9 + checksum: 10c0/a7d8b801139b52f93a7e34830db0de54c5aa45487c7cb551f6f3d44a112c67f1cb8ffdae856b05fd4f17b1749911f1c26f1e3a23bbe0279e17fd96077f13f467 languageName: node linkType: hard @@ -2490,6 +2475,7 @@ __metadata: knip: "npm:^5.59.1" react: "npm:^19.1.0" react-dom: "npm:^19.1.0" + react-icons: "npm:^5.5.0" react-router-dom: "npm:^7.9.4" typescript: "npm:~5.8.3" vite: "npm:^6.3.5" From 5b83a41314508fe222c8b54843fc7202147916b3 Mon Sep 17 00:00:00 2001 From: Seoyeon HEO Date: Sun, 2 Nov 2025 15:14:14 +0900 Subject: [PATCH 6/8] fix: api call --- src/components/Home.tsx | 283 +++++++++++++++++++---------------- src/contexts/PostContext.tsx | 27 +++- 2 files changed, 175 insertions(+), 135 deletions(-) diff --git a/src/components/Home.tsx b/src/components/Home.tsx index 4a4112b..71d854c 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -1,7 +1,6 @@ import { type ChangeEvent, useEffect, useState } from 'react'; import { FaAngleDown, FaAngleUp, FaArrowRotateRight } from 'react-icons/fa6'; import styles from '../Home.module.css'; -// import React from "react"; // import { useAuth } from '../contexts/AuthContext'; import { encodeQueryParams, usePosts } from '../contexts/postContext'; @@ -50,10 +49,10 @@ const Home = () => { useEffect(() => { const q: string = encodeQueryParams({ params: { - roles: `${roles.length === 0 ? null : roles}`, - isActive: `${isActive}`, - domains: `${domains.length === 0 ? null : domains}`, - order: `${order}`, + roles: roles.length === 0 ? null : roles, + isActive: isActive, + domains: domains.length === DOMAINS.length ? null : domains, + order: order, }, }); setQuery(q); @@ -89,6 +88,10 @@ const Home = () => { setRoles([]); setDomain(DOMAINS); setOrder(0); + + setRecStatus('all'); + setDmStatus(DOMAINS); + setOrderStatus(0); }; return ( @@ -111,6 +114,7 @@ const Home = () => {

    개발

    + { value="total" onChange={handleRoleCheck} > -
    + { value="FRONT" onChange={handleRoleCheck} > -
    + { value="BACKEND" onChange={handleRoleCheck} > -
    + { value="APP" onChange={handleRoleCheck} > -
    + { value="OTHERS" onChange={handleRoleCheck} > -

    기획

    - - +
    + + +

    디자인

    - - +
    + + +

    마케팅

    - - +
    + + +
    )} @@ -269,99 +278,119 @@ const Home = () => { {dmExpanded && (
    e.stopPropagation()}>
    - - dmStatus.includes(d)) - } - onChange={handleDomainCheck} - /> - - - - - - - - - - - - - - - - - - +
    + + dmStatus.includes(d)) + } + onChange={handleDomainCheck} + /> +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +