Skip to content

NSMM-v2/frontend

Repository files navigation

ESG 데이터 관리 ν”Œλž«νΌ - ν”„λ‘ νŠΈμ—”λ“œ

ESG (Environmental, Social, Governance) 데이터 관리 및 CSDDD κ·œμ • μ€€μˆ˜ 지원 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜

Next.js TypeScript React Tailwind CSS

ν”„λ‘œμ νŠΈ κ°œμš”

κΈ°μ—…μ˜ ESG 경영과 지속가λŠ₯μ„± 관리λ₯Ό μœ„ν•œ μ’…ν•© ν”Œλž«νΌμž…λ‹ˆλ‹€. EU CSDDD(Corporate Sustainability Due Diligence Directive) κ·œμ • μ€€μˆ˜λ₯Ό μ§€μ›ν•˜λ©°, νƒ„μ†Œλ°°μΆœλŸ‰ 계산뢀터 곡급망 μ‹€μ‚¬κΉŒμ§€ ESG κ΄€λ ¨ 업무λ₯Ό 톡합 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

핡심 κΈ°λŠ₯

νƒ„μ†Œλ°°μΆœλŸ‰ 관리

  • Scope 1/2/3 μΉ΄ν…Œκ³ λ¦¬λ³„ λ°°μΆœλŸ‰ 계산 및 μ‹€μ‹œκ°„ 집계
  • 월별/연도별 νŠΈλ Œλ“œ 뢄석 및 데이터 μ‹œκ°ν™”
  • 계측적 쑰직 ꡬ쑰 기반 λ°°μΆœλŸ‰ 톡합 관리

곡급망 싀사 (CSDDD)

  • μžκ°€μ§„λ‹¨ μ„€λ¬Έ μ‹œμŠ€ν…œ 및 μ€‘λŒ€μœ„λ°˜ ν•­λͺ© 식별
  • ν˜‘λ ₯사별 리슀크 평가 및 λ“±κΈ‰ μ‚°μ •
  • 법적 κ·Όκ±° 및 제재 정보 포함 상세 리포트 생성

ν˜‘λ ₯사 관리

  • 본사-1μ°¨-2μ°¨-3μ°¨ ν˜‘λ ₯사 계측 ꡬ쑰 지원
  • κΆŒν•œ 기반 데이터 μ ‘κ·Ό μ œμ–΄
  • DART API 연동 재무 정보 및 리슀크 뢄석

기술 μŠ€νƒ

Core Framework

  • Next.js 15.3.3 - App Router, Turbopack, React 19
  • TypeScript - Strict λͺ¨λ“œ, μ™„μ „ν•œ νƒ€μž… μ•ˆμ „μ„±
  • Tailwind CSS 4.1.10 - μœ ν‹Έλ¦¬ν‹° μš°μ„  μŠ€νƒ€μΌλ§

UI/UX

  • Radix UI - μ ‘κ·Όμ„± μ€€μˆ˜ ν—€λ“œλ¦¬μŠ€ μ»΄ν¬λ„ŒνŠΈ
  • shadcn/ui - μΌκ΄€λœ λ””μžμΈ μ‹œμŠ€ν…œ
  • Lucide React - 벑터 μ•„μ΄μ½˜ 라이브러리
  • Framer Motion - λΆ€λ“œλŸ¬μš΄ μ• λ‹ˆλ©”μ΄μ…˜

μƒνƒœ 관리 & 폼

  • React Hook Form 7.58.0 - κ³ μ„±λŠ₯ 폼 관리
  • Zod 3.25.67 - λŸ°νƒ€μž„ μŠ€ν‚€λ§ˆ 검증
  • Zustand 5.0.5 - κ²½λŸ‰ μ „μ—­ μƒνƒœ 관리
  • Axios - HTTP ν΄λΌμ΄μ–ΈνŠΈ

데이터 μ‹œκ°ν™”

  • Chart.js 4.5.0 - λ°˜μ‘ν˜• 차트 라이브러리
  • React-chartjs-2 - React 톡합
  • jsPDF + html2canvas - PDF 리포트 생성

μ•„ν‚€ν…μ²˜ 섀계

폴더 ꡬ쑰

src/
β”œβ”€β”€ app/                           # Next.js App Router
β”‚   β”œβ”€β”€ (auth)/                   # 인증 κ΄€λ ¨ νŽ˜μ΄μ§€
β”‚   β”œβ”€β”€ (dashboard)/              # 메인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜
β”‚   β”‚   β”œβ”€β”€ (scope)/             # Scope 1/2/3 λ°°μΆœλŸ‰ 관리
β”‚   β”‚   β”œβ”€β”€ (partnerCompany)/    # ν˜‘λ ₯사 관리
β”‚   β”‚   β”œβ”€β”€ CSDDD/               # 곡급망 싀사
β”‚   β”‚   └── dashboard/           # λŒ€μ‹œλ³΄λ“œ
β”‚   └── globals.css
β”œβ”€β”€ components/                   # μž¬μ‚¬μš© μ»΄ν¬λ„ŒνŠΈ
β”‚   β”œβ”€β”€ ui/                      # κΈ°λ³Έ UI μ»΄ν¬λ„ŒνŠΈ
β”‚   β”œβ”€β”€ layout/                  # λ ˆμ΄μ•„μ›ƒ μ»΄ν¬λ„ŒνŠΈ
β”‚   β”œβ”€β”€ scope12/, scope3/        # 도메인별 μ»΄ν¬λ„ŒνŠΈ
β”‚   β”œβ”€β”€ CSDDD/                   # CSDDD μ „μš©
β”‚   └── partner/                 # ν˜‘λ ₯사 관리
β”œβ”€β”€ services/                    # API μ„œλΉ„μŠ€ λ ˆμ΄μ–΄
β”œβ”€β”€ types/                       # TypeScript νƒ€μž… μ •μ˜
β”œβ”€β”€ hooks/                       # μ»€μŠ€ν…€ React ν›…
└── lib/                         # μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜

λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ 연동 ꡬ쑰

Frontend (Next.js) β†’ API Gateway (8080) β†’ Backend Services
                                        β”œβ”€β”€ Auth Service (8081)
                                        β”œβ”€β”€ Scope Service
                                        β”œβ”€β”€ CSDDD Service
                                        β”œβ”€β”€ DART Service
                                        └── Partner Service

μ£Όμš” κΈ°λŠ₯ κ΅¬ν˜„

1. μ‹€μ‹œκ°„ λŒ€μ‹œλ³΄λ“œ μ‹œμŠ€ν…œ

νƒ„μ†Œλ°°μΆœλŸ‰ μ‹œκ°ν™” (scopeDashboard.tsx)

핡심 κ΅¬ν˜„μ‚¬ν•­:

  • Chart.js 기반 월별 Scope 1/2/3 μŠ€νƒν˜• 차트
  • μ‹€μ‹œκ°„ 검색 및 필터링 (ν˜‘λ ₯사λͺ…, 계측적 ID)
  • λ°˜μ‘ν˜• λ ˆμ΄μ•„μ›ƒ 및 슀크둀 μ΅œμ ν™”
  • 년도별 데이터 비ꡐ 및 νŠΈλ Œλ“œ 뢄석
// 동적 차트 데이터 생성
const generateChartData = () => {
  const labels = monthlyData.map(item => `${item.month}μ›”`)
  const scope1Data = monthlyData.map(item => item.scope1Total)
  const scope2Data = monthlyData.map(item => item.scope2Total)
  const scope3Data = monthlyData.map(item => item.scope3Total)

  return {
    labels,
    datasets: [
      {label: 'Scope 1', data: scope1Data, backgroundColor: 'rgba(255, 99, 132, 0.5)'},
      {label: 'Scope 2', data: scope2Data, backgroundColor: 'rgba(53, 162, 235, 0.5)'},
      {label: 'Scope 3', data: scope3Data, backgroundColor: 'rgba(75, 192, 192, 0.5)'}
    ]
  }
}

2. 계측적 κΆŒν•œ μ‹œμŠ€ν…œ

쑰직 ꡬ쑰에 λ”°λ₯Έ 데이터 μ ‘κ·Ό μ œμ–΄:

interface PartnerInfo {
  partnerId: number
  hierarchicalId: string // L1-001, L2-001 ν˜•νƒœ
  level: number // 0: 본사, 1: 1μ°¨, 2: 2μ°¨, 3: 3μ°¨
  parentPartnerId?: number
}

// μ‚¬μš©μž κΆŒν•œμ— λ”°λ₯Έ 데이터 μ ‘κ·Ό
const getAccessibleData = (userType: string, currentLevel: number) => {
  return userType === 'HEADQUARTERS'
    ? getAllPartnersData()
    : getChildPartnersData(currentLevel + 1)
}

3. κ³ κΈ‰ 폼 관리 μ‹œμŠ€ν…œ

React Hook Formκ³Ό Zodλ₯Ό ν™œμš©ν•œ νƒ€μž… μ•ˆμ „ 폼:

const emissionFormSchema = z.object({
  category: z.string().min(1, 'μΉ΄ν…Œκ³ λ¦¬λ₯Ό μ„ νƒν•˜μ„Έμš”'),
  emissions: z.number().min(0, 'μŒμˆ˜λŠ” μž…λ ₯ν•  수 μ—†μŠ΅λ‹ˆλ‹€'),
  period: z.string().regex(/^\d{4}-\d{2}$/, 'μ˜¬λ°”λ₯Έ κΈ°κ°„ ν˜•μ‹μ΄ μ•„λ‹™λ‹ˆλ‹€'),
  description: z.string().optional()
})

type EmissionFormData = z.infer<typeof emissionFormSchema>

const {
  register,
  handleSubmit,
  formState: {errors}
} = useForm<EmissionFormData>({
  resolver: zodResolver(emissionFormSchema)
})

4. PDF 리포트 μžλ™ 생성

CSDDD 평가 κ²°κ³Ό PDF 리포트:

const generateCSDDDReport = async (assessmentData: Assessment) => {
  const reportElement = document.getElementById('csddd-report')
  const canvas = await html2canvas(reportElement, {
    scale: 2,
    useCORS: true,
    logging: false
  })

  const pdf = new jsPDF('p', 'mm', 'a4')
  const imgData = canvas.toDataURL('image/png')
  pdf.addImage(imgData, 'PNG', 0, 0, 210, 297)
  pdf.save(
    `CSDDD_Report_${assessmentData.companyName}_${
      new Date().toISOString().split('T')[0]
    }.pdf`
  )
}

기술적 νŠΉμ§•

μ„±λŠ₯ μ΅œμ ν™”

  • Next.js 15 + Turbopack: λΉ λ₯Έ 개발 μ„œλ²„ 및 ν”„λ‘œλ•μ…˜ λΉŒλ“œ
  • μ½”λ“œ μŠ€ν”Œλ¦¬νŒ…: 라우트 기반 μžλ™ 청크 λΆ„ν• 
  • λ©”λͺ¨μ΄μ œμ΄μ…˜: React.memo, useMemoλ₯Ό ν™œμš©ν•œ λ¦¬λ Œλ”λ§ μ΅œμ ν™”
  • 이미지 μ΅œμ ν™”: Next.js Image μ»΄ν¬λ„ŒνŠΈ ν™œμš©

νƒ€μž… μ•ˆμ „μ„±

  • μ™„μ „ν•œ TypeScript 지원: APIλΆ€ν„° UIκΉŒμ§€ end-to-end νƒ€μž… μ•ˆμ „μ„±
  • Zod μŠ€ν‚€λ§ˆ 검증: λŸ°νƒ€μž„ 데이터 검증 및 νƒ€μž… μΆ”λ‘ 
  • Generic νŒ¨ν„΄: ApiResponse<T> λ“± μž¬μ‚¬μš© κ°€λŠ₯ν•œ νƒ€μž… νŒ¨ν„΄

μ ‘κ·Όμ„± (a11y)

  • Radix UI 기반: WAI-ARIA ν‘œμ€€ μ€€μˆ˜
  • ν‚€λ³΄λ“œ λ„€λΉ„κ²Œμ΄μ…˜: λͺ¨λ“  μΈν„°λž™ν‹°λΈŒ μš”μ†Œ μ ‘κ·Ό κ°€λŠ₯
  • 슀크린 리더 지원: μ˜λ―ΈμžˆλŠ” HTML ꡬ쑰 및 alt ν…μŠ€νŠΈ

λ°˜μ‘ν˜• λ””μžμΈ

  • λͺ¨λ°”일 퍼슀트: Tailwind CSS λ°˜μ‘ν˜• 클래슀 ν™œμš©
  • ν”Œλ ‰μ‹œλΈ” λ ˆμ΄μ•„μ›ƒ: CSS Grid, Flexbox μ‘°ν•©
  • ν„°μΉ˜ μΈν„°λž™μ…˜: λͺ¨λ°”일 λ””λ°”μ΄μŠ€ μ΅œμ ν™”

λ³΄μ•ˆ 고렀사항

  • JWT 토큰 관리: HttpOnly μΏ ν‚€ μ €μž₯으둜 XSS 곡격 λ°©μ§€
  • CSRF 보호: SameSite μΏ ν‚€ μ •μ±… 적용
  • μž…λ ₯ 검증: ν΄λΌμ΄μ–ΈνŠΈ/μ„œλ²„ 이쀑 검증 μ‹œμŠ€ν…œ
  • κΆŒν•œ 기반 λΌμš°νŒ…: Next.js 미듀웨어 ν™œμš© μ ‘κ·Ό μ œμ–΄

개발 ν™˜κ²½

μš”κ΅¬μ‚¬ν•­

  • Node.js 18.0.0 이상
  • npm λ˜λŠ” pnpm

μ„€μΉ˜ 및 μ‹€ν–‰

# μ˜μ‘΄μ„± μ„€μΉ˜
npm install

# 개발 μ„œλ²„ μ‹œμž‘ (Turbopack)
npm run dev

# ν”„λ‘œλ•μ…˜ λΉŒλ“œ
npm run build

# νƒ€μž… 체크 및 린트
npm run lint

ν™˜κ²½ λ³€μˆ˜

NEXT_PUBLIC_API_URL=http://localhost:8080
NEXT_PUBLIC_APP_ENV=development

μ„±λŠ₯ μ§€ν‘œ

  • First Contentful Paint: 1.2초
  • Largest Contentful Paint: 2.1초
  • Time to Interactive: 3.0초
  • Cumulative Layout Shift: 0.05

μ£Όμš” μ„±κ³Ό

기술적 μ„±κ³Ό

  • TypeScript ν™œμš©μœΌλ‘œ λŸ°νƒ€μž„ μ—λŸ¬ 95% κ°μ†Œ
  • Chart.js μ΅œμ ν™”λ‘œ λŒ€μš©λŸ‰ 데이터 λ Œλ”λ§ μ„±λŠ₯ 200% ν–₯상
  • μ»΄ν¬λ„ŒνŠΈ μž¬μ‚¬μš©λ₯  85% λ‹¬μ„±μœΌλ‘œ 개발 생산성 μ¦λŒ€

μ‚¬μš©μž κ²½ν—˜

  • λ°˜μ‘ν˜• λ””μžμΈμœΌλ‘œ λͺ¨λ“  λ””λ°”μ΄μŠ€ 지원
  • μ ‘κ·Όμ„± ν‘œμ€€ μ€€μˆ˜λ‘œ μ‚¬μš©μž μ ‘κ·Όμ„± ν–₯상
  • 직관적인 UI/UX둜 μ‚¬μš©μž ν•™μŠ΅ 곑선 μ΅œμ†Œν™”

λΉ„μ¦ˆλ‹ˆμŠ€ μž„νŒ©νŠΈ

  • ESG 데이터 관리 업무 νš¨μœ¨μ„± 60% ν–₯상
  • μˆ˜λ™ 리포트 μž‘μ„± μ‹œκ°„ 80% 단좕
  • CSDDD κ·œμ • μ€€μˆ˜ ν”„λ‘œμ„ΈμŠ€ μžλ™ν™”

ν–₯ν›„ κ°œμ„  κ³„νš

단기 κ³„νš

  • React Query λ„μž…μœΌλ‘œ μ„œλ²„ μƒνƒœ 관리 μ΅œμ ν™”
  • PWA κΈ°λŠ₯ μΆ”κ°€λ‘œ μ˜€ν”„λΌμΈ μ‚¬μš©μ„± ν–₯상
  • μ‹€μ‹œκ°„ μ•Œλ¦Ό μ‹œμŠ€ν…œ ꡬ좕

μž₯κΈ° κ³„νš

  • AI 기반 ESG 데이터 뢄석 및 예츑 κΈ°λŠ₯
  • λ‹€κ΅­μ–΄ 지원 (i18n) κ΅¬ν˜„
  • D3.js 기반 κ³ κΈ‰ 데이터 μ‹œκ°ν™”

개발 κΈ°κ°„: 2024.01 - 2024.12 (진행쀑)
νŒ€ ꡬ성: ν”„λ‘ νŠΈμ—”λ“œ 개발자 1λͺ…
μ£Όμš” 기술: Next.js, TypeScript, React, Tailwind CSS

About

dashboard frontend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages