diff --git a/apps/dm_new/app/(with-layout)/apply/place/page.tsx b/apps/dm_new/app/(with-layout)/apply/dmdco/page.tsx
similarity index 99%
rename from apps/dm_new/app/(with-layout)/apply/place/page.tsx
rename to apps/dm_new/app/(with-layout)/apply/dmdco/page.tsx
index 4e13f3449..2bbfa6694 100644
--- a/apps/dm_new/app/(with-layout)/apply/place/page.tsx
+++ b/apps/dm_new/app/(with-layout)/apply/dmdco/page.tsx
@@ -1,4 +1,4 @@
-// apps/dm/app/(landing)/reuse/apply/place/page.tsx
+// app/apply/dmdco/page.tsx
"use client";
import { useMemo, useState } from "react";
diff --git a/apps/dm_new/app/(with-layout)/example/globalCase/overview/page.tsx b/apps/dm_new/app/(with-layout)/example/globalCase/overview/page.tsx
new file mode 100644
index 000000000..4058d71db
--- /dev/null
+++ b/apps/dm_new/app/(with-layout)/example/globalCase/overview/page.tsx
@@ -0,0 +1,229 @@
+// apps/dm/app/(landing)/reuse/business/globalCase/overview/page.tsx
+"use client";
+
+import SubPageHeader from "@/components/SubPageHeader";
+import CaseImageSlider from "@/components/CaseImageSlider";
+
+function SectionTitle({ children }: { children: React.ReactNode }) {
+ return (
+
+
+
{children}
+
+ );
+}
+
+type HrProps = {
+ className?: string;
+};
+
+function Hr({ className = "" }: HrProps) {
+ return
;
+}
+
+type ImgCardProps = {
+ src: string;
+ alt: string;
+};
+
+function ImgCard({ src, alt }: ImgCardProps) {
+ return (
+
+
+
+ );
+}
+
+export default function GreywaterPage() {
+ return (
+
+
+
+
+
+ {/* 슬라이드 이미지 영역 */}
+
+
+
+
+
+ 2024년 하수도 통계 기준 15.6%이며,
+ 제2차 물 재이용 기본 계획을 고려한 2030년 목표는 17%
+
+
+ {/* 진행 바 영역 */}
+
+ {/* 2024 */}
+
+
+ {/* 2030 */}
+
+
+
+
+ {/* 설명 문구 */}
+
+
+ • 우리나라의 하수 처리 재이용률은 15% 수준
+
+
+ • 대만은 가뭄과 공업용수 증가에 대응하여
+
+ {" "}현재 4.3% 수준이며, 16.5%까지 확대 계획 수립
+
+
+
+
+ {/* 테이블 */}
+
+
+
+
+ 국가
+ 해외정보
+ 현재
+ 미래(목표, 예측치)
+
+
+
+
+ 한국
+ 12.1%
+ 15.6%
+ 17%
+
+
+ 대만
+ 2.4%
+ 4.3%
+ 16.5%
+
+
+
+
+
+
+
+
+ {/* 주요 국가의 하수처리수 재이용률 (%) */}
+
+ 주요 국가의 하수처리수 재이용률 (%)
+ {/* 설명 문구 */}
+
+
+ • 전 세계적으로 물 재이용은 호주, 유럽, 아프리카, 미국 등 가뭄이 잦거나 심각한 가뭄이 발생한 국가에서 많이 이루어짐
+
+
+ • 이스라엘, 쿠웨이트 등 중동 및 북아프리카 지역은 가용 수자원이 제한되어 있어 재이용량 비중도 매우 높은 편
+
+
+ {/* 테이블 (2단 병렬: 좌/우 데이터) */}
+
+
+
+
+
+ {/* 좌측 3컬럼 */}
+ 국가명
+ 지역
+ 재이용률
+
+ {/* 우측 3컬럼 */}
+ 국가명
+ 지역
+ 재이용률
+
+
+
+
+ {[
+ {
+ L: { c: "이스라엘", r: "중동&북아프리카", v: "92.3" },
+ R: { c: "튀르키예", r: "동유럽&중앙아시아", v: "26.6" },
+ },
+ {
+ L: { c: "쿠웨이트", r: "중동&북아프리카", v: "89.3" },
+ R: { c: "독일", r: "서유럽", v: "25.0" },
+ },
+ {
+ L: { c: "호주", r: "동아시아&태평양", v: "49.0" },
+ R: { c: "스페인", r: "서유럽", v: "24.4" },
+ },
+ {
+ L: { c: "싱가포르", r: "동아시아&태평양", v: "44.4" },
+ R: { c: "한국", r: "동아시아&태평양", v: "12.1" },
+ },
+ {
+ L: { c: "그리스", r: "서유럽", v: "39.1" },
+ R: { c: "미국", r: "북아메리카", v: "13.1" },
+ },
+ {
+ L: { c: "사우디아라비아", r: "중동&북아프리카", v: "32.8" },
+ R: { c: "프랑스", r: "서유럽", v: "9.5" },
+ },
+ {
+ L: { c: "이탈리아", r: "서유럽", v: "31.7" },
+ R: { c: "대만", r: "동아시아&태평양", v: "2.4" },
+ },
+ {
+ L: { c: "룩셈부르크", r: "서유럽", v: "29.1" },
+ R: { c: "일본", r: "동아시아&태평양", v: "0.8" },
+ },
+ {
+ L: { c: "포르투갈", r: "서유럽", v: "29.0" },
+ R: { c: "", r: "", v: "" }, // 마지막 우측은 빈칸(이미지처럼)
+ },
+ ].map((row, idx) => (
+
+ {/* 좌측 */}
+ {row.L.c}
+ {row.L.r}
+ {row.L.v}
+
+ {/* 우측 */}
+ {row.R.c}
+ {row.R.r}
+ {row.R.v}
+
+ ))}
+
+
+
+
+
+
+ );
+}
diff --git a/apps/dm_new/app/(with-layout)/example/sewage/guri/page.tsx b/apps/dm_new/app/(with-layout)/example/sewage/guri/page.tsx
index 46796d714..2031bbed9 100644
--- a/apps/dm_new/app/(with-layout)/example/sewage/guri/page.tsx
+++ b/apps/dm_new/app/(with-layout)/example/sewage/guri/page.tsx
@@ -42,12 +42,12 @@ export default function GreywaterPage() {
return (
@@ -69,7 +70,7 @@ export default function GreywaterPage() {
사업명
- 수원시 황수원시 황구지천 하수처리수 재이용사업
+ 구리시 도로자동청소시스템 설치사업
@@ -79,7 +80,7 @@ export default function GreywaterPage() {
사업목적
- 황구지천 공공하수처리시설 하수처리수 재이용사업으로 향후 호매실천 및 금곡천 건천화 방지로 주민들에게 친수 공간 제공 및 하천 생태계 보전
+ 고농도 미세먼지 발생 및 폭염의 급증에 따라 공공하수처리시설 발생 재이용수 일부를 도로자동청소시스템에 활용하여 미세먼지 저감 및 폭염 취약성 완화
@@ -89,10 +90,10 @@ export default function GreywaterPage() {
사업 주요 내용
- 총사업비 : 110억원
- 위 치 : 수원시 권선구 호매실천, 금곡천
- 관 로 : 3.9km
- 공 급 량 : 25,000㎥/일(하수처리시설 용량: 45,000㎥/일)
+ 총사업비 : 61억원
+ 위 치 : 구리시 경춘로 및 갈매중앙로 일대 등
+ 관 로 : 5.8km
+ 공급계획
@@ -105,62 +106,38 @@ export default function GreywaterPage() {
-
- {/* 구분 */}
-
- 구분
-
-
- {/* 공급량 */}
-
- 공급량
-
-
- {/* 비고 */}
-
- 비고
-
-
+
+
+ 시설명
+
+
+ 재이용수 용도
+
+
+ 공급량(㎥/일)
+
+
+ 원수
+
+
-
-
- {/* 좌측 병합 */}
-
- 하천 등 유지용수
-
-
-
- 12,500m³/일
-
-
-
- 호매실천 공급
-
-
-
-
-
- 6,250m³/일
-
-
-
- 금곡천1 공급
-
-
-
-
-
- 6,250m³/일
-
-
-
- 금곡천2 공급
-
-
+
+
+ 도로자동청소시스템
+
+
+ 세척살수용수
+
+
+ 178
+
+
+ 구리 공공하수처리장 재이용수
+
+
diff --git a/apps/dm_new/app/(with-layout)/example/sewage/hwanggu/page.tsx b/apps/dm_new/app/(with-layout)/example/sewage/hwanggu/page.tsx
index 36893ee7a..9d95651c9 100644
--- a/apps/dm_new/app/(with-layout)/example/sewage/hwanggu/page.tsx
+++ b/apps/dm_new/app/(with-layout)/example/sewage/hwanggu/page.tsx
@@ -62,6 +62,8 @@ export default function GreywaterPage() {
maxWidthClassName="max-w-[760px]"
slides={[
{ src: "/images/landing/business/sewage/hwanggu_01.png", alt: "수원시 황구지천 하수 재이용 1" },
+ { src: "/images/landing/business/sewage/hwanggu_02.png", alt: "수원시 황구지천 하수 재이용 2" },
+ { src: "/images/landing/business/sewage/hwanggu_03.png", alt: "수원시 황구지천 하수 재이용 3" },
]}
/>
diff --git a/apps/dm_new/app/layout.tsx b/apps/dm_new/app/layout.tsx
index 58eec5936..7224c9dc2 100644
--- a/apps/dm_new/app/layout.tsx
+++ b/apps/dm_new/app/layout.tsx
@@ -2,7 +2,7 @@
import "./globals.css";
import { setCookie } from "../src/shared/lib";
-setCookie("site-id-key", process.env.NEXT_PUBLIC_SITE_ID || "DN");
+setCookie("site-id-key", process.env.NEXT_PUBLIC_SITE_ID || "DM");
export default function RootLayout({
children,
diff --git a/apps/dm_new/app/main/_sections/Cases.tsx b/apps/dm_new/app/main/_sections/Cases.tsx
index 3d91bb5d5..077d05cfe 100644
--- a/apps/dm_new/app/main/_sections/Cases.tsx
+++ b/apps/dm_new/app/main/_sections/Cases.tsx
@@ -25,7 +25,7 @@ export default function Cases() {
();
+const anonymousMenuInFlight = new Map>();
export async function fetchAnonymousMenu(siteId = REUSE_SITE_ID): Promise {
- const response = await fetch(`/cms-service/api/v1/menu/anonymous/user/${siteId}`, {
- method: "GET",
- headers: { "Content-Type": "application/json" },
- cache: "no-store",
- });
+ const cached = anonymousMenuCache.get(siteId);
+ if (cached) return cached;
- if (!response.ok) {
- throw new Error(`Failed to load menu: ${response.status}`);
+ const inFlight = anonymousMenuInFlight.get(siteId);
+ if (inFlight) return inFlight;
+
+ const request = (async () => {
+ const response = await fetch(`/cms-service/api/v1/menu/anonymous/user/${siteId}`, {
+ method: "GET",
+ headers: { "Content-Type": "application/json" },
+ cache: "no-store",
+ });
+
+ if (!response.ok) {
+ throw new Error(`Failed to load menu: ${response.status}`);
+ }
+
+ const data = (await response.json()) as MenuItem[];
+ const normalized = Array.isArray(data) ? normalizeMenus(data) : [];
+ anonymousMenuCache.set(siteId, normalized);
+ return normalized;
+ })();
+
+ anonymousMenuInFlight.set(siteId, request);
+ try {
+ return await request;
+ } finally {
+ anonymousMenuInFlight.delete(siteId);
}
-
- const data = (await response.json()) as MenuItem[];
- if (!Array.isArray(data)) return [];
- return normalizeMenus(data);
}
function isPathMatched(pathname: string, urlPath: string) {
@@ -372,11 +390,14 @@ function isPathMatched(pathname: string, urlPath: string) {
return pathname === urlPath || pathname.startsWith(`${urlPath}/`);
}
+function hasMatchedPathInTree(menu: MenuItem, pathname: string): boolean {
+ if (isPathMatched(pathname, menu.urlPath)) return true;
+ return (menu.children ?? []).some((child) => hasMatchedPathInTree(child, pathname));
+}
+
export function findActiveTopMenu(menus: MenuItem[], pathname: string): MenuItem | null {
const level1Menus = menus.filter((menu) => menu.levelNo === 1 || menu.parentId === null);
- const matched = level1Menus
- .filter((menu) => isPathMatched(pathname, menu.urlPath))
- .sort((a, b) => b.urlPath.length - a.urlPath.length);
+ const matched = level1Menus.filter((menu) => hasMatchedPathInTree(menu, pathname));
return matched[0] ?? level1Menus[0] ?? null;
}
@@ -475,21 +496,7 @@ export const CommonReducer:(set:any)=>CommonAction=(set: any) => {
}
})
)},
- fetchAnonymousMenu: async (siteId = REUSE_SITE_ID) => {
- const response = await fetch(`/cms-service/api/v1/menu/anonymous/user/${siteId}`, {
- method: "GET",
- headers: { "Content-Type": "application/json" },
- cache: "no-store",
- });
-
- if (!response.ok) {
- throw new Error(`Failed to load menu: ${response.status}`);
- }
-
- const data = (await response.json()) as MenuItem[];
- if (!Array.isArray(data)) return [];
- return normalizeMenus(data);
- }
+ fetchAnonymousMenu: async (siteId = REUSE_SITE_ID) => fetchAnonymousMenu(siteId)
}
}
export type CommonStore = CommonType & CommonAction;
diff --git a/apps/dm_new/app/store/store.tsx b/apps/dm_new/app/store/store.tsx
index f885a3bd0..25508bae2 100644
--- a/apps/dm_new/app/store/store.tsx
+++ b/apps/dm_new/app/store/store.tsx
@@ -33,7 +33,7 @@ export const StoreZus = (
) => {
return createStore()((set) => {
if (typeof window !== "undefined") {
- tokenManager.setToken("site-id-key", "DM");
+ tokenManager.setToken("site-id-key", process.env.NEXT_PUBLIC_SITE_ID||"DM");
tokenManager.setToken("site-theme-key", "green");
}
diff --git a/apps/dm_new/components/CaseTabsCarousel.tsx b/apps/dm_new/components/CaseTabsCarousel.tsx
index 2d936ffc5..44f790366 100644
--- a/apps/dm_new/components/CaseTabsCarousel.tsx
+++ b/apps/dm_new/components/CaseTabsCarousel.tsx
@@ -69,21 +69,42 @@ const MOCK: Record = {
title: "경기도 파주시 하수 재이용",
desc: "운정·금촌하수처리시설의 하수처리수를 막공법(U/F, R/O)으로 재처리하여 파주 LCD 산업단지내 3개 업체*에...",
imageSrc: "/images/landing/sewage_01.png",
- href: "#",
+ href: "/reuse/business/sewage/paju",
},
{
id: "sewage-2",
title: "충남보령 하수재이용",
desc: "보령·신보령화력발전소에 하루 1만톤의 탈황용수 공급을 위해 보령하수처리시설의 하수처리수 재이용 사업...",
imageSrc: "/images/landing/sewage_02.png",
- href: "#",
+ href: "/reuse/business/sewage/bolyeong",
},
{
id: "sewage-3",
title: "여수시 하수처리수 재이용",
desc: "(빗물) 월드컵경기장 등 4개소에 노면 빗물분사시스템 및 빗물 공급기를 설치하여 혹서기 도시 열섬효과 및 도로...",
imageSrc: "/images/landing/sewage_03.png",
- href: "#",
+ href: "/reuse/business/sewage/yeosu",
+ },
+ {
+ id: "sewage-4",
+ title: "청주시 하수 재이용 시설",
+ desc: "청주시 하수처리수 재이용 민간투자사업(BTO) 청주시 하수처리수 재이용 민간투자사업(BTO) 청주시 하수처리수 재이용 민간투자사업(BTO)...",
+ imageSrc: "/images/landing/sewage_04.png",
+ href: "/reuse/business/sewage/cheongju",
+ },
+ {
+ id: "sewage-5",
+ title: "수원시 황구지천 하천유지용수",
+ desc: "황구지천 공공하수처리시설 하수처리수 재이용사업으로 향후 호매실천 및 금곡천 건천화 방지로...",
+ imageSrc: "/images/landing/sewage_05.png",
+ href: "/reuse/business/sewage/hwanggu",
+ },
+ {
+ id: "sewage-6",
+ title: "구리시 도로자동청소시스템",
+ desc: "고농도 미세먼지 발생 및 폭염의 급증에 따라 공공하수처리시설 발생 재이용수 일부를 도로자동청소시스템에 활용...",
+ imageSrc: "/images/landing/sewage_06.png",
+ href: "/reuse/business/sewage/guri",
},
...Array.from({ length: 6 }).map((_, i) => ({
id: `sewage-x-${i}`,
diff --git a/apps/dm_new/components/Lnb.tsx b/apps/dm_new/components/Lnb.tsx
index 693f1cebf..250d972b9 100644
--- a/apps/dm_new/components/Lnb.tsx
+++ b/apps/dm_new/components/Lnb.tsx
@@ -70,7 +70,7 @@ export default function Lnb() {
return (
- {currentTopMenu?.menuKornNm ?? ""}
+ {currentTopMenu?.menuKornNm?.trim().split(/\s+/).pop() ?? ""}