From 23c316cb68883c577765ce6d5487dd76a3ce076f Mon Sep 17 00:00:00 2001 From: LiuPei Date: Tue, 19 Aug 2025 15:32:18 +0900 Subject: [PATCH] =?UTF-8?q?[Feat]=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=EB=B0=8F=20=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=81=AC=EB=A1=A4=EB=B0=94=20x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 2 +- .prettierrc | 10 +- .vscode/settings.json | 3 +- app/company/(overview)/page.tsx | 8 +- app/company/[id]/not-found.tsx | 9 +- app/company/[id]/suggestion/not-found.tsx | 9 +- app/globals.css | 29 +- app/layout.tsx | 16 +- app/lib/context/GoogleAnalytics.tsx | 30 +- app/lib/hooks/use-mobile.tsx | 26 +- app/lib/types/models/index.ts | 1 - app/login/fail/page.tsx | 44 +- app/login/layout.tsx | 13 +- app/login/page.tsx | 56 +- app/ui/common/PrelineScript.tsx | 34 +- app/ui/common/ScrollbarHandler.tsx | 67 + app/ui/common/baseButton.tsx | 50 +- app/ui/common/baseSubmitButton.tsx | 42 +- app/ui/common/basicAlert.tsx | 40 +- app/ui/common/basicConfirm.tsx | 53 +- app/ui/common/comboBox.tsx | 2 +- app/ui/common/container.tsx | 9 +- app/ui/common/feedBackModal.tsx | 12 +- app/ui/common/fieldBox.tsx | 16 +- app/ui/common/input.tsx | 45 +- app/ui/common/nextbutton.tsx | 48 +- app/ui/common/prevButton.tsx | 29 +- app/ui/common/row.tsx | 20 +- app/ui/common/search.tsx | 70 +- app/ui/common/searchComboBox.tsx | 27 +- app/ui/common/select.tsx | 44 +- app/ui/common/skeletons.tsx | 220 +- app/ui/common/submitButton.tsx | 59 +- app/ui/common/xsContainer.tsx | 16 +- app/ui/company/CompanyMenu.tsx | 2 +- app/ui/company/CompanyOverviewCard.tsx | 4 +- app/ui/company/TierDistributionChart.tsx | 92 +- app/ui/company/positionSelectBox.tsx | 13 +- app/ui/company/suggestionBtn.tsx | 8 +- app/ui/company/trLink.tsx | 6 +- app/ui/company/verifyMark.tsx | 18 +- app/ui/global.css | 236 +- app/ui/interaction/snow.tsx | 315 +- app/ui/main/FullPageScroll.tsx | 4 +- app/ui/main/Home.tsx | 22 +- app/ui/navigation/InteractiveLink.tsx | 2 +- app/ui/navigation/navBtn.tsx | 12 +- app/ui/navigation/navSearchInput.tsx | 70 +- app/ui/profile/fieldTogglebutton.tsx | 18 +- app/ui/shadcn/components/ui/hover-card.tsx | 44 +- app/ui/shadcn/lib/utils.ts | 6 +- app/ui/testReview/trFormRow.tsx | 62 +- components.json | 40 +- package.json | 123 +- pnpm-lock.yaml | 3516 +++++++++++++++----- postcss.config.mjs | 6 +- tailwind.config.ts | 5 +- tsconfig.json | 63 +- 58 files changed, 3892 insertions(+), 1954 deletions(-) create mode 100644 app/ui/common/ScrollbarHandler.tsx diff --git a/.eslintrc.json b/.eslintrc.json index bffb357..72cc705 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": "next/core-web-vitals" } diff --git a/.prettierrc b/.prettierrc index 93fc268..20eaeaf 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,11 +1,9 @@ { - "useTabs": true, + "useTabs": true, "singleQuote": true, "trailingComma": "none", "printWidth": 100, - "plugins": [ - "prettier-plugin-tailwindcss" - ], - "tailwindConfig": "./tailwind.config.ts", - "tailwindFunctions": ["clsx"] + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindConfig": "./tailwind.config.ts", + "tailwindFunctions": ["clsx"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a73a41..0967ef4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,2 +1 @@ -{ -} \ No newline at end of file +{} diff --git a/app/company/(overview)/page.tsx b/app/company/(overview)/page.tsx index a7876e1..b5f1c37 100644 --- a/app/company/(overview)/page.tsx +++ b/app/company/(overview)/page.tsx @@ -1,11 +1,11 @@ -import { CompanyOverviewCard } from '@/app/ui/company/CompanyOverviewCard'; import { BsThreeDots } from 'react-icons/bs'; -import { PaginationButtons } from '@/app/ui/paging/Pagination'; +import { CompanyOverviewCard } from '@/app/ui/company/CompanyOverviewCard'; +import Container from '@/app/ui/common/container'; +import FeedBackBtn from '@/app/ui/common/feedBackBtn'; import { Metadata } from 'next'; +import { PaginationButtons } from '@/app/ui/paging/Pagination'; import ScrollToTop from '@/app/ui/common/ScrollToTop'; -import Container from '@/app/ui/common/container'; import { fetchCompanyData } from '../../lib/server/queries/company'; -import FeedBackBtn from '@/app/ui/common/feedBackBtn'; const PAGE_SIZE = 10; diff --git a/app/company/[id]/not-found.tsx b/app/company/[id]/not-found.tsx index ddcc73e..0bcbafc 100644 --- a/app/company/[id]/not-found.tsx +++ b/app/company/[id]/not-found.tsx @@ -1,8 +1,5 @@ -import NotFound from "@/app/not-found"; +import NotFound from '@/app/not-found'; export default function Page() { - return ( - - ); - } - \ No newline at end of file + return ; +} diff --git a/app/company/[id]/suggestion/not-found.tsx b/app/company/[id]/suggestion/not-found.tsx index ac5ad45..0bcbafc 100644 --- a/app/company/[id]/suggestion/not-found.tsx +++ b/app/company/[id]/suggestion/not-found.tsx @@ -1,8 +1,5 @@ -import NotFound from "@/app/not-found"; +import NotFound from '@/app/not-found'; export default function Page() { - return ( - - ); - } - \ No newline at end of file + return ; +} diff --git a/app/globals.css b/app/globals.css index 8a21404..f75e1a3 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,30 +1,31 @@ -html, body { - height: 100%; - margin: 0; - padding: 0; - overflow: hidden; +html, +body { + height: 100%; + margin: 0; + padding: 0; + overflow-y: auto; } #__next { - height: 100%; + height: 100%; } .full-height-container { - height: 100%; + height: 100%; } .full-page-container { - height: 100%; - overflow-y: auto; - scroll-snap-type: y mandatory; + height: 100%; + overflow-y: auto; + scroll-snap-type: y mandatory; } .full-page-section { - height: 100%; - scroll-snap-align: start; - scroll-snap-stop: always; + height: 100%; + scroll-snap-align: start; + scroll-snap-stop: always; } html { - scroll-behavior: smooth; + scroll-behavior: smooth; } diff --git a/app/layout.tsx b/app/layout.tsx index 3029684..d1d94c3 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,14 +1,17 @@ -import type { Metadata } from 'next'; -import localFont from 'next/font/local'; import './ui/global.css'; -import Topnav from './ui/navigation/topNav'; + +import { GoogleAnalytics, GoogleTagManager } from '@next/third-parties/google'; + +import AdminPageLayout from '@/app/admin/components/admin-page-layout'; +import Footer from './ui/common/Footer'; import LastPathSetter from './ui/common/lastPathSetter'; +import type { Metadata } from 'next'; import PrelineScript from './ui/common/PrelineScript'; -import { GoogleAnalytics, GoogleTagManager } from '@next/third-parties/google'; import Script from 'next/script'; -import Footer from './ui/common/Footer'; +import ScrollbarHandler from './ui/common/ScrollbarHandler'; +import Topnav from './ui/navigation/topNav'; import { headers } from 'next/headers'; -import AdminPageLayout from '@/app/admin/components/admin-page-layout'; +import localFont from 'next/font/local'; const pretendard = localFont({ src: '../public/fonts/PretendardVariable.woff2', @@ -35,6 +38,7 @@ export default function RootLayout({ /> + diff --git a/app/lib/context/GoogleAnalytics.tsx b/app/lib/context/GoogleAnalytics.tsx index 2367b7b..3c21fcb 100644 --- a/app/lib/context/GoogleAnalytics.tsx +++ b/app/lib/context/GoogleAnalytics.tsx @@ -1,20 +1,20 @@ -import Script from "next/script"; +import Script from 'next/script'; -export default function GoogleAnalytics(){ -return( - <> - - + -) -} \ No newline at end of file + ` + }} + > + + ); +} diff --git a/app/lib/hooks/use-mobile.tsx b/app/lib/hooks/use-mobile.tsx index 2b0fe1d..bcebea3 100644 --- a/app/lib/hooks/use-mobile.tsx +++ b/app/lib/hooks/use-mobile.tsx @@ -1,19 +1,19 @@ -import * as React from "react" +import * as React from 'react'; -const MOBILE_BREAKPOINT = 768 +const MOBILE_BREAKPOINT = 768; export function useIsMobile() { - const [isMobile, setIsMobile] = React.useState(undefined) + const [isMobile, setIsMobile] = React.useState(undefined); - React.useEffect(() => { - const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) - const onChange = () => { - setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) - } - mql.addEventListener("change", onChange) - setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) - return () => mql.removeEventListener("change", onChange) - }, []) + React.useEffect(() => { + const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); + const onChange = () => { + setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); + }; + mql.addEventListener('change', onChange); + setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); + return () => mql.removeEventListener('change', onChange); + }, []); - return !!isMobile + return !!isMobile; } diff --git a/app/lib/types/models/index.ts b/app/lib/types/models/index.ts index c50ce6f..a1c3a9b 100644 --- a/app/lib/types/models/index.ts +++ b/app/lib/types/models/index.ts @@ -2,4 +2,3 @@ export * from './user'; export * from './admin'; export * from './company'; export * from './datalab'; - diff --git a/app/login/fail/page.tsx b/app/login/fail/page.tsx index 98ec7a1..cb20b94 100644 --- a/app/login/fail/page.tsx +++ b/app/login/fail/page.tsx @@ -1,27 +1,23 @@ -import Image from "next/image"; -import Link from "next/link"; +import Image from 'next/image'; +import Link from 'next/link'; export default function Page({ - searchParams - }: { - searchParams: {accessToken?:string,message?:string}; - }) { - const res = searchParams.message ; - return ( -
-
-

-

-
- -
-
-
- {res} -
-
-
-
- ); -}; + searchParams +}: { + searchParams: { accessToken?: string; message?: string }; +}) { + const res = searchParams.message; + return ( +
+
+

+
+
+
+
{res}
+
+
+
+ ); +} diff --git a/app/login/layout.tsx b/app/login/layout.tsx index 3010282..acb95be 100644 --- a/app/login/layout.tsx +++ b/app/login/layout.tsx @@ -1,12 +1,3 @@ - -export default function Layout({ - children, -}: { - children: React.ReactNode -}) { - return ( -
- {children} -
- ) +export default function Layout({ children }: { children: React.ReactNode }) { + return
{children}
; } diff --git a/app/login/page.tsx b/app/login/page.tsx index 69f7a8e..691fd9f 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -11,38 +11,38 @@ export default function Page() { return (
-
-
-
- Sols -
-
-
- -
-
- - - -
카카오 계정으로 계속하기
+
+
+
+ Sols +
+
+
+ +
+
+ + + +
카카오 계정으로 계속하기
+
-
- + +
-
); } diff --git a/app/ui/common/PrelineScript.tsx b/app/ui/common/PrelineScript.tsx index dc9cc4e..65f11eb 100644 --- a/app/ui/common/PrelineScript.tsx +++ b/app/ui/common/PrelineScript.tsx @@ -1,27 +1,27 @@ -"use client"; +'use client'; -import { usePathname } from "next/navigation"; -import { useEffect } from "react"; +import { usePathname } from 'next/navigation'; +import { useEffect } from 'react'; -import { IStaticMethods } from "preline/preline"; +import { IStaticMethods } from 'preline/preline'; declare global { - interface Window { - HSStaticMethods: IStaticMethods; - } + interface Window { + HSStaticMethods: IStaticMethods; + } } export default function PrelineScript() { - const path = usePathname(); + const path = usePathname(); - useEffect(() => { - const loadPreline = async () => { - await import("preline/preline"); + useEffect(() => { + const loadPreline = async () => { + await import('preline/preline'); - window.HSStaticMethods.autoInit(); - }; + window.HSStaticMethods.autoInit(); + }; - loadPreline(); - }, [path]); + loadPreline(); + }, [path]); - return null; -} \ No newline at end of file + return null; +} diff --git a/app/ui/common/ScrollbarHandler.tsx b/app/ui/common/ScrollbarHandler.tsx new file mode 100644 index 0000000..5cc78f4 --- /dev/null +++ b/app/ui/common/ScrollbarHandler.tsx @@ -0,0 +1,67 @@ +'use client'; + +import { useEffect } from 'react'; + +export default function ScrollbarHandler() { + useEffect(() => { + let scrollTimer: NodeJS.Timeout; + + const handleScroll = () => { + console.log('스크롤 감지!'); // 디버깅용 + + // 스크롤 중일 때 클래스 추가 + document.body.classList.add('scrolling'); + + // 기존 타이머 클리어 + clearTimeout(scrollTimer); + + // 스크롤이 멈춘 후 1초 뒤에 스크롤바 색상 원래대로 + scrollTimer = setTimeout(() => { + console.log('스크롤 멈춤, 클래스 제거'); // 디버깅용 + document.body.classList.remove('scrolling'); + }, 1000); + }; + + // 여러 요소에 스크롤 이벤트 리스너 추가 + window.addEventListener('scroll', handleScroll, { passive: true }); + document.addEventListener('scroll', handleScroll, { passive: true }); + + // 모든 스크롤 가능한 요소에 이벤트 추가 + const scrollableElements = document.querySelectorAll('*'); + const scrollListeners: Array<{ element: Element; handler: EventListener }> = []; + + scrollableElements.forEach((element) => { + if ( + element.scrollHeight > element.clientHeight || + element.scrollWidth > element.clientWidth + ) { + const elementHandler = () => { + console.log('요소 스크롤 감지:', element); // 디버깅용 + element.classList.add('scrolling'); + + clearTimeout(scrollTimer); + scrollTimer = setTimeout(() => { + element.classList.remove('scrolling'); + }, 1000); + }; + + element.addEventListener('scroll', elementHandler, { passive: true }); + scrollListeners.push({ element, handler: elementHandler }); + } + }); + + return () => { + window.removeEventListener('scroll', handleScroll); + document.removeEventListener('scroll', handleScroll); + + // 개별 요소 리스너 제거 + scrollListeners.forEach(({ element, handler }) => { + element.removeEventListener('scroll', handler); + }); + + clearTimeout(scrollTimer); + }; + }, []); + + return null; +} diff --git a/app/ui/common/baseButton.tsx b/app/ui/common/baseButton.tsx index 9f64dc3..0d35cf0 100644 --- a/app/ui/common/baseButton.tsx +++ b/app/ui/common/baseButton.tsx @@ -1,31 +1,31 @@ -'use client' -import clsx from "clsx"; +'use client'; +import clsx from 'clsx'; export default function BaseButton({ - text, - active, - onClick, + text, + active, + onClick }: { - text?: string; - active?: boolean; - onClick: () => void; + text?: string; + active?: boolean; + onClick: () => void; }) { - const btnText = text || "확인"; - const isActive = active ?? true; - const activeOnClick = isActive ? onClick : undefined; + const btnText = text || '확인'; + const isActive = active ?? true; + const activeOnClick = isActive ? onClick : undefined; - return ( - - ); + return ( + + ); } diff --git a/app/ui/common/baseSubmitButton.tsx b/app/ui/common/baseSubmitButton.tsx index e4f2bc7..00aebaf 100644 --- a/app/ui/common/baseSubmitButton.tsx +++ b/app/ui/common/baseSubmitButton.tsx @@ -1,27 +1,21 @@ -"use client"; -import clsx from "clsx"; +'use client'; +import clsx from 'clsx'; -export default function BaseSubmitButton({ - text, - active, -}: { - text?: string; - active?: boolean; -}) { - const btnText = text || "확인"; - const isActive = active ?? true; +export default function BaseSubmitButton({ text, active }: { text?: string; active?: boolean }) { + const btnText = text || '확인'; + const isActive = active ?? true; - return ( - - ); + return ( + + ); } diff --git a/app/ui/common/basicAlert.tsx b/app/ui/common/basicAlert.tsx index 69f83ca..87dfbd4 100644 --- a/app/ui/common/basicAlert.tsx +++ b/app/ui/common/basicAlert.tsx @@ -1,24 +1,24 @@ - export default function BasicAlert({ - children, - onClick, - type='button' + children, + onClick, + type = 'button' }: { - children: React.ReactNode; - onClick: () => void; - type?:'button' | 'submit' | 'reset'; + children: React.ReactNode; + onClick: () => void; + type?: 'button' | 'submit' | 'reset'; }) { - return ( -
-
-
- {children} -
- -
-
- - ); + return ( +
+
+
{children}
+ +
+
+ ); } diff --git a/app/ui/common/basicConfirm.tsx b/app/ui/common/basicConfirm.tsx index d1497cc..e3870dc 100644 --- a/app/ui/common/basicConfirm.tsx +++ b/app/ui/common/basicConfirm.tsx @@ -1,28 +1,33 @@ export default function BasicConfirm({ - children, - onConfirm, - onCancel + children, + onConfirm, + onCancel }: { - children: React.ReactNode; - onConfirm?:()=>void; - onCancel?:()=>void; + children: React.ReactNode; + onConfirm?: () => void; + onCancel?: () => void; }) { - return ( -
-
-
- {children} -
-
- - -
-
-
- - ); + return ( +
+
+
{children}
+
+ + +
+
+
+ ); } diff --git a/app/ui/common/comboBox.tsx b/app/ui/common/comboBox.tsx index 6bdc874..dedc9f0 100644 --- a/app/ui/common/comboBox.tsx +++ b/app/ui/common/comboBox.tsx @@ -31,7 +31,7 @@ const ComboBox = ({ aria-expanded={true} data-hs-combo-box-toggle="" > -
diff --git a/app/ui/common/fieldBox.tsx b/app/ui/common/fieldBox.tsx index bde28c3..0a3e330 100644 --- a/app/ui/common/fieldBox.tsx +++ b/app/ui/common/fieldBox.tsx @@ -1,11 +1,7 @@ - - -export default function FieldBox({feild}:{feild:string}) { - return ( -
-
{feild}
-
- ); +export default function FieldBox({ feild }: { feild: string }) { + return ( +
+
{feild}
+
+ ); } diff --git a/app/ui/common/input.tsx b/app/ui/common/input.tsx index fa96e12..10370fa 100644 --- a/app/ui/common/input.tsx +++ b/app/ui/common/input.tsx @@ -1,18 +1,31 @@ -import Image from "next/image"; +import Image from 'next/image'; -export default function Input({ defaultValue,required,type,placeHolder,id,name }: { defaultValue?: string,required?:boolean,type?:string,placeHolder?:string;id?:string;name?:string}) { - - return ( -
- -
- ); +export default function Input({ + defaultValue, + required, + type, + placeHolder, + id, + name +}: { + defaultValue?: string; + required?: boolean; + type?: string; + placeHolder?: string; + id?: string; + name?: string; +}) { + return ( +
+ +
+ ); } diff --git a/app/ui/common/nextbutton.tsx b/app/ui/common/nextbutton.tsx index ba5f0ed..e9c5ca8 100644 --- a/app/ui/common/nextbutton.tsx +++ b/app/ui/common/nextbutton.tsx @@ -1,30 +1,30 @@ -import clsx from "clsx"; +import clsx from 'clsx'; export default function NextButton({ - text, - active, - onClick, + text, + active, + onClick }: { - text?: string; - active?: boolean; - onClick: () => void; + text?: string; + active?: boolean; + onClick: () => void; }) { - const btnText = text || "다음"; - const isActive = active ?? true; - const activeOnClick = isActive ? onClick : undefined; + const btnText = text || '다음'; + const isActive = active ?? true; + const activeOnClick = isActive ? onClick : undefined; - return ( - - ); + return ( + + ); } diff --git a/app/ui/common/prevButton.tsx b/app/ui/common/prevButton.tsx index 7a16468..6f10e47 100644 --- a/app/ui/common/prevButton.tsx +++ b/app/ui/common/prevButton.tsx @@ -1,20 +1,13 @@ +export default function PrevButton({ text, onClick }: { text?: string; onClick: () => void }) { + const btnText = text ?? '이전'; -export default function PrevButton({ - text, - onClick, -}: { - text?: string; - onClick: () => void; -}) { - const btnText = text ?? "이전"; - - return ( - - ); + return ( + + ); } diff --git a/app/ui/common/row.tsx b/app/ui/common/row.tsx index 59e5b21..ad43fbc 100644 --- a/app/ui/common/row.tsx +++ b/app/ui/common/row.tsx @@ -1,12 +1,8 @@ -export default async function Row({head,desc}:{head:string,desc:string}) { - return ( -
-
- {head} -
-
- {desc} -
-
- ) -} \ No newline at end of file +export default async function Row({ head, desc }: { head: string; desc: string }) { + return ( +
+
{head}
+
{desc}
+
+ ); +} diff --git a/app/ui/common/search.tsx b/app/ui/common/search.tsx index 91f11eb..5ec95df 100644 --- a/app/ui/common/search.tsx +++ b/app/ui/common/search.tsx @@ -1,39 +1,39 @@ -"use client"; -import Image from "next/image"; -import { useSearchParams, usePathname, useRouter } from "next/navigation"; -import { useDebouncedCallback } from "use-debounce"; +'use client'; +import Image from 'next/image'; +import { useSearchParams, usePathname, useRouter } from 'next/navigation'; +import { useDebouncedCallback } from 'use-debounce'; export default function Search({ placeholder }: { placeholder: string }) { - const searchParams = useSearchParams(); - const pathname = usePathname(); - const { replace } = useRouter(); - const handleSearch = useDebouncedCallback((term) => { - const params = new URLSearchParams(searchParams); - if (term) { - params.set("query", term); - } else { - params.delete("query"); - } - replace(`${pathname}?${params.toString()}`); - }, 200); + const searchParams = useSearchParams(); + const pathname = usePathname(); + const { replace } = useRouter(); + const handleSearch = useDebouncedCallback((term) => { + const params = new URLSearchParams(searchParams); + if (term) { + params.set('query', term); + } else { + params.delete('query'); + } + replace(`${pathname}?${params.toString()}`); + }, 200); - return ( -
-
- search -
- { - handleSearch(e.target.value); - }} - defaultValue={searchParams.get("query")?.toString()} - /> -
- ); + return ( +
+
+ search +
+ { + handleSearch(e.target.value); + }} + defaultValue={searchParams.get('query')?.toString()} + /> +
+ ); } diff --git a/app/ui/common/searchComboBox.tsx b/app/ui/common/searchComboBox.tsx index 751258f..ba4ae36 100644 --- a/app/ui/common/searchComboBox.tsx +++ b/app/ui/common/searchComboBox.tsx @@ -1,19 +1,18 @@ -"use client"; +'use client'; -import React, { useState } from "react"; -import SearchDropDown from "./searchDropdown"; -import Search from "./search"; +import React, { useState } from 'react'; +import SearchDropDown from './searchDropdown'; +import Search from './search'; -const SearchComboBox = ({query}:{query:string;}) => { - - return ( -
- -
- -
-
- ); +const SearchComboBox = ({ query }: { query: string }) => { + return ( +
+ +
+ +
+
+ ); }; export default SearchComboBox; diff --git a/app/ui/common/select.tsx b/app/ui/common/select.tsx index fb638b3..28aca8f 100644 --- a/app/ui/common/select.tsx +++ b/app/ui/common/select.tsx @@ -1,27 +1,27 @@ -import Image from "next/image"; +import Image from 'next/image'; export default function Select({ - id, - name, - required, - children, + id, + name, + required, + children }: { - id?: string; - name?: string; - required?:boolean - children: React.ReactNode; + id?: string; + name?: string; + required?: boolean; + children: React.ReactNode; }) { - const isRequired = required || false; - return ( -
- -
- ); + const isRequired = required || false; + return ( +
+ +
+ ); } diff --git a/app/ui/common/skeletons.tsx b/app/ui/common/skeletons.tsx index 97ba5de..ef042d5 100644 --- a/app/ui/common/skeletons.tsx +++ b/app/ui/common/skeletons.tsx @@ -1,130 +1,90 @@ -export function InfoTableSkeleton(){ - return ( -
-
-

- -

-

- -

-
-
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
-
    -
  • -
    - -
    - - - - -
    -
    -
    - - - -
    -
  • -
  • -
    - -
    - - - - -
    -
    -
    - - - -
    -
  • -
-
-
-
-
-
- ); -} \ No newline at end of file +export function InfoTableSkeleton() { + return ( +
+
+

+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
    + +
    + + +
    +
    +
    + +
    +
  • +
  • +
    + +
    + + +
    +
    +
    + +
    +
  • +
+
+
+
+
+
+ ); +} diff --git a/app/ui/common/submitButton.tsx b/app/ui/common/submitButton.tsx index 4fd50e2..1dcde2e 100644 --- a/app/ui/common/submitButton.tsx +++ b/app/ui/common/submitButton.tsx @@ -1,35 +1,36 @@ -import clsx from "clsx"; +import clsx from 'clsx'; export default function SubmitButton({ - text, - active, - onClick, - width, - height, + text, + active, + onClick, + width, + height }: { - text?: string; - active?: boolean; - onClick: () => void; - width?:string; - height?:string; + text?: string; + active?: boolean; + onClick: () => void; + width?: string; + height?: string; }) { - const btnText = text || "완료"; - const isActive = active ?? true; - const activeOnClick = isActive ? onClick : undefined; + const btnText = text || '완료'; + const isActive = active ?? true; + const activeOnClick = isActive ? onClick : undefined; - return ( - - ); + return ( + + ); } diff --git a/app/ui/common/xsContainer.tsx b/app/ui/common/xsContainer.tsx index ae94bad..6665574 100644 --- a/app/ui/common/xsContainer.tsx +++ b/app/ui/common/xsContainer.tsx @@ -1,9 +1,9 @@ export default function XsContainer({ - children,className - }: Readonly<{ - children: React.ReactNode; - className?:string; - }>) { - return
{children}
; - } - \ No newline at end of file + children, + className +}: Readonly<{ + children: React.ReactNode; + className?: string; +}>) { + return
{children}
; +} diff --git a/app/ui/company/CompanyMenu.tsx b/app/ui/company/CompanyMenu.tsx index 062afac..28ab32d 100644 --- a/app/ui/company/CompanyMenu.tsx +++ b/app/ui/company/CompanyMenu.tsx @@ -25,7 +25,7 @@ export default function CompanyMenu({ company_id, currentPage }: CompanyMenuProp diff --git a/app/ui/company/CompanyOverviewCard.tsx b/app/ui/company/CompanyOverviewCard.tsx index a130a8e..c32919c 100644 --- a/app/ui/company/CompanyOverviewCard.tsx +++ b/app/ui/company/CompanyOverviewCard.tsx @@ -24,7 +24,7 @@ export function CompanyOverviewCard({ companyData }: { companyData: CompanyOverv

{companyData.company_name}

- {companyData.industry_type.length>0 ? ( + {companyData.industry_type.length > 0 ? ( companyData.industry_type.map((industry) => (
)) ) : ( -
+
)}
diff --git a/app/ui/company/TierDistributionChart.tsx b/app/ui/company/TierDistributionChart.tsx index 9e23b9a..8f01939 100644 --- a/app/ui/company/TierDistributionChart.tsx +++ b/app/ui/company/TierDistributionChart.tsx @@ -93,15 +93,15 @@ const TierDistributionChart = ({ data: dataLabDetails }: Props) => { const [isMobile, setIsMobile] = useState(false); useEffect(() => { const handleResize = () => { - setIsMobile(window.innerWidth < 560); // 768px 이하이면 모바일로 간주 + setIsMobile(window.innerWidth < 560); // 768px 이하이면 모바일로 간주 }; - + window.addEventListener('resize', handleResize); handleResize(); // 초기 상태 설정 - + return () => window.removeEventListener('resize', handleResize); // cleanup - }, []); - + }, []); + const chartData = generateData(dataLabDetails); const maxTotal = Math.max(...chartData.map((d) => d.total)); @@ -120,35 +120,34 @@ const TierDistributionChart = ({ data: dataLabDetails }: Props) => { return ( - {Object.entries(tierBars).map(([tier, bars]) => { - const topBar = bars.reduce((prevBar, currBar) => - currBar.y < prevBar.y ? currBar : prevBar - ); - const tierData = chartData.find((d) => d.tier === tier); - const total = tierData?.total ?? 0; - if (total === 0) return null; // total이 0이면 렌더링하지 않음 - - const x = topBar.x + topBar.width / 2; - const y = topBar.y - 5; - return ( - - {total} - - ); - })} + {Object.entries(tierBars).map(([tier, bars]) => { + const topBar = bars.reduce((prevBar, currBar) => + currBar.y < prevBar.y ? currBar : prevBar + ); + const tierData = chartData.find((d) => d.tier === tier); + const total = tierData?.total ?? 0; + if (total === 0) return null; // total이 0이면 렌더링하지 않음 + + const x = topBar.x + topBar.width / 2; + const y = topBar.y - 5; + return ( + + {total} + + ); + })} - ); - + ); }; return ( @@ -157,7 +156,16 @@ const TierDistributionChart = ({ data: dataLabDetails }: Props) => { tooltip={({ id, value }) => { const formattedId = String(id).replace(/(\D+)(\d)/, '$1 $2'); // id를 문자열로 변환 후 공백 추가 return ( -
+
{formattedId}: {value}명
); @@ -200,19 +208,19 @@ const TierDistributionChart = ({ data: dataLabDetails }: Props) => { axisLeft={ isMobile ? { - tickSize: 5, - tickPadding: 10, - tickRotation: 0, - tickValues: 3, - format: (value: number) => `${value}`, - } // 모바일에서 축을 숨김 + tickSize: 5, + tickPadding: 10, + tickRotation: 0, + tickValues: 3, + format: (value: number) => `${value}` + } // 모바일에서 축을 숨김 : { tickSize: 5, tickPadding: 10, tickRotation: 0, tickValues: 5, - format: (value: number) => `${value}`, - } + format: (value: number) => `${value}` + } } enableGridY={false} enableGridX={false} diff --git a/app/ui/company/positionSelectBox.tsx b/app/ui/company/positionSelectBox.tsx index 536fe26..3c2e2d3 100644 --- a/app/ui/company/positionSelectBox.tsx +++ b/app/ui/company/positionSelectBox.tsx @@ -35,7 +35,9 @@ export default function PositionSelectBox({ router.push(createPageURL(value)); }; return ( -
+
- + {isOfficial && ( -
+
verified
)}
); -} \ No newline at end of file +} diff --git a/app/ui/company/suggestionBtn.tsx b/app/ui/company/suggestionBtn.tsx index fed3e83..2c155f9 100644 --- a/app/ui/company/suggestionBtn.tsx +++ b/app/ui/company/suggestionBtn.tsx @@ -1,7 +1,13 @@ 'use client'; import Link from 'next/link'; -export default function SuggestionBtn({company_id,position_id}:{company_id:string,position_id:string}) { +export default function SuggestionBtn({ + company_id, + position_id +}: { + company_id: string; + position_id: string; +}) { return ( Promise }) { - +import { Button } from '../shadcn/components/ui/button'; +export default function TrLink({ onClick }: { company_id?: string; onClick: () => Promise }) { return ( <>