diff --git a/next.config.js b/next.config.js index 458f2bf..3af57c6 100644 --- a/next.config.js +++ b/next.config.js @@ -1,7 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { images: { - domains: ['localhost', 'api.lms-bgn.id'], + domains: ['localhost', 'api.lms-bgn.id', 'upload.wikimedia.org'], formats: ['image/webp', 'image/avif'], }, // PWA Configuration diff --git a/src/app/admin/payroll/page.tsx b/src/app/admin/payroll/page.tsx new file mode 100644 index 0000000..e899d78 --- /dev/null +++ b/src/app/admin/payroll/page.tsx @@ -0,0 +1,17 @@ +'use client'; + +import React from 'react'; +import { PayrollManagement } from '@/features/payroll-reward-system/components'; +import DashboardLayout from '@/layouts/DashboardLayout'; + +export default function AdminPayrollPage() { + return ( + +
+

Admin Payroll

+

Kelola perhitungan dan pembayaran payroll peserta.

+
+ +
+ ); +} \ No newline at end of file diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 5441aa7..4a5200f 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import Link from 'next/link'; +import Image from 'next/image'; import { useRouter } from 'next/navigation'; import { Eye, EyeOff, Mail, Lock, AlertCircle, CheckCircle } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -95,8 +96,15 @@ export default function LoginPage() {
{/* Logo and Title */}
-
- LMS +
+ Logo Badan Gizi Nasional

Selamat Datang

Masuk ke akun Learning Management System Anda

diff --git a/src/app/page.tsx b/src/app/page.tsx index b528965..7757a48 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -227,44 +227,7 @@ export default function Dashboard() {
- {/* Development Demo Section */} -
-
-
🚀
-
-

- Development Demo - Modular Architecture -

-

- Lihat implementasi EPIC 17: Participant Payroll Reward System menggunakan arsitektur modular baru. - Demo ini menampilkan sistem reward, wallet management, dan payroll calculation. -

-
- - Dependency Injection - - - Event Bus System - - - Plugin Architecture - - - Service Layer - -
- - đŸŽ¯ Lihat Demo Payroll System - - - - -
-
-
+ {/* Development Demo Section moved to Sidebar under Add-ons */} {/* Recent Activities Section */}
diff --git a/src/app/payroll-demo/page.tsx b/src/app/payroll-demo/page.tsx index 431fc6f..d74c8df 100644 --- a/src/app/payroll-demo/page.tsx +++ b/src/app/payroll-demo/page.tsx @@ -11,6 +11,7 @@ import { import { PayrollRewardSystemModule } from '../../features/payroll-reward-system'; import { setupGlobalErrorHandling } from '../../core/errors'; import { container as globalContainer } from '../../core/di/DIContainer'; +import DashboardLayout from '@/layouts/DashboardLayout'; export default function PayrollDemoPage() { const [moduleLoaded, setModuleLoaded] = useState(false); @@ -87,46 +88,51 @@ export default function PayrollDemoPage() { if (loading) { return ( -
-
-
-

Loading Payroll Reward System...

+ +
+
+
+

Loading Payroll Reward System...

+
-
+ ); } if (error) { return ( -
-
-
❌
-

Module Load Error

-

{error}

- + +
+
+
❌
+

Module Load Error

+

{error}

+ +
-
+ ); } return ( - -
+ + +
{/* Header */}

- đŸŽ¯ Payroll Reward System Demo + đŸŽ¯ Payroll Reward System

- Modular Architecture Implementation - EPIC 17 + Modular Payroll Reward System

@@ -175,38 +181,6 @@ export default function PayrollDemoPage() { {/* Content */}
- {/* Module Info Card */} -
-
-
â„šī¸
-
-

- Modular Architecture Demo -

-

- This demo showcases the implementation of EPIC 17 using our new modular architecture. - The system includes reward calculation, wallet management, and payroll processing. -

-
- - ✅ Core DI Container - - - ✅ Event Bus System - - - ✅ Feature Module Plugin - - - ✅ Service Layer - - - ✅ React Components - -
-
-
-
{/* Component Content */} {moduleLoaded && ( @@ -234,67 +208,9 @@ export default function PayrollDemoPage() { )}
)} - - {/* Architecture Info */} -
-

đŸ—ī¸ Architecture Overview

- -
-
-

🔧 Core Layer

-
    -
  • â€ĸ Dependency Injection Container
  • -
  • â€ĸ Event Bus System
  • -
  • â€ĸ Base Interfaces (IService, IRepository)
  • -
  • â€ĸ Plugin Architecture
  • -
-
- -
-

đŸŽ¯ Feature Module

-
    -
  • â€ĸ RewardService
  • -
  • â€ĸ WalletService
  • -
  • â€ĸ PayrollCalculator
  • -
  • â€ĸ Type Definitions
  • -
-
- -
-

🎨 UI Components

-
    -
  • â€ĸ RewardDashboard
  • -
  • â€ĸ WalletBalance
  • -
  • â€ĸ PayrollManagement
  • -
  • â€ĸ Responsive Design
  • -
-
-
- -
-

📋 Implementation Status

-
-
- ✅ - Core Architecture -
-
- ✅ - Service Layer -
-
- ✅ - UI Components -
-
- âŗ - Data Persistence -
-
-
-
+ ); } \ No newline at end of file diff --git a/src/features/payroll-reward-system/components/RewardDashboard.tsx b/src/features/payroll-reward-system/components/RewardDashboard.tsx index c849f82..7bac38f 100644 --- a/src/features/payroll-reward-system/components/RewardDashboard.tsx +++ b/src/features/payroll-reward-system/components/RewardDashboard.tsx @@ -142,12 +142,12 @@ export const RewardDashboard: React.FC = ({ if (error) { return (
-
+

Error

{error}

@@ -168,7 +168,7 @@ export const RewardDashboard: React.FC = ({ onClick={() => setSelectedPeriod(period)} className={`px-3 py-1 rounded text-sm font-medium ${ selectedPeriod === period - ? 'bg-blue-600 text-white' + ? 'bg-primary-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }`} > @@ -181,30 +181,30 @@ export const RewardDashboard: React.FC = ({ {/* Statistics Cards */} {stats && (
-
+
-

Total Earned

+

Total Earned

{formatCurrency(stats.totalEarned)}

💰
-
+
-

Periode Ini

+

Periode Ini

{formatCurrency(stats.thisMonthEarnings)}

📈
-
+
-

Pending

+

Pending

{formatCurrency(stats.pendingRewards)}

âŗ
@@ -292,7 +292,7 @@ export const RewardDashboard: React.FC = ({ {/* View All Link */} {rewards.length > 10 && (
-
diff --git a/src/layouts/Sidebar.tsx b/src/layouts/Sidebar.tsx index 29dc334..50fb499 100644 --- a/src/layouts/Sidebar.tsx +++ b/src/layouts/Sidebar.tsx @@ -3,6 +3,8 @@ import React from 'react'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; +import Image from 'next/image'; +import { useAuth } from '@/contexts/AuthContext'; import { HomeIcon, BookOpenIcon, @@ -14,7 +16,9 @@ import { ChartBarIcon, CogIcon, XMarkIcon, - Bars3Icon + Bars3Icon, + BanknotesIcon, + ShieldCheckIcon } from '@heroicons/react/24/outline'; import { cn } from '@/utils/cn'; @@ -37,8 +41,14 @@ const navigation = [ { name: 'Pengaturan', href: '/settings', icon: CogIcon }, ]; +const addons = [ + { name: 'Payroll Reward System', href: '/payroll-demo', icon: BanknotesIcon }, + { name: 'Admin Payroll', href: '/admin/payroll', icon: ShieldCheckIcon }, +]; + export function Sidebar({ isOpen, isCollapsed, onClose, onToggleCollapse }: SidebarProps) { const pathname = usePathname(); + const { user } = useAuth(); return ( <> @@ -53,9 +63,16 @@ export function Sidebar({ isOpen, isCollapsed, onClose, onToggleCollapse }: Side
{!isCollapsed && (
-
- -
+
+ Logo Badan Gizi Nasional +
LMS BGN
Badan Gizi Nasional
@@ -108,6 +125,39 @@ export function Sidebar({ isOpen, isCollapsed, onClose, onToggleCollapse }: Side ); })} + + {/* Add-ons section */} + {!isCollapsed && ( +
+ Add-ons +
+ )} + {addons + .filter(item => !item.href.startsWith('/admin') || user?.role === 'admin') + .map((item) => { + const isActive = pathname === item.href; + return ( + + + {!isCollapsed && ( + {item.name} + )} + + ); + })} {/* User info */} @@ -135,8 +185,15 @@ export function Sidebar({ isOpen, isCollapsed, onClose, onToggleCollapse }: Side {/* Mobile header */}
-
- +
+ Logo Badan Gizi Nasional
LMS BGN
@@ -184,6 +241,34 @@ export function Sidebar({ isOpen, isCollapsed, onClose, onToggleCollapse }: Side ); })} + + {/* Add-ons section */} +
+ Add-ons +
+ {addons + .filter(item => !item.href.startsWith('/admin') || user?.role === 'admin') + .map((item) => { + const isActive = pathname === item.href; + return ( + +
+ + {item.name} +
+ + ); + })} {/* Mobile user info */}