diff --git a/apps/common/features/.gitignore b/apps/common/features/.gitignore deleted file mode 100644 index e8d8437ee..000000000 --- a/apps/common/features/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -.env* \ No newline at end of file diff --git a/apps/common/features/.prettierrc b/apps/common/features/.prettierrc deleted file mode 100644 index b4bfed357..000000000 --- a/apps/common/features/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "plugins": ["prettier-plugin-tailwindcss"] -} diff --git a/apps/common/features/app/(with-base-layout)/board/page.tsx b/apps/common/features/app/(with-base-layout)/board/page.tsx deleted file mode 100644 index 9f8a68c08..000000000 --- a/apps/common/features/app/(with-base-layout)/board/page.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import { BoardPage } from "@/pages/board"; -export default BoardPage; diff --git a/apps/common/features/app/(with-base-layout)/layout.tsx b/apps/common/features/app/(with-base-layout)/layout.tsx deleted file mode 100644 index c3254a935..000000000 --- a/apps/common/features/app/(with-base-layout)/layout.tsx +++ /dev/null @@ -1,35 +0,0 @@ -"use client"; - -import { usePathname, useRouter } from "next/navigation"; -import { useQueryClient } from "@tanstack/react-query"; -import type { MenuItem } from "@common/components/api"; -import { BaseLayout } from "@common/components/ui"; -import { useMenuStore } from "@/shared/lib"; -import { PageLayout } from "@/shared/ui/page-layout"; - -export default function WithBaseLayout({ - children, -}: { - children: React.ReactNode; -}) { - const router = useRouter(); - const pathname = usePathname(); - const queryClient = useQueryClient(); - - const { setCurrentMenuInfo } = useMenuStore((state) => state); - - const handleMenuClick = (item: MenuItem) => { - setCurrentMenuInfo(item); - router.push(item.urlPath); - }; - - return ( - - {children} - - ); -} diff --git a/apps/common/features/app/(with-base-layout)/loading.tsx b/apps/common/features/app/(with-base-layout)/loading.tsx deleted file mode 100644 index 3a3b15932..000000000 --- a/apps/common/features/app/(with-base-layout)/loading.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import { SkeletonPage } from "@/shared/ui/skeleton-page"; -export default SkeletonPage; diff --git a/apps/common/features/app/api/proxy/[...url]/route.ts b/apps/common/features/app/api/proxy/[...url]/route.ts deleted file mode 100644 index d3092c5c1..000000000 --- a/apps/common/features/app/api/proxy/[...url]/route.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { - ACCESS_TOKEN, - AUTH_USER_ID, - CLAIM_NAME, - REFRESH_TOKEN, - SERVER_API_URL, - SITE_ID, -} from "@/shared/config"; -import { cookies } from "next/headers"; -import { NextResponse } from "next/server"; - -async function handler( - request: Request, - params: { url: string[] }, - method: "GET" | "POST" | "PUT" | "DELETE", -) { - const cookieStore = await cookies(); - const headers: Record = { - "Content-Type": "application/json", - "X-Site-Id": SITE_ID, - }; - let body = {}; - const isRefreshHandler = params.url.includes("refresh"); - - // silent refresh - if (isRefreshHandler) { - const refreshToken = cookieStore.get(REFRESH_TOKEN); - headers[CLAIM_NAME] = refreshToken?.value ?? ""; - - if (!headers[CLAIM_NAME]) { - return NextResponse.json({ message: "Can't refresh" }, { status: 401 }); - } - } - - try { - if (!isRefreshHandler) { - body = await request.json(); - } - - const result = await fetch(`${SERVER_API_URL}/${params.url.join("/")}`, { - method, - headers, - body: JSON.stringify(body), - }); - - if (!result.ok) { - return NextResponse.json( - { message: "Invalid Credentials" }, - { status: 401 }, - ); - } - - const accessToken = result.headers.get(ACCESS_TOKEN); - const refreshToken = result.headers.get(REFRESH_TOKEN); - const userId = result.headers.get(AUTH_USER_ID); - - if (accessToken && userId) { - const response = NextResponse.json({ - [ACCESS_TOKEN]: accessToken, - [AUTH_USER_ID]: userId, - }); - - if (refreshToken) { - cookieStore.set(REFRESH_TOKEN, refreshToken, { - httpOnly: true, - sameSite: "lax", - path: "/", - }); - } - - return response; - } - - return NextResponse.json( - { message: "Invalid Credentials" }, - { status: 401 }, - ); - } catch (error) { - return NextResponse.json( - { message: "Server Error", error }, - { status: 500 }, - ); - } -} - -export async function POST( - request: Request, - props: { params: Promise<{ url: string[] }> }, -) { - const params = await props.params; - return handler(request, params, "POST"); -} - -export async function PUT( - request: Request, - props: { params: Promise<{ url: string[] }> }, -) { - const params = await props.params; - return handler(request, params, "PUT"); -} diff --git a/apps/common/features/app/auth/login/page.tsx b/apps/common/features/app/auth/login/page.tsx deleted file mode 100644 index 8f9e6adc6..000000000 --- a/apps/common/features/app/auth/login/page.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import { LoginPage } from "@/pages/auth/login"; -export default LoginPage; diff --git a/apps/common/features/app/layout.tsx b/apps/common/features/app/layout.tsx deleted file mode 100644 index aa2049dcc..000000000 --- a/apps/common/features/app/layout.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import type { Metadata } from "next"; -import { App } from "@/app"; - -export const metadata: Metadata = { - title: "유역하수도 통합 정보플랫폼", -}; - -export default App; diff --git a/apps/common/features/eslint.config.mjs b/apps/common/features/eslint.config.mjs deleted file mode 100644 index 9109635e9..000000000 --- a/apps/common/features/eslint.config.mjs +++ /dev/null @@ -1,21 +0,0 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); - -const eslintConfig = [ - ...compat.extends("next/core-web-vitals", "next/typescript"), - { - rules: { - "react-hooks/exhaustive-deps": "off", - }, - }, -]; - -export default eslintConfig; diff --git a/apps/common/features/middleware.ts b/apps/common/features/middleware.ts deleted file mode 100644 index 5b38dc5a8..000000000 --- a/apps/common/features/middleware.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; -import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config"; - -const serverApiUrl = process.env.NEXT_PUBLIC_SERVER_API_URL; - -export function middleware(req: NextRequest) { - const pathname = req.nextUrl.pathname; - const searchParams = req.nextUrl.searchParams; - - if (pathname.startsWith("/server")) { - const queryParams = searchParams.toString(); - const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${ - queryParams ? `?${queryParams}` : "" - }`; - return NextResponse.rewrite(new URL(newUrl)); - } - - if (pathname.startsWith("/attach-service")) { - const requestHeaders = new Headers(req.headers); - const token = req.cookies.get(CLAIM_NAME)?.value; - const userId = req.cookies.get(AUTH_USER_ID)?.value; - const newUrl = `${serverApiUrl}${pathname}`; - - if (token) requestHeaders.set(CLAIM_NAME, token); - if (userId) requestHeaders.set(AUTH_USER_ID, userId); - - return NextResponse.rewrite(new URL(newUrl), { - headers: requestHeaders, - }); - } - - return NextResponse.next(); -} - -export const config = { - matcher: ["/server/:path*", "/attach-service/:path*"], -}; diff --git a/apps/common/features/next.config.ts b/apps/common/features/next.config.ts deleted file mode 100644 index cb651cdc0..000000000 --- a/apps/common/features/next.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { NextConfig } from "next"; - -const nextConfig: NextConfig = {}; - -export default nextConfig; diff --git a/apps/common/features/package.json b/apps/common/features/package.json deleted file mode 100644 index bf44a814c..000000000 --- a/apps/common/features/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "feature", - "version": "0.0.0", - "private": true, - "scripts": { - "dev": "next dev -p 13000", - "build": "next build", - "start": "next start -p 13000", - "lint": "next lint" - }, - "dependencies": { - "@common/assets": "workspace:*", - "@common/components": "workspace:*", - "@frontend-opensource/use-react-hooks": "^1.1.4", - "@hookform/resolvers": "^4.1.3", - "@minoru/react-dnd-treeview": "^3.5.0", - "@radix-ui/react-label": "^2.1.2", - "@radix-ui/react-slot": "^1.1.2", - "@tanstack/react-query": "^5.67.1", - "@tanstack/react-table": "^8.21.2", - "@tinymce/tinymce-react": "^6.1.0", - "axios": "^1.8.1", - "chart.js": "^4.4.8", - "dayjs": "^1.11.13", - "js-cookie": "^3.0.5", - "next": "15.1.7", - "react-chartjs-2": "^5.3.0", - "react-dnd": "^16.0.1", - "react-hook-form": "^7.54.2", - "tailwindcss-animate": "^1.0.7", - "tus-js-client": "^4.3.1", - "zod": "^3.24.2", - "zustand": "^5.0.3" - }, - "devDependencies": { - "@eslint/eslintrc": "^3", - "@faker-js/faker": "^9.5.0", - "@types/js-cookie": "^3.0.6", - "@types/node": "^22.13.1", - "@types/webpack": "^5.28.5", - "eslint": "^9", - "eslint-config-next": "15.1.7", - "postcss": "^8", - "prettier": "^3.4.2", - "prettier-plugin-tailwindcss": "^0.6.11", - "steiger": "^0.5.5", - "tailwindcss": "^3.4.1", - "typescript": "^5" - } -} diff --git a/apps/common/features/pages/.gitkeep b/apps/common/features/pages/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/common/features/postcss.config.mjs b/apps/common/features/postcss.config.mjs deleted file mode 100644 index 1a69fd2a4..000000000 --- a/apps/common/features/postcss.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('postcss-load-config').Config} */ -const config = { - plugins: { - tailwindcss: {}, - }, -}; - -export default config; diff --git a/apps/common/features/public/images/bg_login.jpg b/apps/common/features/public/images/bg_login.jpg deleted file mode 100755 index b7793d16a..000000000 Binary files a/apps/common/features/public/images/bg_login.jpg and /dev/null differ diff --git a/apps/common/features/src/app/index.tsx b/apps/common/features/src/app/index.tsx deleted file mode 100644 index 5a73f2fdd..000000000 --- a/apps/common/features/src/app/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import "./styles/base.css"; -import "./styles/components.css"; -import { AppProvider } from "./providers"; -import { cookies } from "next/headers"; - -const App = async ({ children }: Readonly<{ children: React.ReactNode }>) => { - const theme = (await cookies()).get("site-theme-key"); - - return ( - - - {children} - - - ); -}; - -export { App }; diff --git a/apps/common/features/src/app/providers/app-provider.tsx b/apps/common/features/src/app/providers/app-provider.tsx deleted file mode 100644 index 6fd488b90..000000000 --- a/apps/common/features/src/app/providers/app-provider.tsx +++ /dev/null @@ -1,28 +0,0 @@ -"use client"; - -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { ConfirmProvider } from "@frontend-opensource/use-react-hooks"; -import { AuthWrapper } from "@/entities/auth"; -import { MenuWrapper } from "@/entities/menu"; -import { StoreProvider } from "@/shared/providers"; -import { AlertDialog } from "@/shared/ui/alert-dialog"; -import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; - -const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { - const queryClient = new QueryClient(); - return ( - - - - - {children} - - - - - - - ); -}; - -export { AppProvider }; diff --git a/apps/common/features/src/app/providers/index.ts b/apps/common/features/src/app/providers/index.ts deleted file mode 100644 index 15f99b7fd..000000000 --- a/apps/common/features/src/app/providers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AppProvider } from "./app-provider"; diff --git a/apps/common/features/src/app/styles/base.css b/apps/common/features/src/app/styles/base.css deleted file mode 100644 index e24111afe..000000000 --- a/apps/common/features/src/app/styles/base.css +++ /dev/null @@ -1,11 +0,0 @@ -@import "@common/assets/styles/base.css"; -@import "@common/assets/styles/diveicon.css"; - -@tailwind base; -@tailwind utilities; - -html, -body { - font-family: "Noto Sans KR", sans-serif; - font-size: 10px; -} diff --git a/apps/common/features/src/app/styles/components.css b/apps/common/features/src/app/styles/components.css deleted file mode 100644 index 5b9742c0f..000000000 --- a/apps/common/features/src/app/styles/components.css +++ /dev/null @@ -1,129 +0,0 @@ -.card { - position: relative; - margin: 0.6rem; - box-sizing: border-box; - min-height: 2rem; - border-radius: 0.5rem; - padding: 0.6rem; - font-size: 1.3rem; - color: #666; -} - -.card_width10 { - width: calc(10% - 12px); -} - -.card_width20 { - width: calc(20% - 12px); -} - -.card_width25 { - width: calc(25% - 12px); -} - -.card_width30 { - width: calc(30% - 12px); -} - -.card_width33 { - width: calc(33.333% - 12px); -} - -.card_width40 { - width: calc(40% - 12px); -} - -.card_width45 { - width: calc(45% - 12px); -} - -.card_width50 { - width: calc(50% - 12px); -} - -.card_width60 { - width: calc(60% - 12px); -} - -.card_width66 { - width: calc(66.666% - 12px); -} - -.card_width70 { - width: calc(70% - 12px); -} - -.card_width75 { - width: calc(75% - 12px); -} - -.card_width80 { - width: calc(80% - 12px); -} - -.card_width90 { - width: calc(90% - 12px); -} - -.card_width100 { - width: calc(100% - 12px); -} - -.card_nopadding { - padding: 0 !important; -} - -.card_nomargin { - width: 100%; - margin: 0 !important; - padding: 0 !important; -} - -.topline { - border-top: 1px solid #ccc; -} - -.bottomline { - border-bottom: 1px solid #e6eef3; - background: #fff; -} - -.card-border { - border: 1px solid #dbe2e6; - background-color: rgba(255, 255, 255, 0.6); - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); -} - -.card-header { - margin-top: -0.6rem; - margin-left: -0.6rem; - margin-right: -0.6rem; - display: flex; - align-items: center; - justify-content: space-between; - border-bottom: 1px solid #e1e7eb; - padding: 1rem; -} - -.card-footer { - margin-left: -0.6rem; - margin-right: -0.6rem; - margin-top: 0.5rem; - display: flex; - align-items: center; - justify-content: center; - border-top: 1px solid #e1e7eb; - padding-top: 1rem; - padding-bottom: 1rem; -} - -/* 블랙 테마 */ -[data-theme="black"] { - .card-border { - background-color: rgba(255, 255, 255, 0.065); - border-color: #38383a; - } - .card-header { - border-bottom-color: #3f4042; - } -} diff --git a/apps/common/features/src/entities/attachment/api/attachment-service.ts b/apps/common/features/src/entities/attachment/api/attachment-service.ts deleted file mode 100644 index c930b7012..000000000 --- a/apps/common/features/src/entities/attachment/api/attachment-service.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import type { - Attachment, - AttachmentService, -} from "../model/attachment-interface"; - -export class AttachmentApiService implements AttachmentService { - public async getAttachments(atflCd: string): Promise { - const response = await client.get( - `${ENDPOINT.ATTACH_SERVICE.ATTACHMENTS}/${atflCd}`, - ); - return response.data; - } - - public async deleteAttachment(atflId: string): Promise { - await client.delete(`${ENDPOINT.ATTACH_SERVICE.ATTACHMENTS}/${atflId}`); - } - - public async deleteAttachmentByAtflCd(atflCd: string): Promise { - await client.delete( - `${ENDPOINT.ATTACH_SERVICE.ATTACHMENTS}/atflCd/${atflCd}`, - ); - } - - public async getImageUrl(atflId: string): Promise { - if (!atflId) return ""; - const response = await fetch(`${ENDPOINT.ATTACH_SERVICE.IMAGES}/${atflId}`); - const blob = await response.blob(); - return URL.createObjectURL(blob); - } - - public async getImageUrlByAtflCd(atflCd: string): Promise { - if (!atflCd) return ""; - const response = await fetch( - `${ENDPOINT.ATTACH_SERVICE.IMAGES}/atflCd/${atflCd}`, - ); - const blob = await response.blob(); - return URL.createObjectURL(blob); - } -} - -export const AttachmentApi = new AttachmentApiService(); diff --git a/apps/common/features/src/entities/attachment/index.ts b/apps/common/features/src/entities/attachment/index.ts deleted file mode 100644 index 182ef9fd6..000000000 --- a/apps/common/features/src/entities/attachment/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AttachmentApi } from "./api/attachment-service"; diff --git a/apps/common/features/src/entities/attachment/model/attachment-interface.ts b/apps/common/features/src/entities/attachment/model/attachment-interface.ts deleted file mode 100644 index 5986a96d1..000000000 --- a/apps/common/features/src/entities/attachment/model/attachment-interface.ts +++ /dev/null @@ -1,22 +0,0 @@ -export interface Attachment { - atflCd: string; - atflSn: number; - atflId: string; - physFileNm: string; - orgnlFileNm: string; - atflFlieSz: number; - atflType: string; - dwnldNocs: number; - delYn: string; - lnkgDmnId: string; - lnkgDmnNm: string; - regDt: string; -} - -export interface AttachmentService { - getAttachments: (atflCd: string) => Promise; - deleteAttachment: (atflId: string) => Promise; - deleteAttachmentByAtflCd: (atflCd: string) => Promise; - getImageUrl: (atflId: string) => Promise; - getImageUrlByAtflCd: (atflCd: string) => Promise; -} diff --git a/apps/common/features/src/entities/auth/api/login-service.ts b/apps/common/features/src/entities/auth/api/login-service.ts deleted file mode 100644 index c1968fe36..000000000 --- a/apps/common/features/src/entities/auth/api/login-service.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { AxiosError } from "axios"; -import { - ENDPOINT, - JWT_EXPIRATION_TIME, - ACCESS_TOKEN, - AUTH_USER_ID, - CLAIM_NAME, -} from "@/shared/config"; -import type { LoginService, ILogin } from "../model/login-interface"; -import { tokenManager } from "../lib/token-manager"; - -export class LoginApiService implements LoginService { - private static instance: LoginApiService; - - private constructor() {} - - public static getInstance(): LoginApiService { - if (!LoginApiService.instance) { - LoginApiService.instance = new LoginApiService(); - } - return LoginApiService.instance; - } - - public async login(payload: ILogin): Promise { - try { - const response = await fetch(`/api/proxy${ENDPOINT.USER_SERVICE.LOGIN}`, { - method: "POST", - body: JSON.stringify({ - userId: payload.userId, - password: payload.password, - }), - }); - - const data = await response.json(); - const accessToken = data[ACCESS_TOKEN]; - const tokenId = data[AUTH_USER_ID]; - - if (!accessToken || !tokenId) { - throw new Error("Missing required authentication tokens"); - } - - tokenManager.setToken(CLAIM_NAME, accessToken); - tokenManager.setToken(AUTH_USER_ID, tokenId); - tokenManager.setupRefreshTimer( - () => this.silentRefresh(), - JWT_EXPIRATION_TIME, - ); - } catch (error) { - if (error instanceof AxiosError) { - throw new Error(`Login failed: ${error.response?.data?.message}`); - } - throw new Error(`Login failed: ${error}`); - } - } - - public async silentRefresh(): Promise { - try { - const response = await fetch( - `/api/proxy${ENDPOINT.USER_SERVICE.SILENT_REFRESH}`, - { method: "PUT" }, - ); - - const data = await response.json(); - const accessToken = data[ACCESS_TOKEN]; - const tokenId = data[AUTH_USER_ID]; - - if (!accessToken || !tokenId) { - throw new Error("Missing required authentication tokens"); - } - - tokenManager.setToken(CLAIM_NAME, accessToken); - tokenManager.setToken(AUTH_USER_ID, tokenId); - } catch (error) { - tokenManager.clearAuthToken(); - if (error instanceof AxiosError) { - throw new Error( - `Silent refresh failed: ${error.response?.data?.message}`, - ); - } - throw new Error(`Silent refresh failed: ${error}`); - } - } -} - -export const LoginApi = LoginApiService.getInstance(); diff --git a/apps/common/features/src/entities/auth/index.ts b/apps/common/features/src/entities/auth/index.ts deleted file mode 100644 index 97e142225..000000000 --- a/apps/common/features/src/entities/auth/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { LoginApi } from "./api/login-service"; -export { AuthWrapper } from "./lib/auth-wrapper"; diff --git a/apps/common/features/src/entities/auth/lib/auth-wrapper.tsx b/apps/common/features/src/entities/auth/lib/auth-wrapper.tsx deleted file mode 100644 index 705c03231..000000000 --- a/apps/common/features/src/entities/auth/lib/auth-wrapper.tsx +++ /dev/null @@ -1,49 +0,0 @@ -"use client"; - -import { useEffect } from "react"; -import { useRouter } from "next/navigation"; -import { client } from "@/shared/api"; -import type { IUserInfo } from "@/shared/store"; -import { getCookie, useUserStore } from "@/shared/lib"; -import { ENDPOINT, AUTH_USER_ID } from "@/shared/config"; -import { LoginApi } from "../api/login-service"; - -const AuthWrapper = ({ children }: { children: React.ReactNode }) => { - const router = useRouter(); - const { userInfo, setUserInfo } = useUserStore((state) => state); - - async function authCheck() { - const userId = getCookie(AUTH_USER_ID); - if (!userId) { - throw new Error("Missing required authentication tokens"); - } - - const response = await client.get( - `${ENDPOINT.USER_SERVICE.USERS}/${userId}`, - ); - if (!userInfo) setUserInfo(response.data); - } - - useEffect(() => { - (async () => { - try { - await authCheck(); - } catch (error) { - console.error(error); - - try { - await LoginApi.silentRefresh(); - await authCheck(); - } catch (refreshError) { - console.error("Token refresh failed:", refreshError); - setUserInfo(null); - router.push("/auth/login"); - } - } - })(); - }, []); - - return <>{children}>; -}; - -export { AuthWrapper }; diff --git a/apps/common/features/src/entities/auth/lib/token-manager.ts b/apps/common/features/src/entities/auth/lib/token-manager.ts deleted file mode 100644 index 0e761486a..000000000 --- a/apps/common/features/src/entities/auth/lib/token-manager.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { AUTH_USER_ID, CLAIM_NAME } from "@/shared/config"; -import { getCookie, setCookie, removeCookie } from "@/shared/lib"; - -export class TokenManager { - private static instance: TokenManager; - private refreshTimer: NodeJS.Timeout | null = null; - - private constructor() {} - - public static getInstance(): TokenManager { - if (!TokenManager.instance) { - TokenManager.instance = new TokenManager(); - } - return TokenManager.instance; - } - - public getToken(key: string): string | undefined { - return getCookie(key); - } - - public setToken(key: string, value: string): void { - setCookie(key, value, { - secure: window.location.protocol === "https:", - sameSite: "lax", - }); - } - - public removeToken(key: string): void { - removeCookie(key); - } - - public setupRefreshTimer( - callback: () => Promise, - expirationTime: number, - ): void { - if (this.refreshTimer) { - clearTimeout(this.refreshTimer); - } - - this.refreshTimer = setTimeout(() => { - callback().catch((error) => { - console.error("Silent refresh failed:", error); - this.clearAuthToken(); - }); - }, expirationTime - 60000); - } - - public clearAuthToken(): void { - if (this.refreshTimer) { - clearTimeout(this.refreshTimer); - this.refreshTimer = null; - } - - this.removeToken(CLAIM_NAME); - this.removeToken(AUTH_USER_ID); - } -} - -export const tokenManager = TokenManager.getInstance(); diff --git a/apps/common/features/src/entities/auth/model/login-interface.ts b/apps/common/features/src/entities/auth/model/login-interface.ts deleted file mode 100644 index 5aaf53044..000000000 --- a/apps/common/features/src/entities/auth/model/login-interface.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface ILogin { - userId: string; - password: string; -} - -export interface LoginService { - login(payload: ILogin): Promise; - silentRefresh(): Promise; -} diff --git a/apps/common/features/src/entities/board/api/board-service.ts b/apps/common/features/src/entities/board/api/board-service.ts deleted file mode 100644 index 9cf29599b..000000000 --- a/apps/common/features/src/entities/board/api/board-service.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import type { - BoardPopupList, - BoardPopupParams, - BoardService, -} from "../model/board-interface"; - -export class BoardApiService implements BoardService { - public async getBoardPopupList( - params: BoardPopupParams, - ): Promise { - const response = await client.get( - `${ENDPOINT.BOARD_SERVICE.BBS}`, - { params }, - ); - return response.data; - } -} - -export const BoardApi = new BoardApiService(); diff --git a/apps/common/features/src/entities/board/index.ts b/apps/common/features/src/entities/board/index.ts deleted file mode 100644 index 2173bb4a0..000000000 --- a/apps/common/features/src/entities/board/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { BoardApi } from "./api/board-service"; -export { type BoardPopup } from "./model/board-interface"; diff --git a/apps/common/features/src/entities/board/model/board-interface.ts b/apps/common/features/src/entities/board/model/board-interface.ts deleted file mode 100644 index 942840d74..000000000 --- a/apps/common/features/src/entities/board/model/board-interface.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { PageableList, PageableParams } from "@/shared/model"; - -export const BOARD_TYPE = { - BBSNORMAL: "BBSNORMAL", - BBSFAQ: "BBSFAQ", - BBSIMAGE: "BBSIMAGE", - BBSMOVIE: "BBSMOVIE", -} as const; - -export type BoardType = (typeof BOARD_TYPE)[keyof typeof BOARD_TYPE]; - -export interface BoardPopupParams extends PageableParams { - bbsNm?: string; -} - -export interface BoardPopup { - bbsId: number; - bbsTypeCd: BoardType; - bbsTypeNm: string; - bbsNm: string; - bbsExpln: string; - rfrncUseYn: string; - atflUseYn: string; - atflMaxCnt: number; - atflMaxFileSz: number; - ansUseYn: string; - cmntUseYn: string; - dgstfnEvlUseYn: string; - smsUseYn: string; - upndFixUseYn: string; - pstgPrdUseYn: string; - popupUseYn: string; - delYn: string; - regDt: string; - pstCnt: number; -} - -export type BoardPopupList = PageableList; - -export interface BoardService { - getBoardPopupList: (params: BoardPopupParams) => Promise; -} diff --git a/apps/common/features/src/entities/code/@x/posting.ts b/apps/common/features/src/entities/code/@x/posting.ts deleted file mode 100644 index 0525684d9..000000000 --- a/apps/common/features/src/entities/code/@x/posting.ts +++ /dev/null @@ -1 +0,0 @@ -export { CodeSelect } from "../ui/code-select"; diff --git a/apps/common/features/src/entities/code/api/code-service.ts b/apps/common/features/src/entities/code/api/code-service.ts deleted file mode 100644 index 0d1055f6a..000000000 --- a/apps/common/features/src/entities/code/api/code-service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import type { CodeService, ICode } from "../model/code-interface"; - -export class CodeApiService implements CodeService { - public async getCode(upCd: string): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.CODE}/${upCd}`, - ); - return response.data; - } -} - -export const CodeApi = new CodeApiService(); diff --git a/apps/common/features/src/entities/code/index.ts b/apps/common/features/src/entities/code/index.ts deleted file mode 100644 index 0b6633f4b..000000000 --- a/apps/common/features/src/entities/code/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { CodeSelect } from "./ui/code-select"; diff --git a/apps/common/features/src/entities/code/model/code-interface.ts b/apps/common/features/src/entities/code/model/code-interface.ts deleted file mode 100644 index 0d066e6da..000000000 --- a/apps/common/features/src/entities/code/model/code-interface.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface ICode { - lwpoCd: string; - upCd: string; - lwpoCdNm: string; -} - -export interface CodeService { - getCode(upCd: string): Promise; -} diff --git a/apps/common/features/src/entities/code/ui/code-select.tsx b/apps/common/features/src/entities/code/ui/code-select.tsx deleted file mode 100644 index bd175a8a9..000000000 --- a/apps/common/features/src/entities/code/ui/code-select.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@common/components"; -import { ENDPOINT } from "@/shared/config"; -import { CodeApi } from "../api/code-service"; - -type CodeSelectProps = { - upCd: string; -} & React.ComponentPropsWithoutRef; - -function CodeSelect({ upCd, defaultValue, ...props }: CodeSelectProps) { - const { data: code } = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.CODE, upCd], - queryFn: () => CodeApi.getCode(upCd), - enabled: !!upCd, - }); - - const defaultValueText = - code?.find((item) => item.lwpoCd === defaultValue)?.lwpoCdNm ?? "선택"; - - return ( - - - - - - {code?.map((item) => ( - - {item.lwpoCdNm} - - ))} - - - ); -} - -export { CodeSelect }; diff --git a/apps/common/features/src/entities/editor/api/editor-service.ts b/apps/common/features/src/entities/editor/api/editor-service.ts deleted file mode 100644 index 3e2fc75a4..000000000 --- a/apps/common/features/src/entities/editor/api/editor-service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { client } from "@/shared/api"; -import type { - EditorService, - FileInfo, - UploadFile, -} from "../model/editor-interface"; -import { ENDPOINT } from "@/shared/config"; - -export class EditorApiService implements EditorService { - async uploadImage(data: UploadFile): Promise { - const response = await client.post( - ENDPOINT.ATTACH_SERVICE.EDITOR_UPLOAD, - data, - ); - return response.data; - } -} - -export const EditorApi = new EditorApiService(); diff --git a/apps/common/features/src/entities/editor/index.ts b/apps/common/features/src/entities/editor/index.ts deleted file mode 100644 index 1ae82fb4f..000000000 --- a/apps/common/features/src/entities/editor/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Editor } from "./ui/editor"; diff --git a/apps/common/features/src/entities/editor/lib/blob-to-base64.ts b/apps/common/features/src/entities/editor/lib/blob-to-base64.ts deleted file mode 100644 index 2f0e68c0f..000000000 --- a/apps/common/features/src/entities/editor/lib/blob-to-base64.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const blobToBase64 = (blob: Blob): Promise => { - return new Promise((resolve) => { - const reader = new FileReader(); - reader.onload = () => { - const base64 = reader.result as string; - resolve(base64.split(",")[1] || ""); - }; - reader.readAsDataURL(blob); - }); -}; diff --git a/apps/common/features/src/entities/editor/lib/generate-file-info.ts b/apps/common/features/src/entities/editor/lib/generate-file-info.ts deleted file mode 100644 index c36ed3577..000000000 --- a/apps/common/features/src/entities/editor/lib/generate-file-info.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { blobToBase64 } from "./blob-to-base64"; - -export const generateFileInfo = async (blobInfo: { - blob: () => Blob; - filename: () => string; -}) => { - const blob = blobInfo.blob(); - const base64 = await blobToBase64(blob); - return { - fieldName: `${blob.type.split("/")[1]}`, - fileType: blob.type, - fileBase64: base64, - originalName: blobInfo.filename(), - size: blob.size, - }; -}; diff --git a/apps/common/features/src/entities/editor/model/editor-base-config.ts b/apps/common/features/src/entities/editor/model/editor-base-config.ts deleted file mode 100644 index 1b97ba9a0..000000000 --- a/apps/common/features/src/entities/editor/model/editor-base-config.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { SERVER_API_URL } from "@/shared/config"; - -export const editorBaseConfig = { - apiKey: process.env.NEXT_PUBLIC_TINY_API_KEY, - init: { - language: "ko_KR", - height: 500, - plugins: [ - "advlist", - "autolink", - "lists", - "link", - "image", - "charmap", - "preview", - "anchor", - "searchreplace", - "visualblocks", - "code", - "codesample", - "fullscreen", - "insertdatetime", - "media", - "table", - "code", - "help", - "wordcount", - "save", - ], - toolbar: [ - "undo redo | blocks fontfamily fontsize | bold italic underline strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist blockquote | table", - "link image", - ], - images_upload_base_path: SERVER_API_URL, - file_picker_types: "image", - }, -}; diff --git a/apps/common/features/src/entities/editor/model/editor-interface.ts b/apps/common/features/src/entities/editor/model/editor-interface.ts deleted file mode 100644 index ed6b4a987..000000000 --- a/apps/common/features/src/entities/editor/model/editor-interface.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface UploadFile { - fieldName: string; - fileType: string; - fileBase64: string; - originalName: string; - size: number; -} - -export interface FileInfo { - originalFileName: string; - message: string; - fileType: string; - size: number; - uploaded: number; - url: string; -} - -export interface EditorService { - uploadImage(data: UploadFile): Promise; -} diff --git a/apps/common/features/src/entities/editor/ui/editor.tsx b/apps/common/features/src/entities/editor/ui/editor.tsx deleted file mode 100644 index b5ef02153..000000000 --- a/apps/common/features/src/entities/editor/ui/editor.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { useRef } from "react"; -import { - Editor as TinyEditor, - type Editor as TinyEditorInstance, - type IAllProps, -} from "@tinymce/tinymce-react"; -import { editorBaseConfig as baseConfig } from "../model/editor-base-config"; -import { generateFileInfo } from "../lib/generate-file-info"; -import { EditorApi } from "../api/editor-service"; - -const Editor = ({ ...props }: IAllProps) => { - const editorRef = useRef(null); - - const imagesUploadHandler = (blobInfo: { - blob: () => Blob; - filename: () => string; - }) => { - return new Promise(async (resolve) => { - const fileInfo = await generateFileInfo(blobInfo); - const data = await EditorApi.uploadImage(fileInfo); - resolve(data.url); - }); - }; - - const filePickerCallback = ( - callback: (base64: string, meta: { title: string }) => void, - ) => { - const input = document.createElement("input"); - input.setAttribute("type", "file"); - input.setAttribute("accept", "image/*"); - input.onchange = async () => { - const file = input.files?.[0]; - if (!file) return; - const reader = new FileReader(); - reader.onload = async () => { - const base64 = reader.result as string; - callback(base64, { title: file.name }); - }; - reader.readAsDataURL(file); - }; - input.click(); - }; - - return ( - { - editorRef.current = editor; - }} - init={{ - ...baseConfig.init, - images_upload_handler: imagesUploadHandler, - file_picker_callback: filePickerCallback, - }} - {...props} - /> - ); -}; - -export { Editor }; diff --git a/apps/common/features/src/entities/menu-authority/api/menu-authority-service.ts b/apps/common/features/src/entities/menu-authority/api/menu-authority-service.ts deleted file mode 100644 index f9b01b4d8..000000000 --- a/apps/common/features/src/entities/menu-authority/api/menu-authority-service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import type { - MenuAuthorityList, - MenuAuthorityParams, - MenuAuthorityPayloadData, - MenuAuthorityService, -} from "../model/menu-authority-interface"; - -export class MenuAuthorityApiService implements MenuAuthorityService { - public async getMenuAuthorityList( - params: MenuAuthorityParams, - ): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.MENU_AUTHRTS}`, - { params }, - ); - return response.data; - } - - public async saveMenuAuthority( - data: MenuAuthorityPayloadData[], - ): Promise { - const response = await client.post( - `${ENDPOINT.CMS_SERVICE.MENU_AUTHRTS}`, - data, - ); - return response.data; - } -} - -export const MenuAuthorityApi = new MenuAuthorityApiService(); diff --git a/apps/common/features/src/entities/menu-authority/index.ts b/apps/common/features/src/entities/menu-authority/index.ts deleted file mode 100644 index 07433a098..000000000 --- a/apps/common/features/src/entities/menu-authority/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ManagementAuthorityDialog } from "./ui/management-authority-dialog"; diff --git a/apps/common/features/src/entities/menu-authority/model/menu-authority-interface.ts b/apps/common/features/src/entities/menu-authority/model/menu-authority-interface.ts deleted file mode 100644 index d6775838c..000000000 --- a/apps/common/features/src/entities/menu-authority/model/menu-authority-interface.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { z } from "zod"; -import type { PageableList, PageableParams } from "@/shared/model"; - -export interface MenuAuthorityParams extends PageableParams { - groupId?: string; - menuCd?: number; - useYn?: string; -} - -export const menuAuthoritySchema = z.object({ - groupId: z.string(), - groupNm: z.string(), - menuCd: z.number(), - mngAuthrtYn: z.string(), - inqAuthrtYn: z.string(), - regAuthrtYn: z.string(), - mdfcnAuthrtYn: z.string(), - delAuthrtYn: z.string(), - useYn: z.string(), - mode: z.string(), -}); - -export const menuAuthorityPayloadSchema = menuAuthoritySchema.omit({ - groupNm: true, -}); - -export const menuAuthorityFormSchema = z.object({ - menuAuthority: z.array(menuAuthorityPayloadSchema), -}); - -export type MenuAuthority = z.infer; -export type MenuAuthorityList = PageableList; -export type MenuAuthorityPayloadData = z.infer< - typeof menuAuthorityPayloadSchema ->; -export type MenuAuthorityFormData = z.infer; - -export interface MenuAuthorityService { - getMenuAuthorityList(params: MenuAuthorityParams): Promise; - saveMenuAuthority(data: MenuAuthorityPayloadData[]): Promise; -} diff --git a/apps/common/features/src/entities/menu-authority/model/menu-authority-table-columns.tsx b/apps/common/features/src/entities/menu-authority/model/menu-authority-table-columns.tsx deleted file mode 100644 index 1a9863e15..000000000 --- a/apps/common/features/src/entities/menu-authority/model/menu-authority-table-columns.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import type { ColumnDef } from "@tanstack/react-table"; -import type { UseFormReturn } from "react-hook-form"; -import { Checkbox } from "@common/components/ui"; -import type { - MenuAuthority, - MenuAuthorityFormData, - MenuAuthorityPayloadData, -} from "./menu-authority-interface"; - -export const createColumns = ( - form: UseFormReturn, -): ColumnDef[] => { - const getCurrentRow = (i: number) => form.watch("menuAuthority")[i]; - - const handleCheckedChange = - (i: number, key: keyof MenuAuthorityPayloadData) => (checked: boolean) => { - if (getCurrentRow(i)?.mode === "R") { - form.setValue(`menuAuthority.${i}.mode`, "U"); - } - form.setValue(`menuAuthority.${i}.${key}`, checked ? "Y" : "N"); - }; - - return [ - { - accessorKey: "groupNm", - header: "그룹명", - }, - { - accessorKey: "mngAuthrtYn", - header: "관리권한", - cell: ({ row }) => { - return ( - { - if (checked) { - handleCheckedChange( - row.index, - "regAuthrtYn", - )(checked as boolean); - handleCheckedChange( - row.index, - "mdfcnAuthrtYn", - )(checked as boolean); - handleCheckedChange( - row.index, - "delAuthrtYn", - )(checked as boolean); - handleCheckedChange( - row.index, - "inqAuthrtYn", - )(checked as boolean); - } - handleCheckedChange(row.index, "mngAuthrtYn")(checked as boolean); - }} - /> - ); - }, - }, - { - accessorKey: "regAuthrtYn", - header: "등록권한", - cell: ({ row }) => { - return ( - { - if (checked) { - handleCheckedChange( - row.index, - "inqAuthrtYn", - )(checked as boolean); - } - handleCheckedChange(row.index, "regAuthrtYn")(checked as boolean); - }} - /> - ); - }, - }, - { - accessorKey: "mdfcnAuthrtYn", - header: "수정권한 ", - cell: ({ row }) => { - return ( - - ); - }, - }, - { - accessorKey: "delAuthrtYn", - header: "삭제권한", - cell: ({ row }) => { - return ( - - ); - }, - }, - { - accessorKey: "inqAuthrtYn", - header: "조회권한", - cell: ({ row }) => { - return ( - - ); - }, - }, - ]; -}; diff --git a/apps/common/features/src/entities/menu-authority/ui/management-authority-dialog.tsx b/apps/common/features/src/entities/menu-authority/ui/management-authority-dialog.tsx deleted file mode 100644 index 62915e2ed..000000000 --- a/apps/common/features/src/entities/menu-authority/ui/management-authority-dialog.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useMutation, useQuery } from "@tanstack/react-query"; -import { getCoreRowModel, useReactTable } from "@tanstack/react-table"; -import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { - Button, - DataTable, - Dialog, - DialogClose, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@common/components/ui"; -import { ENDPOINT } from "@/shared/config"; -import { useAlertStore } from "@/shared/lib/use-alert-store"; -import { - menuAuthorityFormSchema, - type MenuAuthorityFormData, - type MenuAuthorityPayloadData, -} from "../model/menu-authority-interface"; -import { createColumns } from "../model/menu-authority-table-columns"; -import { MenuAuthorityApi } from "../api/menu-authority-service"; - -type ManagementAuthorityDialogProps = { - menuCd?: number; -} & React.ComponentProps; - -function ManagementAuthorityDialog({ - menuCd, - ...props -}: ManagementAuthorityDialogProps) { - const { confirm } = useConfirm(); - const { setMessage: alert } = useAlertStore((state) => state); - - const { data: menuAuthorityList } = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.MENU_AUTHRTS, menuCd], - queryFn: () => MenuAuthorityApi.getMenuAuthorityList({ menuCd }), - enabled: !!menuCd, - }); - - const { mutateAsync: saveMenuAuthority } = useMutation({ - mutationFn: (data: MenuAuthorityPayloadData[]) => - MenuAuthorityApi.saveMenuAuthority(data), - onSuccess: () => { - alert("저장되었습니다."); - }, - }); - - const form = useForm({ - resolver: zodResolver(menuAuthorityFormSchema), - values: { - menuAuthority: menuAuthorityList?.content ?? [], - }, - }); - - const table = useReactTable({ - data: menuAuthorityList?.content ?? [], - columns: createColumns(form), - getCoreRowModel: getCoreRowModel(), - }); - - const handleSave = async () => { - if (await confirm("저장하시겠습니까?")) { - const data = form.getValues("menuAuthority"); - const filteredData = data.filter((item) => item.mode !== "R"); - await saveMenuAuthority(filteredData); - } - }; - - return ( - - - - - 권한관리 - - - - - 그룹별 메뉴 권한 - - - - - 저장 - - - - 취소 - - - - - - ); -} - -export { ManagementAuthorityDialog }; diff --git a/apps/common/features/src/entities/menu/api/menu-service.ts b/apps/common/features/src/entities/menu/api/menu-service.ts deleted file mode 100644 index b6c1510cd..000000000 --- a/apps/common/features/src/entities/menu/api/menu-service.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { client } from "@common/components/api"; -import { ENDPOINT } from "@/shared/config"; -import type { MenuItem, MenuService } from "../model/menu-interface"; - -export class MenuApiService implements MenuService { - async getMenuRoles(siteId: string): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.MENU_ROLES}/${siteId}`, - ); - return response.data; - } -} - -export const MenuApi = new MenuApiService(); diff --git a/apps/common/features/src/entities/menu/index.ts b/apps/common/features/src/entities/menu/index.ts deleted file mode 100644 index 1fa9dd218..000000000 --- a/apps/common/features/src/entities/menu/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { MenuWrapper } from "./lib/menu-wrapper"; diff --git a/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx b/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx deleted file mode 100644 index d473548af..000000000 --- a/apps/common/features/src/entities/menu/lib/menu-wrapper.tsx +++ /dev/null @@ -1,29 +0,0 @@ -"use client"; - -import { useEffect } from "react"; -import { usePathname } from "next/navigation"; -import { SITE_ID } from "@/shared/config"; -import { useMenuStore } from "@/shared/lib"; -import { MenuApi } from "../api/menu-service"; -import { getCurrentMenu } from "./utils"; - -const MenuWrapper = ({ children }: { children: React.ReactNode }) => { - const pathname = usePathname(); - const { setCurrentMenuInfo } = useMenuStore((state) => state); - - useEffect(() => { - (async () => { - const menuRoles = await MenuApi.getMenuRoles(SITE_ID); - if (!menuRoles) return; - - const currentMenu = getCurrentMenu(menuRoles, pathname ?? ""); - if (!currentMenu) return; - - setCurrentMenuInfo(currentMenu); - })(); - }, []); - - return <>{children}>; -}; - -export { MenuWrapper }; diff --git a/apps/common/features/src/entities/menu/lib/utils.ts b/apps/common/features/src/entities/menu/lib/utils.ts deleted file mode 100644 index 1cf4514d9..000000000 --- a/apps/common/features/src/entities/menu/lib/utils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { MenuItem } from "../model/menu-interface"; - -export const getCurrentMenu = ( - menus: MenuItem[], - pathname: string, -): MenuItem | null => { - for (const menu of menus) { - if ( - menu.urlPath !== "" && - (menu.urlPath === pathname || pathname.startsWith(menu.urlPath)) - ) - return menu; - - if (menu.children) { - const children = getCurrentMenu(menu.children, pathname); - if (children) return children; - } - } - return null; -}; diff --git a/apps/common/features/src/entities/menu/model/menu-interface.ts b/apps/common/features/src/entities/menu/model/menu-interface.ts deleted file mode 100644 index 12c7d007a..000000000 --- a/apps/common/features/src/entities/menu/model/menu-interface.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface MenuItem { - menuCd: number; - menuKornNm: string; - menuEngNm: string; - parentId: number | null; - sortSeq: number; - iconNm?: string; - children: MenuItem[] | null; - levelNo: number; - urlPath: string; - menuLnkgTypeCd: string; - menuLnkgSn: number; - menuPath: string; - qrcd: string; - useYn: string; - otptYn: string; - newWndwYn: string; - requiredUrlPath: boolean; -} - -export interface MenuService { - getMenuRoles(siteId: string): Promise; -} diff --git a/apps/common/features/src/entities/posting/api/posting-service.ts b/apps/common/features/src/entities/posting/api/posting-service.ts deleted file mode 100644 index 2fafd6557..000000000 --- a/apps/common/features/src/entities/posting/api/posting-service.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import type { PageableList } from "@/shared/model"; -import type { - PostService, - PostingParams, - Post, - PostPayloadData, -} from "../model/posting-interface"; - -export class PostingApiService implements PostService { - public async getPostingHistory( - params: PostingParams, - ): Promise> { - const response = await client.get>( - `${ENDPOINT.CMS_SERVICE.POSTINGS}`, - { params }, - ); - return response.data; - } - - public async savePosting(data: PostPayloadData[]): Promise { - const response = await client.post( - `${ENDPOINT.CMS_SERVICE.POSTINGS}`, - data, - ); - return response.data; - } -} - -export const PostingApi = new PostingApiService(); diff --git a/apps/common/features/src/entities/posting/index.ts b/apps/common/features/src/entities/posting/index.ts deleted file mode 100644 index c6029d757..000000000 --- a/apps/common/features/src/entities/posting/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { PostingApi } from "./api/posting-service"; -export { - POSTING_TYPE, - type Post, - type PostPayloadData, -} from "./model/posting-interface"; -export { PostingDialog } from "./ui/posting-dialog"; diff --git a/apps/common/features/src/entities/posting/model/posting-interface.ts b/apps/common/features/src/entities/posting/model/posting-interface.ts deleted file mode 100644 index b14b2ab66..000000000 --- a/apps/common/features/src/entities/posting/model/posting-interface.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { PageableList, PageableParams } from "@/shared/model"; -import { z } from "zod"; - -export const POSTING_TYPE = { - POPUP: "POPUP", - BANNER: "BANNER", - IMAGE: "IMAGE", -} as const; - -export type PostingType = (typeof POSTING_TYPE)[keyof typeof POSTING_TYPE]; - -export interface PostingParams extends PageableParams { - pstgTrgtNo: number; -} - -export const postSchema = z.object({ - siteId: z.string(), - siteNm: z.string(), - pstgTypeCd: z.string(), - pstgTypeNm: z.string(), - pstgTrgtNo: z.number(), - pstgBgngDt: z.string().optional(), - pstgEndDt: z.string().optional(), - pstgPrdSeCd: z.string(), - pstgPrdSeNm: z.string(), - delYn: z.string(), -}); - -export const postPayloadSchema = postSchema - .extend({ - mode: z.string(), - }) - .omit({ - siteNm: true, - pstgTypeNm: true, - pstgPrdSeNm: true, - }); - -export const postingFormSchema = z.object({ - pstg: z.array(postPayloadSchema), -}); - -export type Post = z.infer; -export type PostPayloadData = z.infer; -export type PostingFormData = z.infer; - -export interface PostService { - getPostingHistory: (params: PostingParams) => Promise>; - savePosting: (data: PostPayloadData[]) => Promise; -} diff --git a/apps/common/features/src/entities/posting/ui/posting-dialog.tsx b/apps/common/features/src/entities/posting/ui/posting-dialog.tsx deleted file mode 100644 index 9e27a4485..000000000 --- a/apps/common/features/src/entities/posting/ui/posting-dialog.tsx +++ /dev/null @@ -1,323 +0,0 @@ -import dayjs from "dayjs"; -import { useState } from "react"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useFieldArray, useForm } from "react-hook-form"; -import { useMutation, useQuery } from "@tanstack/react-query"; -import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { - Dialog, - DialogTrigger, - Button, - DialogContent, - DialogHeader, - DialogTitle, - Badge, - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, - Checkbox, - Select, - DateRangePicker, - DialogClose, - DialogFooter, -} from "@common/components/ui"; -import { cn } from "@common/components/lib"; -import { CodeSelect } from "@/entities/code/@x/posting"; -import { SiteApi, type Site } from "@/entities/site/@x/posting"; -import type { PageableList } from "@/shared/model"; -import { ENDPOINT } from "@/shared/config"; -import { PostingApi } from "../api/posting-service"; -import { - postingFormSchema, - type PostingFormData, - type PostingType, - type PostPayloadData, -} from "../model/posting-interface"; -import { useAlertStore } from "@/shared/lib/use-alert-store"; - -type DateRange = { - from: string; - to?: string; -}; - -type PostingTarget = { - pstgTrgtNm: string; - pstgTrgtNo: number; -}; - -type PostingDialogProps = { - postingType: PostingType; - postingTargets: PostingTarget[]; -}; - -const POSTING_TYPE_LABEL = { - POPUP: "팝업", - BANNER: "배너", - IMAGE: "이미지", -} as const; - -function PostingDialog({ postingType, postingTargets }: PostingDialogProps) { - const { confirm } = useConfirm(); - const { setMessage: alert } = useAlertStore((state) => state); - const [selectedRows, setSelectedRows] = useState([]); - const [rememberPeriodCode, setRememberPeriodCode] = useState< - Record - >({}); - const [rememberPeriodDate, setRememberPeriodDate] = useState< - Record - >({}); - - const { data: siteList } = useQuery>({ - queryKey: [ENDPOINT.CMS_SERVICE.SITES], - queryFn: () => SiteApi.getSiteList({}), - }); - - const { mutateAsync: savePosting } = useMutation({ - mutationFn: (data: PostPayloadData[]) => PostingApi.savePosting(data), - onSuccess: () => { - alert("저장되었습니다."); - }, - }); - - const form = useForm({ - resolver: zodResolver(postingFormSchema), - }); - const { fields, append, replace } = useFieldArray({ - control: form.control, - name: "pstg", - }); - - const isFormValid = - fields.length && fields.every((field) => field.pstgPrdSeCd !== ""); - - const isAllSelected = - siteList && selectedRows.length === siteList.content.length; - - const postingPeriod = (siteId: string) => { - const periodCode = Number(rememberPeriodCode[siteId]); - - if (periodCode === 99) return "상시"; - - return `${dayjs().format("YYYY-MM-DD")} ~ ${dayjs() - .add(periodCode, "day") - .format("YYYY-MM-DD")}`; - }; - - const handleOpenChange = (open: boolean) => { - if (open) return true; - replace([]); - setSelectedRows([]); - setRememberPeriodCode({}); - setRememberPeriodDate({}); - }; - - const handleAppendFields = (i: number) => { - const siteId = siteList?.content[i]?.siteId ?? ""; - const newFields = postingTargets.map((target) => ({ - siteId, - pstgTypeCd: postingType, - pstgTrgtNo: target.pstgTrgtNo, - pstgBgngDt: rememberPeriodDate[siteId]?.from ?? "", - pstgEndDt: rememberPeriodDate[siteId]?.to ?? "", - pstgPrdSeCd: rememberPeriodCode[siteId] ?? "", - delYn: "N", - mode: "C", - })); - append(newFields); - }; - - const handleUpdateFields = - (siteId: string) => (obj: Record) => { - const updatedFields = fields.map((field) => - "siteId" in field && field.siteId === siteId - ? { ...field, ...obj } - : field, - ); - replace(updatedFields); - }; - - const handleRemoveFields = (siteId: string) => { - const filteredFields = fields.filter( - (field) => "siteId" in field && field.siteId !== siteId, - ); - replace(filteredFields); - }; - - const handleSelectRow = (i: number) => { - const isSelected = selectedRows.includes(i); - setSelectedRows((prev) => - isSelected ? prev.filter((j) => j !== i) : [...prev, i], - ); - - if (isSelected) { - const siteId = siteList?.content[i]?.siteId; - if (!siteId) return; - handleRemoveFields(siteId); - return; - } - - handleAppendFields(i); - }; - - const handleSelectAll = () => { - if (selectedRows.length === (siteList?.content.length ?? 0)) { - replace([]); - setSelectedRows([]); - } else { - replace([]); - setSelectedRows(siteList?.content.map((_, i) => i) ?? []); - siteList?.content.forEach((_, i) => handleAppendFields(i)); - } - }; - - const handlePeriodCodeChange = (siteId: string) => (value: string) => { - const from = dayjs().format("YYYY-MM-DD 00:00:00"); - const to = dayjs().add(Number(value), "day").format("YYYY-MM-DD 23:59:59"); - - setRememberPeriodCode((prev) => ({ - ...prev, - [siteId]: value, - })); - setRememberPeriodDate((prev) => ({ - ...prev, - [siteId]: { from, to }, - })); - handleUpdateFields(siteId)({ - pstgPrdSeCd: value, - pstgBgngDt: from, - pstgEndDt: to, - }); - }; - - const handlePeriodDateChange = - (siteId: string) => (value: DateRange | undefined) => { - const from = dayjs(value?.from).format("YYYY-MM-DD 00:00:00"); - const to = dayjs(value?.to).format("YYYY-MM-DD 23:59:59"); - setRememberPeriodDate((prev) => ({ - ...prev, - [siteId]: { from, to }, - })); - handleUpdateFields(siteId)({ - pstgBgngDt: from, - pstgEndDt: to, - }); - }; - - const handleSave = async () => { - if (await confirm("저장하시겠습니까?")) { - const data = form.getValues("pstg"); - await savePosting(data); - } - }; - - return ( - - - - - 사이트반영 - - - - - 사이트 반영 - - - - 선택된 {POSTING_TYPE_LABEL[postingType]} - - - {postingTargets.map((target) => ( - - {target.pstgTrgtNm} - - ))} - - - - - - - - - - - - - - - 사이트명 - 게시 구분 - - - - {siteList?.content.map((site, i) => ( - - - handleSelectRow(i)} - /> - - {site.siteNm} - - - - {!!Number(rememberPeriodCode[site.siteId]) && ( - - 게시 기간: {postingPeriod(site.siteId)} - - )} - {Number(rememberPeriodCode[site.siteId]) === 0 && ( - - handlePeriodDateChange(site.siteId)( - date as DateRange | undefined, - ) - } - disabled={!selectedRows.includes(i)} - /> - )} - - - - ))} - - - - - - 저장 - - - - 취소 - - - - - - ); -} - -function PostingPeriodSelect({ - ...props -}: React.ComponentPropsWithoutRef) { - return ; -} - -export { PostingDialog }; diff --git a/apps/common/features/src/entities/site/@x/posting.ts b/apps/common/features/src/entities/site/@x/posting.ts deleted file mode 100644 index 6470b3cb2..000000000 --- a/apps/common/features/src/entities/site/@x/posting.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { SiteApi } from "../api/site-service"; -export type { Site } from "../model/site-interface"; diff --git a/apps/common/features/src/entities/site/api/site-service.ts b/apps/common/features/src/entities/site/api/site-service.ts deleted file mode 100644 index a5d9d7cd6..000000000 --- a/apps/common/features/src/entities/site/api/site-service.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { client } from "@/shared/api"; -import { ENDPOINT } from "@/shared/config"; -import { - siteFormSchema, - type SiteService, - type SiteList, - type SiteDetail, - type SiteParams, - type SiteFormData, -} from "../model/site-interface"; - -export class SiteApiService implements SiteService { - public async getSiteList(params?: SiteParams): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.SITES}`, - { params }, - ); - return response.data; - } - - public async siteDetail(siteId: string): Promise { - const response = await client.get( - `${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, - ); - return response.data; - } - - public async createSite(data: SiteFormData): Promise { - const validatedData = siteFormSchema.parse(data); - const response = await client.post( - `${ENDPOINT.CMS_SERVICE.SITES}`, - validatedData, - ); - return response.data; - } - - public async updateSite(siteId: string, data: SiteFormData): Promise { - const validatedData = siteFormSchema.parse(data); - const response = await client.put( - `${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, - validatedData, - ); - return response.data; - } - - public async deleteSite(siteId: string): Promise { - await client.delete(`${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`); - } -} - -export const SiteApi = new SiteApiService(); diff --git a/apps/common/features/src/entities/site/index.ts b/apps/common/features/src/entities/site/index.ts deleted file mode 100644 index c7b437a64..000000000 --- a/apps/common/features/src/entities/site/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { SiteApi } from "./api/site-service"; -export { - siteFormSchema, - type SiteParams, - type Site, - type SiteFormData, -} from "./model/site-interface"; diff --git a/apps/common/features/src/entities/site/model/site-interface.ts b/apps/common/features/src/entities/site/model/site-interface.ts deleted file mode 100644 index 8846f59b9..000000000 --- a/apps/common/features/src/entities/site/model/site-interface.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { z } from "zod"; -import type { PageableParams, PageableList } from "@/shared/model"; - -export interface SiteParams extends PageableParams { - siteNm?: string; - siteKndCd?: string; - useYn?: string; -} - -export interface Site { - siteId: string; - siteNm: string; - siteKindCode: string; - bscSiteYn: string; - siteAddr: string; - useYn: string; - regDt: string; - rgTrNm: string; - dmnAddr: string; -} - -export interface SiteDetail extends SiteFormData { - siteId: string; - siteKindNm: string; - basicSiteYn: string; - faxNumber: string; - regDt: string; - rgTr: string; - mdfcnDt: string; - mdFr: string; - rgTrNm: string; - mdfrNm: string; -} - -export const siteFormSchema = z.object({ - siteId: z.string().max(2).nonempty(), - siteNm: z.string().max(100).nonempty(), - siteExpln: z.string().max(1000).nullish(), - siteKndCd: z.string().max(10).nonempty(), - siteAddr: z.string().max(2000).nullish(), - faxNo: z.string().max(100).nullish(), - telNo: z.string().max(1000).nullish(), - lwndCn: z.string().max(2000).nullish(), - bscSiteYn: z.string(), - bkmkIcon: z.string().max(100).nullish(), - useYn: z.string(), - siteSkn: z.string().max(10).nullish(), - dmnAddr: z.string().nullish(), -}); - -export type SiteFormData = z.infer; -export type SiteList = PageableList; - -export interface SiteService { - getSiteList(params: SiteParams): Promise; - siteDetail(siteId: string): Promise; - updateSite(siteId: string, data: SiteFormData): Promise; - createSite(data: SiteFormData): Promise; -} diff --git a/apps/common/features/src/pages/auth/login/index.ts b/apps/common/features/src/pages/auth/login/index.ts deleted file mode 100644 index 2093c3d8d..000000000 --- a/apps/common/features/src/pages/auth/login/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { LoginPage } from "./ui/login-page"; diff --git a/apps/common/features/src/pages/auth/login/ui/login-page.tsx b/apps/common/features/src/pages/auth/login/ui/login-page.tsx deleted file mode 100644 index 4700a691b..000000000 --- a/apps/common/features/src/pages/auth/login/ui/login-page.tsx +++ /dev/null @@ -1,129 +0,0 @@ -"use client"; - -import Image from "next/image"; -import { images } from "@common/assets"; -import { LoginApi } from "@/entities/auth"; -import "./login.css"; - -function LoginPage() { - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - - const formData = new FormData(e.target as HTMLFormElement); - const userId = formData.get("id") as string; - const password = formData.get("password") as string; - - await LoginApi.login({ userId, password }); - window.location.href = "/dashboard"; - }; - - return ( - - - - - 하수도정보시스템 - - CMS 통합관리시스템 - - 하수도정보시스템 CMS 통합관리시스템에 오신 것을 환영합니다. - - - - - - - - - - ID - - - - - - - PASSWORD - - - - - - - - - - 아이디저장 - - {/* 비밀번호 또는 아이디를 잃어버리셨나요? */} - - - LOGIN - - - - copyright © 2023 KECO. All rights reserved. - - - - 개인정보처리방침 - - - 저작권정책안내 - - - 이메일무단수집거부 - - - - - 주소 : (22689) 인천광역시 서구 환경로 42(경서동 - 종합환경연구단지) - - - 전화 : (시스템) 032-590-4321, 3752, 4314 / (통 계) 032-590-3723, - 3722 - - 팩스 :032-590-3729 - - - - - - ); -} - -export { LoginPage }; diff --git a/apps/common/features/src/pages/auth/login/ui/login.css b/apps/common/features/src/pages/auth/login/ui/login.css deleted file mode 100755 index 831cc13a9..000000000 --- a/apps/common/features/src/pages/auth/login/ui/login.css +++ /dev/null @@ -1,311 +0,0 @@ -/** -* OLYM Cascading Style Sheets -* File Name : login.css -* Description : 로그인 스타일시트 -* Author : Web business Team / Choi Hyun Mi -* Email : desingtj@olym.co.kr -* Date : 2023.07.20 -* Update : 2023.07.26 -* Copyright(c) 2023 OLYM Communications. All Rights Reserved. -*/ -html, -body { - background: #fff; -} -.fx { - display: flex; - -ms-display: flex; - -webkit-display: flex; - box-sizing: border-box; -} -.login { - width: 100%; - height: 100vh; -} -.login .left_box { - width: 100%; - background: url(../../../../../public/images/bg_login.jpg) no-repeat - center/cover; - flex-direction: column; - justify-content: space-between; - padding: 7% 5% 5% 5%; -} -.login .left_box .text h1 { - font-size: 53px; - color: #fff; -} -.login .left_box .text h1 span { - font-weight: 800; -} -.login .left_box .text p { - margin-top: 40px; - font-size: 18px; - color: #fff; -} -.login .login_box { - width: 100%; - flex-direction: column; - justify-content: center; - padding: 4% 12% 4% 6%; -} -.login .login_box > ul { - flex-direction: column; - gap: 40px; -} -.login .login_box > ul > li h2 { - font-size: 22px; - font-weight: 600; - color: #2640a5; - margin-bottom: 14px; -} -.login .login_box > ul > li .input_st { - position: relative; -} -.login .login_box > ul > li .input_st .diveicon { - position: absolute; - top: 50%; - left: 28px; - transform: translateY(-50%); - font-family: "Xeicon"; - font-size: 25px; - color: #003288; -} -.login .login_box > ul > li input { - width: 100%; - padding: 20px 20px 20px 70px; - background: #f7f7f7; - box-sizing: border-box; - border: none; - border-radius: 5px; - font-size: 18px; - font-weight: 700; - color: #000; - height: auto; -} -.login .login_box > ul > li input:focus { - outline: 1px solid #3c5fe5; -} -.login .login_box > ul > li input::placeholder { - color: #afabab; - font-weight: 500; -} -.login .login_box .bottom_box { - justify-content: space-between; - gap: 20px; - padding: 50px 0 45px 0; -} -.login .login_box .bottom_box .checks { - display: flex; - align-items: center; - gap: 8px; -} -.login .login_box .bottom_box .checks input[type="checkbox"] { - width: 18px; - height: 18px; -} -.login .login_box .bottom_box .checks label { - font-size: 14px; -} -.login .login_box .bottom_box .pw_message { - align-items: center; - gap: 5px; - color: #636363; - font-weight: 500; - border-bottom: 1px solid #ccc; - padding-bottom: 5px; -} -.login .login_box .bottom_box .pw_message i { - color: #327af5; - font-size: 20px; -} -.login .login_box .login_btn { - position: relative; - border-radius: 5px; - padding: 24px 15px; - background: linear-gradient( - to left, - #1d3969 0%, - #264078 10%, - #172558 40%, - #162254 50%, - #111c43 60%, - #111c42 100% - ); - overflow: hidden; - justify-content: center; - align-items: center; - gap: 10px; - color: #fff; - cursor: pointer; -} -.login .login_box .login_btn span { - font-family: "Montserrat"; - font-size: 19px; - font-weight: 700; - position: relative; -} -.login .login_box .login_btn i { - font-size: 22px; - transform: translateY(-2px); -} -.login .login_box .login_btn:before { - display: block; - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - opacity: 0; - background: linear-gradient( - to right, - #1d3969 0%, - #264078 10%, - #172558 40%, - #162254 50%, - #111c43 60%, - #111c42 100% - ); - transition: opacity 0.5s; -} -.login .login_box .login_btn:hover::before { - opacity: 1; -} -.login .footer .copy { - margin-top: 36px; - justify-content: space-between; - align-items: center; - gap: 3%; -} -.login .footer .copy p { - font-size: 13px; - color: #d4d4d4; - width: 44%; - text-align: center; -} -.login .footer .copy::before, -.login .login_box .copy::after { - content: ""; - width: 20%; - height: 1px; - background: #d4d4d4; -} -.login .footer .fot_btn { - gap: 20px; - margin: 30px 0 10px 0; -} -.login .footer .fot_btn a { - color: #333; - font-weight: 700; - font-size: 13px; -} -.login .footer .fot_btn a:hover { - color: #003288; -} -.login .footer .addr { - color: #666; - font-size: 13px; - gap: 3px 20px; - flex-wrap: wrap; -} -/* 비밀번호 변경 팝업창 */ -.login .modal .modal_container { - width: 750px; -} -.login .pw_desc { - padding: 10px 10px 30px 10px; - color: #666; -} -.login .pw_desc p { - font-size: 1.25rem; - color: #000; - font-weight: 700; - margin-bottom: 10px; -} -.login .pw_desc span { - color: #f60; - font-weight: 700; -} -.login .modal .form_write { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - padding: 20px 50px; -} -@media (max-width: 1024px) { - .login { - flex-direction: column; - height: auto; - } - .login .left_box { - padding: 30px; - flex-direction: column-reverse; - gap: 20px; - } - .login .left_box .text h1 { - font-size: 30px; - line-height: 1.2em; - } - .login .left_box .text p { - margin-top: 20px; - font-size: 14px; - } - .login .left_box .img img { - height: 40px; - } - .login .login_box { - padding: 30px; - } - .login .login_box > ul { - gap: 20px; - } - .login .login_box > ul > li h2 { - margin-bottom: 7px; - } - .login .login_box > ul > li .input_st::after { - left: 15px; - font-size: 20px; - } - .login .login_box > ul > li input { - padding: 15px 10px 15px 50px; - font-size: 16px; - } - .login .login_box .bottom_box { - flex-direction: column; - align-items: flex-start; - padding: 30px 0; - } - .login .login_box .bottom_box .id_save label { - font-size: 14px; - } - .login .login_box .login_btn { - padding: 15px; - } - .login .login_box .login_btn span { - font-size: 16px; - } - .login .login_box .login_btn i { - font-size: 18px; - transform: translateY(-1px); - } - .login .login_box .copy p { - width: 100%; - } - .login .login_box .copy::before, - .login .login_box .copy::after { - display: none; - } - .login .footer .addr { - font-size: 11px; - gap: 3px 10px; - } - .login .modal .modal_container { - width: 90%; - } - .login .pw_desc { - padding: 0 0 20px 0; - } - .login .modal .form_write { - padding: 10px; - } -} -/* // login */ diff --git a/apps/common/features/src/pages/board/index.ts b/apps/common/features/src/pages/board/index.ts deleted file mode 100644 index 483a2f96b..000000000 --- a/apps/common/features/src/pages/board/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { BoardPage } from "./ui/board-page"; diff --git a/apps/common/features/src/pages/board/ui/board-page.tsx b/apps/common/features/src/pages/board/ui/board-page.tsx deleted file mode 100644 index 15960674e..000000000 --- a/apps/common/features/src/pages/board/ui/board-page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -function BoardPage() { - return 게시판 관리; -} - -export { BoardPage }; diff --git a/apps/common/features/src/shared/api/client.ts b/apps/common/features/src/shared/api/client.ts deleted file mode 100644 index 709bb44a5..000000000 --- a/apps/common/features/src/shared/api/client.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Client } from "@common/network"; -import { BASE_URL } from "../config/api"; -import { SITE_ID } from "../config/env"; - -export const client = Client.getInstance({ - baseURL: BASE_URL, - siteId: SITE_ID, -}); diff --git a/apps/common/features/src/shared/api/index.ts b/apps/common/features/src/shared/api/index.ts deleted file mode 100644 index b7b9d6121..000000000 --- a/apps/common/features/src/shared/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { client } from "./client"; diff --git a/apps/common/features/src/shared/config/api.ts b/apps/common/features/src/shared/config/api.ts deleted file mode 100644 index 94d2e728d..000000000 --- a/apps/common/features/src/shared/config/api.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { PROXY_HOST } from "./env"; - -export const BASE_URL = `${PROXY_HOST}/server`; - -export const ENDPOINT = { - ATTACH_SERVICE: { - TUS_UPLOAD: "/attach-service/api/v1/tus/upload", - EDITOR_UPLOAD: "/attach-service/api/v1/upload/editor", - IMAGES: "/attach-service/api/v1/images", - ATTACHMENTS: "/attach-service/api/v1/atfl/attachments", - }, - USER_SERVICE: { - LOGIN: "/user-service/login", - USERS: "/user-service/api/v1/users", - SILENT_REFRESH: "/user-service/api/v1/users/token/refresh", - AUTHRTS: "/user-service/api/v1/authorizations", - ROLES_AUTHRTS: "/user-service/api/v1/role-authorizations", - }, - CMS_SERVICE: { - SITES: "/cms-service/api/v1/sites", - IPS: "/cms-service/api/v1/site-ips", - DOMAINS: "/cms-service/api/v1/site-dmns", - POSTINGS: "/cms-service/api/v1/site-pstgs", - CODE: "/cms-service/api/v1/code/cache", - MENUS: "/cms-service/api/v1/menus", - MENU_ROLES: "/cms-service/api/v1/menu-roles", - MENU_AUTHRTS: "/cms-service/api/v1/menu-authrts", - CONTENTS: "/cms-service/api/v1/contents", - USER_ORGANIZATION: "/cms-service/api/v1/user-ognz", - IMAGES: "/cms-service/api/v1/images", - BANNERS: "/cms-service/api/v1/bnrs", - TEMPLATE: "/cms-service/api/v1/tmplt", - TERMS: "/cms-service/api/v1/trms", - }, - BOARD_SERVICE: { - BBS: "/board-service/api/v1/bbs", - }, -}; - -export const JWT_EXPIRATION_TIME = 1800000; diff --git a/apps/common/features/src/shared/config/env.ts b/apps/common/features/src/shared/config/env.ts deleted file mode 100644 index f0b4c83b1..000000000 --- a/apps/common/features/src/shared/config/env.ts +++ /dev/null @@ -1,13 +0,0 @@ -export const PORT = process.env.NEXT_PUBLIC_PORT || "3000"; -export const PROXY_HOST = - process.env.NEXT_PUBLIC_PROXY_HOST || `http://localhost:${PORT}`; - -export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL; -export const SITE_ID = process.env.NEXT_PUBLIC_SITE_ID || "CS"; - -export const CLAIM_NAME = process.env.NEXT_PUBLIC_CLAIM_NAME || "Authorization"; -export const ACCESS_TOKEN = - process.env.NEXT_PUBLIC_ACCESS_TOKEN || "access-token"; -export const REFRESH_TOKEN = - process.env.NEXT_PUBLIC_REFRESH_TOKEN || "refresh-token"; -export const AUTH_USER_ID = process.env.NEXT_PUBLIC_AUTH_USER_ID || "token-id"; diff --git a/apps/common/features/src/shared/config/index.ts b/apps/common/features/src/shared/config/index.ts deleted file mode 100644 index cd83447d5..000000000 --- a/apps/common/features/src/shared/config/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./api"; -export * from "./env"; diff --git a/apps/common/features/src/shared/lib/cookie.ts b/apps/common/features/src/shared/lib/cookie.ts deleted file mode 100644 index 8f5d0011b..000000000 --- a/apps/common/features/src/shared/lib/cookie.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Cookies from "js-cookie"; - -export function getCookie(name: string): string | undefined { - if (typeof window === "undefined") { - return undefined; - } - return Cookies.get(name); -} - -export function setCookie( - name: string, - value: string, - options?: Cookies.CookieAttributes, -): void { - if (typeof window === "undefined") { - return; - } - Cookies.set(name, value, options); -} - -export function removeCookie( - name: string, - options?: Cookies.CookieAttributes, -): void { - if (typeof window === "undefined") { - return; - } - Cookies.remove(name, options); -} diff --git a/apps/common/features/src/shared/lib/index.ts b/apps/common/features/src/shared/lib/index.ts deleted file mode 100644 index bfbe51702..000000000 --- a/apps/common/features/src/shared/lib/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { getCookie, setCookie, removeCookie } from "./cookie"; -export { useMenuStore } from "./use-menu-store"; -export { useUserStore } from "./use-user-store"; diff --git a/apps/common/features/src/shared/lib/use-alert-store.ts b/apps/common/features/src/shared/lib/use-alert-store.ts deleted file mode 100644 index c21a00ed3..000000000 --- a/apps/common/features/src/shared/lib/use-alert-store.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useStore } from "zustand"; -import { useContext } from "react"; -import type { AlertStore } from "../store/alert-store"; -import { StoreContext } from "../providers/store-provider"; - -export const useAlertStore = (selector: (store: AlertStore) => T): T => { - const storeContext = useContext(StoreContext); - - if (!storeContext) { - throw new Error("useAlertStore must be used within StoreProvider"); - } - - return useStore(storeContext.alertStore, selector); -}; diff --git a/apps/common/features/src/shared/lib/use-attachment-store.ts b/apps/common/features/src/shared/lib/use-attachment-store.ts deleted file mode 100644 index 285699cc6..000000000 --- a/apps/common/features/src/shared/lib/use-attachment-store.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useStore } from "zustand"; -import { useContext } from "react"; -import type { AttachmentStore } from "../store/attachment-store"; -import { StoreContext } from "../providers/store-provider"; - -export const useAttachmentStore = ( - selector: (store: AttachmentStore) => T, -): T => { - const store = useContext(StoreContext); - if (!store) { - throw new Error("useAttachmentStore must be used within StoreProvider"); - } - return useStore(store.attachmentStore, selector); -}; diff --git a/apps/common/features/src/shared/lib/use-menu-store.ts b/apps/common/features/src/shared/lib/use-menu-store.ts deleted file mode 100644 index 66e41c76c..000000000 --- a/apps/common/features/src/shared/lib/use-menu-store.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useStore } from "zustand"; -import { useContext } from "react"; -import type { MenuStore } from "../store/menu-store"; -import { StoreContext } from "../providers/store-provider"; - -export const useMenuStore = (selector: (store: MenuStore) => T): T => { - const storeContext = useContext(StoreContext); - - if (!storeContext) { - throw new Error("useMenuStore must be used within StoreProvider"); - } - - return useStore(storeContext.menuStore, selector); -}; diff --git a/apps/common/features/src/shared/lib/use-tus.ts b/apps/common/features/src/shared/lib/use-tus.ts deleted file mode 100644 index fdaeb1f65..000000000 --- a/apps/common/features/src/shared/lib/use-tus.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { useEffect, useState } from "react"; -import { type HttpResponse, Upload } from "tus-js-client"; -import { AUTH_USER_ID, CLAIM_NAME, ENDPOINT } from "../config"; -import { useAttachmentStore } from "./use-attachment-store"; -import { getCookie } from "./cookie"; - -export const useTus = () => { - const { attachmentFileCode, setAttachmentFileCode } = useAttachmentStore( - (state) => state, - ); - - const [file, setFile] = useState(null); - const [upload, setUpload] = useState(null); - const [response, setResponse] = useState(null); - const [progress, setProgress] = useState(0); - - const metadata = { - filename: file?.name ?? "", - filetype: file?.type ?? "", - atflCd: attachmentFileCode, - }; - - const createUpload = () => { - return new Upload(file!, { - endpoint: `${ENDPOINT.ATTACH_SERVICE.TUS_UPLOAD}`, - chunkSize: 10 * 1024 * 1024, - headers: { - [CLAIM_NAME]: getCookie(CLAIM_NAME) ?? "", - [AUTH_USER_ID]: getCookie(AUTH_USER_ID) ?? "", - }, - metadata, - onError(error) { - throw new Error(`Failed because: ${error}`); - }, - onProgress(bytesUploaded, bytesTotal) { - const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2); - setProgress(Number(percentage)); - }, - onAfterResponse(req, res) { - const fileInfo = res.getHeader("X-File-Info"); - if (fileInfo === undefined || fileInfo === null) return; - - setAttachmentFileCode(JSON.parse(fileInfo)?.atflCd ?? ""); - setResponse(res); - }, - }); - }; - - useEffect(() => { - if (!file) return; - - const upload = createUpload(); - upload.start(); - setUpload(upload); - }, [file]); - - return { - file, - upload, - response, - progress, - setFile, - }; -}; diff --git a/apps/common/features/src/shared/lib/use-user-store.ts b/apps/common/features/src/shared/lib/use-user-store.ts deleted file mode 100644 index 748caed4c..000000000 --- a/apps/common/features/src/shared/lib/use-user-store.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { useStore } from "zustand"; -import { useContext } from "react"; -import type { UserStore } from "../store/user-store"; -import { StoreContext } from "../providers/store-provider"; - -export const useUserStore = (selector: (store: UserStore) => T): T => { - const storeContext = useContext(StoreContext); - - if (!storeContext) { - throw new Error("useUserStore must be used within StoreProvider"); - } - - return useStore(storeContext.userStore, selector); -}; diff --git a/apps/common/features/src/shared/model/api-interface.ts b/apps/common/features/src/shared/model/api-interface.ts deleted file mode 100644 index 133c0c401..000000000 --- a/apps/common/features/src/shared/model/api-interface.ts +++ /dev/null @@ -1,34 +0,0 @@ -interface SortConfig { - empty: boolean; - sorted: boolean; - unsorted: boolean; -} - -interface PageableConfig { - sort: SortConfig; - offset: number; - pageNumber: number; - pageSize: number; - paged: boolean; - unpaged: boolean; -} - -export interface PageableList { - content: T[]; - pageable: PageableConfig; - sort: SortConfig; - totalPages: number; - totalElements: number; - number: number; - numberOfElements: number; - size: number; - first: boolean; - last: boolean; - empty: boolean; -} - -export interface PageableParams { - page?: number; - size?: number; - sort?: string[]; -} diff --git a/apps/common/features/src/shared/model/index.ts b/apps/common/features/src/shared/model/index.ts deleted file mode 100644 index cf589d200..000000000 --- a/apps/common/features/src/shared/model/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./api-interface"; diff --git a/apps/common/features/src/shared/providers/index.ts b/apps/common/features/src/shared/providers/index.ts deleted file mode 100644 index f2e092170..000000000 --- a/apps/common/features/src/shared/providers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { StoreProvider } from "./store-provider"; diff --git a/apps/common/features/src/shared/providers/store-provider.tsx b/apps/common/features/src/shared/providers/store-provider.tsx deleted file mode 100644 index a0ec17b61..000000000 --- a/apps/common/features/src/shared/providers/store-provider.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client"; - -import { createContext, useRef } from "react"; -import { - createAlertStore, - createAttachmentStore, - createMenuStore, - createUserStore, -} from "../store"; - -type StoreContextType = { - alertStore: ReturnType; - attachmentStore: ReturnType; - menuStore: ReturnType; - userStore: ReturnType; -}; - -export const StoreContext = createContext( - undefined, -); - -export const StoreProvider = ({ children }: { children: React.ReactNode }) => { - const storeRef = useRef(null); - if (storeRef.current === null) { - storeRef.current = { - alertStore: createAlertStore(), - attachmentStore: createAttachmentStore(), - menuStore: createMenuStore(), - userStore: createUserStore(), - }; - } - - return ( - - {children} - - ); -}; diff --git a/apps/common/features/src/shared/store/alert-store.ts b/apps/common/features/src/shared/store/alert-store.ts deleted file mode 100644 index 3bba65848..000000000 --- a/apps/common/features/src/shared/store/alert-store.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createStore } from "zustand/vanilla"; - -export type AlertState = { - message: string; - callback?: () => void; -}; - -export type AlertActions = { - setMessage: (message: string, callback?: () => void) => void; -}; - -export type AlertStore = AlertState & AlertActions; - -export const defaultInitState: AlertState = { - message: "", - callback: undefined, -}; - -export const createAlertStore = (initState: AlertState = defaultInitState) => { - return createStore()((set) => ({ - ...initState, - setMessage: (message: string, callback?: () => void) => - set(() => ({ message, callback })), - })); -}; diff --git a/apps/common/features/src/shared/store/attachment-store.ts b/apps/common/features/src/shared/store/attachment-store.ts deleted file mode 100644 index faa700949..000000000 --- a/apps/common/features/src/shared/store/attachment-store.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createStore } from "zustand/vanilla"; - -export type AttachmentState = { - attachmentFileCode: string; -}; - -export type AttachmentActions = { - setAttachmentFileCode: (attachmentFileCode: string) => void; -}; - -export type AttachmentStore = AttachmentState & AttachmentActions; - -export const defaultInitState: AttachmentState = { - attachmentFileCode: "", -}; - -export const createAttachmentStore = ( - initState: AttachmentState = defaultInitState, -) => { - return createStore()((set) => ({ - ...initState, - setAttachmentFileCode: (attachmentFileCode: string) => - set({ attachmentFileCode }), - })); -}; diff --git a/apps/common/features/src/shared/store/index.ts b/apps/common/features/src/shared/store/index.ts deleted file mode 100644 index e26f6781e..000000000 --- a/apps/common/features/src/shared/store/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { createAlertStore } from "./alert-store"; -export { createAttachmentStore } from "./attachment-store"; -export { createMenuStore } from "./menu-store"; -export { createUserStore, type IUserInfo } from "./user-store"; diff --git a/apps/common/features/src/shared/store/menu-store.ts b/apps/common/features/src/shared/store/menu-store.ts deleted file mode 100644 index f0c6340c9..000000000 --- a/apps/common/features/src/shared/store/menu-store.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createStore } from "zustand/vanilla"; -import type { MenuItem } from "@common/components/api"; - -export type MenuState = { - currentMenuInfo: MenuItem | null; -}; - -export type MenuActions = { - setCurrentMenuInfo: (menu: MenuItem) => void; -}; - -export type MenuStore = MenuState & MenuActions; - -export const defaultInitState: MenuState = { - currentMenuInfo: null, -}; - -export const createMenuStore = (initState: MenuState = defaultInitState) => { - return createStore()((set) => ({ - ...initState, - setCurrentMenuInfo: (menu: MenuItem) => set({ currentMenuInfo: menu }), - })); -}; diff --git a/apps/common/features/src/shared/store/user-store.ts b/apps/common/features/src/shared/store/user-store.ts deleted file mode 100644 index 00379fb1f..000000000 --- a/apps/common/features/src/shared/store/user-store.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { createStore } from "zustand/vanilla"; - -export interface IUserInfo { - regDt: string; - mdfcnDt: string; - rgtr: string; - mdfr: string; - userUnqId: string; - userId: string; - userName: string; - email: string; - encryptedPassword: string; - refreshToken: string; - userStateCode: string; - lastLoginDate: string; - loginFailCount: number; - pswdHnt: string; - pswdAns: string; - mphn: string; - telno: string; - zip: string; - addr: string; - daddr: string; - laeSeCd: string; - ogdpSeCd: string; - aprvYn: string; - autzrId: string; - expryYmd: string; - lastPswdChgDt: string; - googleId: string; - kakaoId: string; - naverId: string; - isSocialUser: boolean; - hasPassword: boolean; -} - -export type UserState = { - userInfo: IUserInfo | null; -}; - -export type UserActions = { - setUserInfo: (userInfo: IUserInfo | null) => void; -}; - -export type UserStore = UserState & UserActions; - -export const defaultInitState: UserState = { - userInfo: null, -}; - -export const createUserStore = (initState: UserState = defaultInitState) => { - return createStore()((set) => ({ - ...initState, - setUserInfo: (userInfo: IUserInfo | null) => set(() => ({ userInfo })), - })); -}; diff --git a/apps/common/features/src/shared/ui/alert-dialog.tsx b/apps/common/features/src/shared/ui/alert-dialog.tsx deleted file mode 100644 index 728276713..000000000 --- a/apps/common/features/src/shared/ui/alert-dialog.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { - Dialog, - DialogContent, - DialogFooter, - DialogClose, - Button, -} from "@common/components/ui"; -import { useAlertStore } from "../lib/use-alert-store"; - -function AlertDialog() { - const { message, callback, setMessage } = useAlertStore((state) => state); - const handleOpenChange = () => { - setMessage(""); - callback?.(); - }; - return ( - - - - {message} - - - - 확인 - - - - - ); -} - -export { AlertDialog }; diff --git a/apps/common/features/src/shared/ui/confirm-dialog.tsx b/apps/common/features/src/shared/ui/confirm-dialog.tsx deleted file mode 100644 index 4223d197e..000000000 --- a/apps/common/features/src/shared/ui/confirm-dialog.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { - Dialog, - DialogContent, - DialogFooter, - DialogClose, - Button, - type ButtonProps, -} from "@common/components/ui"; - -type ConfirmDialogProps = { - open?: boolean; - confirmButtonProps?: ButtonProps & { label?: string }; - cancelButtonProps?: ButtonProps & { label?: string }; -}; - -function ConfirmDialog({ - open, - confirmButtonProps, - cancelButtonProps, -}: ConfirmDialogProps) { - const { message, isOpen, onConfirm, onCancel } = useConfirm(); - return ( - - - - {message} - - - - - {confirmButtonProps?.label ?? "확인"} - - - - - {cancelButtonProps?.label ?? "취소"} - - - - - - ); -} - -export { ConfirmDialog }; diff --git a/apps/common/features/src/shared/ui/form.tsx b/apps/common/features/src/shared/ui/form.tsx deleted file mode 100644 index bd579d263..000000000 --- a/apps/common/features/src/shared/ui/form.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import * as React from "react"; -import * as LabelPrimitive from "@radix-ui/react-label"; -import { Slot } from "@radix-ui/react-slot"; -import { - Controller, - FormProvider, - useFormContext, - type ControllerProps, - type FieldPath, - type FieldValues, -} from "react-hook-form"; -import { cn, Label } from "@common/components"; - -const Form = FormProvider; - -type FormFieldContextValue< - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath, -> = { - name: TName; -}; - -const FormFieldContext = React.createContext( - {} as FormFieldContextValue, -); - -const FormField = < - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath, ->({ - ...props -}: ControllerProps) => { - return ( - - - - ); -}; - -const useFormField = () => { - const fieldContext = React.useContext(FormFieldContext); - const itemContext = React.useContext(FormItemContext); - const { getFieldState, formState } = useFormContext(); - - const fieldState = getFieldState(fieldContext.name, formState); - - if (!fieldContext) { - throw new Error("useFormField should be used within "); - } - - const { id } = itemContext; - - return { - id, - name: fieldContext.name, - formItemId: `${id}-form-item`, - formDescriptionId: `${id}-form-item-description`, - formMessageId: `${id}-form-item-message`, - ...fieldState, - }; -}; - -type FormItemContextValue = { - id: string; -}; - -const FormItemContext = React.createContext( - {} as FormItemContextValue, -); - -const FormItem = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const id = React.useId(); - - return ( - - - - ); -}); -FormItem.displayName = "FormItem"; - -const FormLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => { - const { error, formItemId } = useFormField(); - - return ( - - ); -}); -FormLabel.displayName = "FormLabel"; - -const FormControl = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ ...props }, ref) => { - const { error, formItemId, formDescriptionId, formMessageId } = - useFormField(); - - return ( - - ); -}); -FormControl.displayName = "FormControl"; - -const FormDescription = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const { formDescriptionId } = useFormField(); - - return ( - - ); -}); -FormDescription.displayName = "FormDescription"; - -const FormMessage = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, children, ...props }, ref) => { - const { error, formMessageId } = useFormField(); - const body = error ? String(error?.message ?? "") : children; - - if (!body) { - return null; - } - - return ( - - {body} - - ); -}); -FormMessage.displayName = "FormMessage"; - -export { - useFormField, - Form, - FormItem, - FormLabel, - FormControl, - FormDescription, - FormMessage, - FormField, -}; diff --git a/apps/common/features/src/shared/ui/page-layout.tsx b/apps/common/features/src/shared/ui/page-layout.tsx deleted file mode 100644 index 17100389a..000000000 --- a/apps/common/features/src/shared/ui/page-layout.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { PageTitle } from "@common/components"; -import { useMenuStore } from "../lib/use-menu-store"; - -function PageLayout({ children }: { children: React.ReactNode }) { - const { currentMenuInfo } = useMenuStore((state) => state); - - const menuPaths = currentMenuInfo?.menuPath - ?.split(">") - .map((path) => path.trim()); - - return ( - - - {children} - - ); -} - -export { PageLayout }; diff --git a/apps/common/features/src/shared/ui/skeleton-page.tsx b/apps/common/features/src/shared/ui/skeleton-page.tsx deleted file mode 100644 index fca5c8e76..000000000 --- a/apps/common/features/src/shared/ui/skeleton-page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Skeleton } from "@common/components/ui/skeleton"; - -function SkeletonPage() { - return ( - - - - - ); -} - -export { SkeletonPage }; diff --git a/apps/common/features/src/widgets/form-wrapper/index.ts b/apps/common/features/src/widgets/form-wrapper/index.ts deleted file mode 100644 index aa5addaf9..000000000 --- a/apps/common/features/src/widgets/form-wrapper/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { FormWrapper } from "./ui/form-wrapper"; diff --git a/apps/common/features/src/widgets/form-wrapper/ui/form-wrapper.tsx b/apps/common/features/src/widgets/form-wrapper/ui/form-wrapper.tsx deleted file mode 100644 index 19f941106..000000000 --- a/apps/common/features/src/widgets/form-wrapper/ui/form-wrapper.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { useRouter } from "next/navigation"; -import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { type FieldValues, type UseFormReturn } from "react-hook-form"; -import { Button } from "@common/components/ui"; -import { Form } from "@/shared/ui/form"; - -type FormWrapperProps = { - form: UseFormReturn; - children: React.ReactNode; - isModifyMode?: boolean; - handleSave: (data: T) => Promise; - handleDelete?: () => Promise; -}; - -function FormWrapper({ - form, - children, - isModifyMode, - handleSave, - handleDelete, -}: FormWrapperProps) { - const router = useRouter(); - const { confirm } = useConfirm(); - - const onSubmit = async (data: T) => { - const confirmMessage = isModifyMode - ? "수정하시겠습니까?" - : "저장하시겠습니까?"; - - if (await confirm(confirmMessage)) { - await handleSave(data); - } - }; - - const onDelete = async () => { - if (await confirm("삭제하시겠습니까?")) { - await handleDelete?.(); - } - }; - - return ( - - - {children} - - router.back()} - > - 목록 - - - 저장 - - {isModifyMode && ( - - 삭제 - - )} - - - - ); -} - -export { FormWrapper }; diff --git a/apps/common/features/tailwind.config.ts b/apps/common/features/tailwind.config.ts deleted file mode 100644 index 5f9a2750d..000000000 --- a/apps/common/features/tailwind.config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Config } from "tailwindcss"; -import tailwindcssAnimate from "tailwindcss-animate"; -import presetConfig from "../../../tailwind.config.preset"; - -export default { - presets: [presetConfig], - content: [ - "./src/**/*.{js,ts,jsx,tsx,mdx}", - "../../../packages/common/components/src/ui/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - boxShadow: { - blur: "0 0 10px -1px rgba(0, 0, 0, 0.06)", - }, - }, - }, - plugins: [tailwindcssAnimate], -} satisfies Config; diff --git a/apps/common/features/tsconfig.json b/apps/common/features/tsconfig.json deleted file mode 100644 index 60991f388..000000000 --- a/apps/common/features/tsconfig.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "target": "ES2017", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "verbatimModuleSyntax": true, - "strictNullChecks": true, - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "baseUrl": "./src", - "paths": { - "@/*": ["./*"], - "@common/components/*": ["../../../../packages/common/components/src/*"], - "@common/components": ["../../../../packages/common/components/src"], - "@common/network/*": ["../../../../packages/common/network/*"], - "@common/network": ["../../../../packages/common/network/"] - } - }, - "include": [ - ".eslintrc.*", - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - "**/*.mts", - "**/*.js", - "**/*.cjs", - "**/*.mjs", - "**/*.jsx", - "**/*.json", - ".next/types/**/*.ts" - ], - "exclude": ["**/node_modules", "**/.*/*"] -}
하수도정보시스템 CMS 통합관리시스템에 오신 것을 환영합니다.
copyright © 2023 KECO. All rights reserved.
- - 주소 : (22689) 인천광역시 서구 환경로 42(경서동 - 종합환경연구단지) - - - 전화 : (시스템) 032-590-4321, 3752, 4314 / (통 계) 032-590-3723, - 3722 - - 팩스 :032-590-3729 -
{message}
- {body} -