From 8a2a4db69a1d1355ad522e5051a63abb25660b40 Mon Sep 17 00:00:00 2001 From: Flook Date: Sun, 9 Nov 2025 09:12:57 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B8=9E=E0=B8=B1=E0=B8=92=E0=B8=99=E0=B8=B2?= =?UTF-8?q?=20Frontend=20(Web)=20=E0=B9=81=E0=B8=A5=E0=B8=B0=20Backend=20(?= =?UTF-8?q?Django=20DRF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/misc.xml | 9 + .idea/modules.xml | 8 + .idea/monorepo-starter-template.iml | 9 + .idea/vcs.xml | 6 + backend/accounts/admin.py | 35 +- .../migrations/0002_customuser_role.py | 18 + backend/accounts/models.py | 17 +- backend/accounts/serializers.py | 11 +- backend/core/settings.py | 64 +- backend/core/spectacular_hooks.py | 13 + backend/core/urls.py | 23 +- backend/model_registry/__init__.py | 0 backend/model_registry/admin.py | 3 + backend/model_registry/apps.py | 6 + .../model_registry/migrations/0001_initial.py | 33 + backend/model_registry/migrations/__init__.py | 0 backend/model_registry/models.py | 37 ++ .../model_registry/repositories/__init__.py | 0 .../repositories/ai_model_repository.py | 23 + .../model_registry/serializers/__init__.py | 0 .../serializers/ai_model_serializer.py | 16 + backend/model_registry/services/__init__.py | 0 .../services/ai_model_service.py | 58 ++ backend/model_registry/tests.py | 3 + backend/model_registry/views.py | 3 + backend/model_registry/views/__init__.py | 0 .../model_registry/views/ai_model_viewset.py | 72 +++ backend/requirements.txt | 4 +- web/package-lock.json | 569 +++++++++++++++++- web/package.json | 12 +- web/public/favicon-32x32.svg | 16 + web/public/intro.png | Bin 0 -> 189330 bytes web/public/logo192.png | Bin 0 -> 8260 bytes web/src/App.jsx | 23 +- web/src/app/store.js | 23 + web/src/components/ErrorText.jsx | 17 + web/src/components/InputText.jsx | 28 + web/src/components/LandingIntro.jsx | 31 + web/src/components/LoginForm.jsx | 122 ++++ web/src/components/SidebarSubmenu.jsx | 87 +++ web/src/components/Subtitle.jsx | 12 + web/src/components/TemplatePointers.jsx | 34 ++ web/src/components/TitleCard.jsx | 33 + web/src/config/sidebarRoutes.jsx | 108 ++++ web/src/features/auth/authSlice.js | 81 +++ web/src/layouts/AuthLayout.jsx | 16 + web/src/layouts/MainLayout.jsx | 176 ++++++ web/src/main.jsx | 13 +- web/src/pages/BlankPage.jsx | 41 ++ web/src/pages/Dashboard.jsx | 25 + web/src/routes/AuthRoutes.jsx | 23 + web/src/routes/PrivateRoutes.jsx | 30 + web/src/routes/ProtectedRoute.jsx | 17 + web/src/routes/pageRoutes.jsx | 18 + web/src/schemas/authSchema.js | 9 + web/src/services/authApi.js | 139 +++++ web/src/services/axiosClient.js | 58 ++ 59 files changed, 2215 insertions(+), 31 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/monorepo-starter-template.iml create mode 100644 .idea/vcs.xml create mode 100644 backend/accounts/migrations/0002_customuser_role.py create mode 100644 backend/core/spectacular_hooks.py create mode 100644 backend/model_registry/__init__.py create mode 100644 backend/model_registry/admin.py create mode 100644 backend/model_registry/apps.py create mode 100644 backend/model_registry/migrations/0001_initial.py create mode 100644 backend/model_registry/migrations/__init__.py create mode 100644 backend/model_registry/models.py create mode 100644 backend/model_registry/repositories/__init__.py create mode 100644 backend/model_registry/repositories/ai_model_repository.py create mode 100644 backend/model_registry/serializers/__init__.py create mode 100644 backend/model_registry/serializers/ai_model_serializer.py create mode 100644 backend/model_registry/services/__init__.py create mode 100644 backend/model_registry/services/ai_model_service.py create mode 100644 backend/model_registry/tests.py create mode 100644 backend/model_registry/views.py create mode 100644 backend/model_registry/views/__init__.py create mode 100644 backend/model_registry/views/ai_model_viewset.py create mode 100644 web/public/favicon-32x32.svg create mode 100644 web/public/intro.png create mode 100644 web/public/logo192.png create mode 100644 web/src/app/store.js create mode 100644 web/src/components/ErrorText.jsx create mode 100644 web/src/components/InputText.jsx create mode 100644 web/src/components/LandingIntro.jsx create mode 100644 web/src/components/LoginForm.jsx create mode 100644 web/src/components/SidebarSubmenu.jsx create mode 100644 web/src/components/Subtitle.jsx create mode 100644 web/src/components/TemplatePointers.jsx create mode 100644 web/src/components/TitleCard.jsx create mode 100644 web/src/config/sidebarRoutes.jsx create mode 100644 web/src/features/auth/authSlice.js create mode 100644 web/src/layouts/AuthLayout.jsx create mode 100644 web/src/layouts/MainLayout.jsx create mode 100644 web/src/pages/BlankPage.jsx create mode 100644 web/src/pages/Dashboard.jsx create mode 100644 web/src/routes/AuthRoutes.jsx create mode 100644 web/src/routes/PrivateRoutes.jsx create mode 100644 web/src/routes/ProtectedRoute.jsx create mode 100644 web/src/routes/pageRoutes.jsx create mode 100644 web/src/schemas/authSchema.js create mode 100644 web/src/services/authApi.js create mode 100644 web/src/services/axiosClient.js diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b8763d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5f3a278 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/monorepo-starter-template.iml b/.idea/monorepo-starter-template.iml new file mode 100644 index 0000000..67954c8 --- /dev/null +++ b/.idea/monorepo-starter-template.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/backend/accounts/admin.py b/backend/accounts/admin.py index e80d26e..0e23c57 100644 --- a/backend/accounts/admin.py +++ b/backend/accounts/admin.py @@ -1,11 +1,34 @@ +# users/admin.py + from django.contrib import admin -from django.contrib.auth.admin import UserAdmin +from django.contrib.auth.admin import UserAdmin as BaseUserAdmin # เปลี่ยนชื่อเป็น BaseUserAdmin เพื่อป้องกันการซ้ำซ้อน from .models import CustomUser -# ใช้ UserAdmin เพื่อให้ได้ UI ที่ครบถ้วนสำหรับการจัดการผู้ใช้ -class CustomUserAdmin(UserAdmin): - # Fieldsets หรือ list_display (ถ้าต้องการปรับแต่ง UI) - pass +# สร้าง Custom User Admin เพื่อจัดการฟิลด์เพิ่มเติม +class CustomUserAdmin(BaseUserAdmin): + # 1. กำหนดฟิลด์ที่จะแสดงในหน้าลิสต์ผู้ใช้ + list_display = ( + 'username', + 'email', + 'first_name', + 'last_name', + 'is_staff', + 'is_superuser', + 'role' + ) -# ลงทะเบียน CustomUser ด้วย CustomUserAdmin + # 2. กำหนดโครงสร้างและการจัดกลุ่มฟิลด์ในหน้าแก้ไขผู้ใช้ + fieldsets = ( + (None, {'fields': ('username', 'password')}), + ('Personal info', {'fields': ('first_name', 'last_name', 'email', 'phone_number')}), # 🔑 เพิ่ม phone_number + ('Role and Permissions', { # สร้างกลุ่มใหม่เพื่อจัดระเบียบ + 'fields': ('role', 'is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'), + }), + ('Important dates', {'fields': ('last_login', 'date_joined')}), + ) + + # 3. กำหนดฟิลด์ที่ใช้ในการค้นหาในหน้าลิสต์ผู้ใช้ + search_fields = ('username', 'email', 'phone_number') + +# ลงทะเบียน CustomUser ด้วย CustomUserAdmin ที่ถูกปรับแต่ง admin.site.register(CustomUser, CustomUserAdmin) \ No newline at end of file diff --git a/backend/accounts/migrations/0002_customuser_role.py b/backend/accounts/migrations/0002_customuser_role.py new file mode 100644 index 0000000..eea7bda --- /dev/null +++ b/backend/accounts/migrations/0002_customuser_role.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-11-08 22:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='role', + field=models.CharField(choices=[('ADMIN', 'Administrator'), ('OPERATOR', 'Operator'), ('VIEWER', 'Viewer')], default='VIEWER', max_length=20), + ), + ] diff --git a/backend/accounts/models.py b/backend/accounts/models.py index be1b122..a4262ea 100644 --- a/backend/accounts/models.py +++ b/backend/accounts/models.py @@ -1,20 +1,19 @@ from django.db import models -# Create your models here. from django.contrib.auth.models import AbstractUser class CustomUser(AbstractUser): # เพิ่มฟิลด์ที่ต้องการ เช่น phone_number phone_number = models.CharField(max_length=20, blank=True, null=True, unique=True) - # ตัวอย่าง: - # is_customer = models.BooleanField(default=False) - - # ถ้าต้องการให้ email เป็น Unique (ไม่ซ้ำกัน) email = models.EmailField(unique=True) - # Field ที่ใช้สำหรับการล็อกอิน (ถ้าไม่ใช่ username) - # USERNAME_FIELD = 'email' - # REQUIRED_FIELDS = ['username'] # ถ้าเปลี่ยน USERNAME_FIELD ต้องกำหนด REQUIRED_FIELDS + # เพิ่มฟิลด์ Role สำหรับ RBAC ที่กำหนดเอง + ROLE_CHOICES = [ + ('ADMIN', 'Administrator'), + ('OPERATOR', 'Operator'), + ('VIEWER', 'Viewer'), + ] + role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='VIEWER') - # ไม่ต้องใส่ pass เพราะมันสืบทอดมาจาก AbstractUser + # ไม่ต้องเปลี่ยนส่วนอื่นๆ ถ้าสืบทอดจาก AbstractUser pass diff --git a/backend/accounts/serializers.py b/backend/accounts/serializers.py index b99488a..28a85d0 100644 --- a/backend/accounts/serializers.py +++ b/backend/accounts/serializers.py @@ -12,5 +12,12 @@ class UserSerializer(serializers.ModelSerializer): # Serializer สำหรับการดึงข้อมูล (ใช้แสดงข้อมูลผู้ใช้ปัจจุบัน) class Meta: model = CustomUser - fields = ('id', 'username', 'email', 'phone_number', 'first_name', 'last_name') - read_only_fields = ('id', 'username') + fields = ( + 'id', 'username', 'email', 'phone_number', 'first_name', 'last_name', + # เพิ่มฟิลด์สถานะสิทธิ์/Role สำหรับ RBAC + 'is_active', 'is_staff', 'is_superuser', + # เพิ่ม 'role' ใน model + 'role', + ) + # ตั้งค่า is_active, is_staff, is_superuser เป็น read_only + read_only_fields = ('id', 'username', 'is_active', 'is_staff', 'is_superuser', 'role') diff --git a/backend/core/settings.py b/backend/core/settings.py index 3ea7d36..f6c38ae 100644 --- a/backend/core/settings.py +++ b/backend/core/settings.py @@ -50,6 +50,8 @@ THIRD_PARTY_APPS = [ 'django_bolt', 'rest_framework', 'corsheaders', + 'drf_spectacular', + 'drf_spectacular_sidecar', ] LOCAL_APPS = [ @@ -57,6 +59,7 @@ LOCAL_APPS = [ 'accounts', 'user_profile', 'permissions', + 'model_registry' ] INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS @@ -171,6 +174,8 @@ AUTH_USER_MODEL = 'accounts.CustomUser' # ต้องชี้ไปที่ M # 2. ตั้งค่า REST Framework REST_FRAMEWORK = { + 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', + 'DEFAULT_AUTHENTICATION_CLASSES': ( # ใช้ JWT เป็นวิธีการยืนยันตัวตนหลัก 'rest_framework_simplejwt.authentication.JWTAuthentication', @@ -228,4 +233,61 @@ CELERY_RESULT_BACKEND = f'redis://{REDIS_HOST}:{REDIS_PORT}/0' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' -CELERY_TIMEZONE = 'Asia/Bangkok' \ No newline at end of file +CELERY_TIMEZONE = 'Asia/Bangkok' + +# ---------------------------------------------------------------------- +# SPECTACULAR CONFIGURATION +# ---------------------------------------------------------------------- + +SPECTACULAR_SETTINGS = { + # ชื่อโครงการของคุณ + 'TITLE': 'MONAI MLOps Service API', + + # คำอธิบายสั้นๆ ของโครงการ + 'DESCRIPTION': 'API Gateway and Model Registry for Medical AI Inference Services (Django DRF + FastAPI/MONAI).', + + # เวอร์ชัน API + 'VERSION': 'v1', + + # กำหนด URL ที่ใช้ในการสร้าง Schema (เพื่อให้รวมทุก Endpoints) + 'SERVE_URLCONF': 'core.urls', + + # กำหนดให้ใช้ Sidecar เพื่อการแสดงผลแบบออฟไลน์ + 'SWAGGER_UI_DIST': 'SIDECAR', + 'SWAGGER_UI_FAVICON_HREF': 'SIDECAR', + 'REDOC_DIST': 'SIDECAR', + + # กำหนด Authentication สำหรับ Doc (แสดงช่องใส่ JWT Token ใน Swagger) + 'SECURITY': [ + { + 'BearerAuth': { # ชื่อนี้จะใช้ใน Components/SecuritySchemes + 'type': 'http', + 'scheme': 'bearer', + 'bearerFormat': 'JWT', + } + } + ], + # ----------------------------------------------------------- + # การจัดเรียงและกำหนดชื่อ Tags + # ----------------------------------------------------------- + 'TAGS': [ + { + 'name': '1. Authentication & User Management', + 'description': 'Endpoints for JWT token management, login, and user profile operations (Djoser).', + #'exclude': False, # ไม่ต้องระบุ, แต่ DRF Spectacular จะรู้ว่าต้องใช้ Tag นี้แทน 'v1' + }, + { + # ให้เป็นชื่อใหม่ที่ไม่ซ้ำกัน หรือจัดการลำดับใหม่** + 'name': '2. Model Registry & Metadata Management', + 'description': 'CRUD operations for managing AI Service metadata, URLs, and versions.', + }, + { + 'name': '3. MLOps Control & Service Orchestration', + 'description': 'Actions to test service health, set model status (Hot Swap), and proxy inference requests.', + }, + ], + 'POSTPROCESSING_HOOKS': [ + 'core.spectacular_hooks.rename_djoser_tags', + ], + # ตั้งค่าอื่น ๆ (ถ้าจำเป็น) +} \ No newline at end of file diff --git a/backend/core/spectacular_hooks.py b/backend/core/spectacular_hooks.py new file mode 100644 index 0000000..5a992e4 --- /dev/null +++ b/backend/core/spectacular_hooks.py @@ -0,0 +1,13 @@ +# core/spectacular_hooks.py +def rename_djoser_tags(result, generator, request, public): + """ + เปลี่ยน Tag 'v1' ของ Djoser ให้เป็นชื่อ Tag ที่ต้องการ + """ + # result คือ OpenAPI spec เป็น dict + paths = result.get('paths', {}) + for path, path_item in paths.items(): + for method, operation in path_item.items(): + tags = operation.get('tags', []) + if 'v1' in tags: + operation['tags'] = ['1. Authentication & User Management'] + return result diff --git a/backend/core/urls.py b/backend/core/urls.py index a26824d..c3be368 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -18,13 +18,34 @@ from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter +from model_registry.views.ai_model_viewset import AiModelRegistryViewSet +from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView + # 1. กำหนดตัวแปร router ก่อนใช้งาน router = DefaultRouter() +# 2. ลงทะเบียน API ViewSets (Project-Level Routing) +# URL: /api/v1/models/ +router.register( + r'models', + AiModelRegistryViewSet, + basename='aimodel' # basename จำเป็นเมื่อ ViewSet ไม่ได้สืบทอดจาก Model +) + +# 3. ลงทะเบียน ViewSet อื่น ๆ urlpatterns = [ path('admin/', admin.site.urls), - # 2. Endpoints สำหรับการยืนยันตัวตน (Login, Logout, Register) + # Schema OpenAPI + path('api/schema/', SpectacularAPIView.as_view(), name='schema'), + + # Swagger UI + path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), + + # Redoc UI + path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), + + # Endpoints สำหรับการยืนยันตัวตน (Login, Logout, Register) path('api/v1/auth/', include('djoser.urls')), # /users/ (Register/Update/Me), /users/set_password path('api/v1/auth/', include('djoser.urls.jwt')), # /jwt/create (Login), /jwt/refresh (Refresh Token) diff --git a/backend/model_registry/__init__.py b/backend/model_registry/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/model_registry/admin.py b/backend/model_registry/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/model_registry/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/model_registry/apps.py b/backend/model_registry/apps.py new file mode 100644 index 0000000..4ce609e --- /dev/null +++ b/backend/model_registry/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ModelRegistryConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'model_registry' diff --git a/backend/model_registry/migrations/0001_initial.py b/backend/model_registry/migrations/0001_initial.py new file mode 100644 index 0000000..b4f1eca --- /dev/null +++ b/backend/model_registry/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 5.2.7 on 2025-11-08 03:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='AiModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True, verbose_name='ชื่อโมเดล')), + ('model_version', models.CharField(default='v1.0.0', max_length=50, verbose_name='เวอร์ชัน')), + ('developer', models.CharField(blank=True, max_length=255, null=True, verbose_name='ผู้พัฒนา/ทีม')), + ('base_url', models.URLField(max_length=500, verbose_name='Base URL ของ AI Service (Internal)')), + ('inference_path', models.CharField(max_length=255, verbose_name='Endpoint Path สำหรับ Inference')), + ('status', models.CharField(choices=[('ACTIVE', 'ใช้งาน'), ('INACTIVE', 'ไม่ใช้งาน'), ('TESTING', 'กำลังทดสอบ')], default='INACTIVE', max_length=20, verbose_name='สถานะบริการ')), + ('auth_required', models.BooleanField(default=False, verbose_name='ต้องการ Internal Auth Key')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'AI Model Registry', + 'verbose_name_plural': 'AI Model Registry', + }, + ), + ] diff --git a/backend/model_registry/migrations/__init__.py b/backend/model_registry/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/model_registry/models.py b/backend/model_registry/models.py new file mode 100644 index 0000000..a61987f --- /dev/null +++ b/backend/model_registry/models.py @@ -0,0 +1,37 @@ +from django.db import models + +class AiModel(models.Model): + # 1. ข้อมูลพื้นฐานและการลงทะเบียน + name = models.CharField(max_length=255, unique=True, verbose_name="ชื่อโมเดล") + model_version = models.CharField(max_length=50, default="v1.0.0", verbose_name="เวอร์ชัน") + developer = models.CharField(max_length=255, blank=True, null=True, verbose_name="ผู้พัฒนา/ทีม") + + # 2. ข้อมูลการเรียกใช้ (API Management) + base_url = models.URLField(max_length=500, verbose_name="Base URL ของ AI Service (Internal)") + inference_path = models.CharField(max_length=255, verbose_name="Endpoint Path สำหรับ Inference") + # ตัวอย่าง: base_url="http://ai_model_server:8001/", inference_path="inference/spleen/" + + # 3. สถานะและการควบคุม + status_choices = [ + ('ACTIVE', 'ใช้งาน'), + ('INACTIVE', 'ไม่ใช้งาน'), + ('TESTING', 'กำลังทดสอบ'), + ] + status = models.CharField(max_length=20, choices=status_choices, default='INACTIVE', verbose_name="สถานะบริการ") + + auth_required = models.BooleanField(default=False, verbose_name="ต้องการ Internal Auth Key") + + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + def full_inference_url(self): + # สร้าง Full URL สำหรับ DRF ใช้เรียก (Proxy) + return f"{self.base_url.rstrip('/')}/{self.inference_path.lstrip('/')}" + + def __str__(self): + return f"{self.name} ({self.model_version}) - {self.status}" + + class Meta: + verbose_name = "AI Model Registry" + verbose_name_plural = "AI Model Registry" + # สามารถเพิ่ม unique_together (name, model_version) ได้ในภายหลัง \ No newline at end of file diff --git a/backend/model_registry/repositories/__init__.py b/backend/model_registry/repositories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/model_registry/repositories/ai_model_repository.py b/backend/model_registry/repositories/ai_model_repository.py new file mode 100644 index 0000000..eb30a9e --- /dev/null +++ b/backend/model_registry/repositories/ai_model_repository.py @@ -0,0 +1,23 @@ +from ..models import AiModel +from typing import List, Optional + +class AiModelRepository: + """จัดการการเข้าถึงฐานข้อมูลสำหรับ AiModel โดยเฉพาะ""" + + def get_all(self) -> List[AiModel]: + return AiModel.objects.all().order_by('name', '-model_version') + + def get_by_id(self, pk: int) -> Optional[AiModel]: + try: + return AiModel.objects.get(pk=pk) + except AiModel.DoesNotExist: + return None + + def save(self, model_instance: AiModel) -> AiModel: + """ใช้สำหรับ Create และ Update""" + model_instance.save() + return model_instance + + def delete(self, model_instance: AiModel): + model_instance.delete() + # Logic อื่น ๆ ที่เกี่ยวข้องกับการเข้าถึง DB \ No newline at end of file diff --git a/backend/model_registry/serializers/__init__.py b/backend/model_registry/serializers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/model_registry/serializers/ai_model_serializer.py b/backend/model_registry/serializers/ai_model_serializer.py new file mode 100644 index 0000000..7a9f1b7 --- /dev/null +++ b/backend/model_registry/serializers/ai_model_serializer.py @@ -0,0 +1,16 @@ +from rest_framework import serializers +from ..models import AiModel + +class AiModelSerializer(serializers.ModelSerializer): + # Read-only field สำหรับแสดงผล Full URL ที่ DRF จะใช้ Proxy + full_endpoint = serializers.SerializerMethodField() + + class Meta: + model = AiModel + fields = '__all__' + read_only_fields = ('created_at', 'updated_at', 'full_endpoint') + + def get_full_endpoint(self, obj: AiModel) -> str: + return obj.full_inference_url() + + # สามารถเพิ่ม Custom Validation ที่นี่: เช่น ตรวจสอบความถูกต้องของ base_url format \ No newline at end of file diff --git a/backend/model_registry/services/__init__.py b/backend/model_registry/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/model_registry/services/ai_model_service.py b/backend/model_registry/services/ai_model_service.py new file mode 100644 index 0000000..6630a08 --- /dev/null +++ b/backend/model_registry/services/ai_model_service.py @@ -0,0 +1,58 @@ +from ..repositories.ai_model_repository import AiModelRepository +from ..models import AiModel +from typing import Optional, List +import requests +from django.conf import settings # ใช้สำหรับ Configs ภายนอก/Secrets + +class ConnectionError(Exception): + """Custom Exception สำหรับการเชื่อมต่อล้มเหลว""" + pass + +class AiModelService: + def __init__(self, repository: AiModelRepository): + self.repo = repository + + def get_all_models(self) -> List[AiModel]: + return self.repo.get_all() + + def create_model(self, validated_data: dict) -> AiModel: + # Business Logic: ตรวจสอบความซ้ำซ้อน, การตั้งค่าเริ่มต้น + new_model = AiModel(**validated_data) + return self.repo.save(new_model) + + def test_connection(self, pk: int) -> dict: + """Logic สำหรับเรียก HTTP Ping ไปยัง AI Service ภายนอก""" + model = self.repo.get_by_id(pk) + if not model: + raise ValueError("Model not found") + + # ใช้ Root URL ของ Service สำหรับ Ping + test_url = model.base_url.rstrip('/') + '/' + + try: + # ใช้ requests เพื่อเรียก HTTP (ใช้ httpx ถ้าต้องการ Async) + response = requests.get(test_url, timeout=5) + response.raise_for_status() # Raise error for 4xx or 5xx + + return { + "status": "success", + "message": f"Successfully pinged {test_url}", + "response_status": response.status_code, + "response_data": response.json() + } + except requests.exceptions.RequestException as e: + # แปลง HTTP Error เป็น Custom Exception ของ Business Logic + raise ConnectionError(f"Connection failed to {test_url}: {e}") + + def set_status(self, pk: int, new_status: str) -> Optional[AiModel]: + # Business Logic: การเปลี่ยนสถานะต้องผ่าน Service + model = self.repo.get_by_id(pk) + if model: + # Logic: มีเงื่อนไขว่าต้องผ่าน TESTING ก่อนไป ACTIVE + if model.status == 'TESTING' and new_status == 'ACTIVE': + # Logic: Trigger Hot Swap ใน FastAPI Service ก่อนเปลี่ยนสถานะ (ถ้าต้องการ) + pass + + model.status = new_status + return self.repo.save(model) + return None \ No newline at end of file diff --git a/backend/model_registry/tests.py b/backend/model_registry/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/model_registry/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/model_registry/views.py b/backend/model_registry/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backend/model_registry/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/backend/model_registry/views/__init__.py b/backend/model_registry/views/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/model_registry/views/ai_model_viewset.py b/backend/model_registry/views/ai_model_viewset.py new file mode 100644 index 0000000..42bc7fd --- /dev/null +++ b/backend/model_registry/views/ai_model_viewset.py @@ -0,0 +1,72 @@ +from rest_framework import viewsets, permissions, status +from rest_framework.response import Response +from rest_framework.decorators import action +from drf_spectacular.utils import extend_schema, extend_schema_view + +from ..models import AiModel +from ..serializers.ai_model_serializer import AiModelSerializer +from ..repositories.ai_model_repository import AiModelRepository +from ..services.ai_model_service import AiModelService, ConnectionError + +# Dependency Injection: สร้าง Instance ของ Repository และ Service +# สำหรับโปรเจกต์ขนาดเล็กสามารถทำแบบนี้ได้ +repo = AiModelRepository() +service = AiModelService(repository=repo) + +@extend_schema_view( + # 1. การดำเนินการ CRUD ปกติ: จัดอยู่ใน Model Registry + list=extend_schema(tags=['2. Model Registry & Metadata Management']), + retrieve=extend_schema(tags=['2. Model Registry & Metadata Management']), + create=extend_schema(tags=['2. Model Registry & Metadata Management']), + update=extend_schema(tags=['2. Model Registry & Metadata Management']), + partial_update=extend_schema(tags=['2. Model Registry & Metadata Management']), + destroy=extend_schema(tags=['2. Model Registry & Metadata Management']), +) +class AiModelRegistryViewSet(viewsets.ModelViewSet): + queryset = AiModel.objects.all() + serializer_class = AiModelSerializer + permission_classes = [permissions.IsAdminUser] + + # ----------------------------------------------- + # Override Create/List (เรียกใช้ Service Layer) + # ----------------------------------------------- + def get_queryset(self): + # List/Retrieve จะเรียก Service Layer แทนการเรียก ORM โดยตรง + return service.get_all_models() + + def create(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + + try: + new_model = service.create_model(serializer.validated_data) + return Response(self.get_serializer(new_model).data, status=status.HTTP_201_CREATED) + except Exception as e: + return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST) + + # ----------------------------------------------- + # Custom Action: ทดสอบการเชื่อมต่อ + # ----------------------------------------------- + @extend_schema(tags=['3. MLOps Control & Service Orchestration']) + @action(detail=True, methods=['post'], url_path='test-connection') + def test_connection(self, request, pk=None): + try: + result = service.test_connection(pk=int(pk)) + return Response(result) + except ValueError as e: + return Response({"detail": str(e)}, status=status.HTTP_404_NOT_FOUND) + except ConnectionError as e: + # Response ด้วย error ที่ชัดเจนจากการเชื่อมต่อ + return Response({"status": "error", "detail": str(e)}, status=status.HTTP_400_BAD_REQUEST) + + @extend_schema(tags=['3. MLOps Control & Service Orchestration']) + @action(detail=True, methods=['patch'], url_path='set-status') + def set_status(self, request, pk=None): + new_status = request.data.get('status') + if not new_status or new_status not in [choice[0] for choice in AiModel.status_choices]: + return Response({"detail": "Invalid status provided."}, status=status.HTTP_400_BAD_REQUEST) + + updated_model = service.set_status(pk=int(pk), new_status=new_status) + if updated_model: + return Response(self.get_serializer(updated_model).data) + return Response({"detail": "Model not found."}, status=status.HTTP_404_NOT_FOUND) \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index 84e2f83..ff1c0a9 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -11,4 +11,6 @@ django-redis # สำหรับเชื่อมต่อ Django redis # ไคลเอนต์ Python สำหรับ Redis celery # ตัว Worker boto3 -python-dotenv \ No newline at end of file +python-dotenv +drf-spectacular +drf-spectacular-sidecar \ No newline at end of file diff --git a/web/package-lock.json b/web/package-lock.json index 50b923e..5af736d 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,11 +8,21 @@ "name": "web", "version": "0.0.0", "dependencies": { + "@heroicons/react": "^2.2.0", + "@hookform/resolvers": "^5.2.2", + "@reduxjs/toolkit": "^2.10.1", "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.7", + "axios": "^1.13.2", "daisyui": "^5.3.10", "react": "^19.1.1", "react-dom": "^19.1.1", - "tailwindcss": "^4.1.16" + "react-hook-form": "^7.66.0", + "react-icons": "^5.5.0", + "react-redux": "^9.2.0", + "react-router-dom": "^7.9.5", + "tailwindcss": "^4.1.16", + "yup": "^1.7.1" }, "devDependencies": { "@eslint/js": "^9.36.0", @@ -907,6 +917,27 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, + "node_modules/@hookform/resolvers": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz", + "integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==", + "license": "MIT", + "dependencies": { + "@standard-schema/utils": "^0.3.0" + }, + "peerDependencies": { + "react-hook-form": "^7.55.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1004,6 +1035,32 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.10.1.tgz", + "integrity": "sha512-/U17EXQ9Do9Yx4DlNGU6eVNfZvFJfYpUtRRdLf19PbPjdWBxNlxGZXywQZ1p1Nz8nMkWplTI7iD/23m07nolDA==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.2.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.43", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz", @@ -1297,6 +1354,18 @@ "win32" ] }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@tailwindcss/node": { "version": "4.1.16", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", @@ -1554,6 +1623,32 @@ "vite": "^5.2.0 || ^6 || ^7" } }, + "node_modules/@tanstack/query-core": { + "version": "5.90.7", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.7.tgz", + "integrity": "sha512-6PN65csiuTNfBMXqQUxQhCNdtm1rV+9kC9YwWAIKcaxAauq3Wu7p18j3gQY3YIBJU70jT/wzCCZ2uqto/vQgiQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.7.tgz", + "integrity": "sha512-wAHc/cgKzW7LZNFloThyHnV/AX9gTg3w5yAv0gvQHPZoCnepwqCMtzbuPbb2UvfvO32XZ46e8bPOYbfZhzVnnQ==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1616,7 +1711,7 @@ "version": "19.2.2", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -1632,6 +1727,12 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@vitejs/plugin-react": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.0.tgz", @@ -1716,6 +1817,23 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1778,6 +1896,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1846,6 +1977,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1860,6 +2003,15 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -1879,7 +2031,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/daisyui": { @@ -1916,6 +2068,15 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -1925,6 +2086,20 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.243", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.243.tgz", @@ -1945,6 +2120,51 @@ "node": ">=10.13.0" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.11", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", @@ -2275,6 +2495,42 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2289,6 +2545,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2299,6 +2564,43 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2325,6 +2627,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2341,6 +2655,45 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2351,6 +2704,16 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -2799,6 +3162,36 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2990,6 +3383,18 @@ "node": ">= 0.8.0" } }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3021,6 +3426,54 @@ "react": "^19.2.0" } }, + "node_modules/react-hook-form": { + "version": "7.66.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz", + "integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", @@ -3031,6 +3484,65 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.5.tgz", + "integrity": "sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.5.tgz", + "integrity": "sha512-mkEmq/K8tKN63Ae2M7Xgz3c9l9YNbY+NHH6NNeUmLA3kDkhKXRsNb/ZpxaEunvGo2/3YXdk5EJU3Hxp3ocaBPw==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.5" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3098,6 +3610,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3175,6 +3693,12 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -3191,6 +3715,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3204,6 +3734,18 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", @@ -3245,6 +3787,15 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "version": "7.1.12", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", @@ -3364,6 +3915,18 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } } } } diff --git a/web/package.json b/web/package.json index c6d48a9..d86172d 100644 --- a/web/package.json +++ b/web/package.json @@ -10,11 +10,21 @@ "preview": "vite preview" }, "dependencies": { + "@heroicons/react": "^2.2.0", + "@hookform/resolvers": "^5.2.2", + "@reduxjs/toolkit": "^2.10.1", "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.7", + "axios": "^1.13.2", "daisyui": "^5.3.10", "react": "^19.1.1", "react-dom": "^19.1.1", - "tailwindcss": "^4.1.16" + "react-hook-form": "^7.66.0", + "react-icons": "^5.5.0", + "react-redux": "^9.2.0", + "react-router-dom": "^7.9.5", + "tailwindcss": "^4.1.16", + "yup": "^1.7.1" }, "devDependencies": { "@eslint/js": "^9.36.0", diff --git a/web/public/favicon-32x32.svg b/web/public/favicon-32x32.svg new file mode 100644 index 0000000..70627f0 --- /dev/null +++ b/web/public/favicon-32x32.svg @@ -0,0 +1,16 @@ + + + +Created with Fabric.js 2.4.6 + + + + + + + + + DDO + + + \ No newline at end of file diff --git a/web/public/intro.png b/web/public/intro.png new file mode 100644 index 0000000000000000000000000000000000000000..001ec91dd7828eda40c7db88590cf1af5091e07a GIT binary patch literal 189330 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 fCgcAdW3FH$gW^&hxOIK#WFgIV($@~6-f>OC* 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 LEyWM=7D4|HD{$3J literal 0 HcmV?d00001 diff --git a/web/src/App.jsx b/web/src/App.jsx index 3e4fa0f..eda475f 100644 --- a/web/src/App.jsx +++ b/web/src/App.jsx @@ -1,11 +1,22 @@ -function App() { +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import AuthRoutes from "./routes/AuthRoutes.jsx"; +import PrivateRoutes from "./routes/PrivateRoutes.jsx"; + + +function App() { return ( - <> -

ทดสอบนำเข้าฟอนต์ในโปรเจกต์ Daisy UI

- - + // ต้องห่อหุ้มด้วย Provider ของ Redux และ QueryClient ใน main.jsx + + + {/* Private Routes: ตรวจสอบล็อกอินก่อนเข้า /dashboard/* */} + }/> + + {/* Auth Routes: สำหรับ /login, /register และเป็น Fallback หลัก */} + }/> + + ) } -export default App +export default App \ No newline at end of file diff --git a/web/src/app/store.js b/web/src/app/store.js new file mode 100644 index 0000000..d7f53cf --- /dev/null +++ b/web/src/app/store.js @@ -0,0 +1,23 @@ +import { configureStore } from '@reduxjs/toolkit'; +import authReducer from '../features/auth/authSlice'; + +export const store = configureStore({ + reducer: { + // กำหนด Reducer หลัก + auth: authReducer, + // [เพิ่ม Reducer อื่น ๆ ที่นี่] + }, + // ปิด serializableCheck ใน Production เพื่อประสิทธิภาพ + middleware: (getDefaultMiddleware) => getDefaultMiddleware({ + serializableCheck: { + // อาจจะต้องยกเว้น action types บางตัวที่ไม่ serialize ได้ + }, + }), + // ใน Vite ตัวแปร import.meta.env.MODE จะถูก ตั้งค่าให้อัตโนมัติ ตามคำสั่งที่ใช้ตอนรัน เช่น + // vite หรือ npm run dev "development" + // vite build หรือ npm run build "production" + devTools: import.meta.env.MODE !== 'production', +}); + +// Export ฟังก์ชันเพื่อให้ Components ภายนอก (เช่น axiosClient) เข้าถึง store instance ได้ +export const getStore = () => store; \ No newline at end of file diff --git a/web/src/components/ErrorText.jsx b/web/src/components/ErrorText.jsx new file mode 100644 index 0000000..a477498 --- /dev/null +++ b/web/src/components/ErrorText.jsx @@ -0,0 +1,17 @@ +import React from 'react'; + +function ErrorText({ children, styleClass }) { + const defaultClasses = "p-3 bg-red-100 text-red-600 rounded-lg text-sm font-medium border border-red-300 break-words whitespace-normal"; + + return ( + <> + {children && ( +

+ {children} +

+ )} + + ); +} + +export default ErrorText; diff --git a/web/src/components/InputText.jsx b/web/src/components/InputText.jsx new file mode 100644 index 0000000..32ec38c --- /dev/null +++ b/web/src/components/InputText.jsx @@ -0,0 +1,28 @@ +import React, { forwardRef } from "react"; + +// ใช้ forwardRef เพื่อให้ RHF สามารถส่ง ref มาที่ input ได้ +const InputText = forwardRef( + // รับ Props ที่จำเป็นสำหรับ RHF (ref, name, value, onChange, onBlur) + // และรับ error object เพื่อแสดงข้อความ Validation + ({ labelTitle, labelStyle, type, containerStyle, placeholder, error, ...rest }, ref) => { + + return( +
+ + + {/* แสดงข้อความ Error ที่ส่งมาจาก RHF errors object */} + {error &&

{error.message}

} +
+ ); + } +); + +export default InputText; \ No newline at end of file diff --git a/web/src/components/LandingIntro.jsx b/web/src/components/LandingIntro.jsx new file mode 100644 index 0000000..a309ed4 --- /dev/null +++ b/web/src/components/LandingIntro.jsx @@ -0,0 +1,31 @@ +import TemplatePointers from "./TemplatePointers.jsx" + +function LandingIntro(){ + + return( +
+
+
+ +

+ {/* ไฟล์ logo192.png ใน /public */} + App Logo + DDO Console +

+ + {/* ไฟล์ intro.png ใน /public */} +
+ Admin Template +
+ + + +
+ +
+
+ ) + +} + +export default LandingIntro diff --git a/web/src/components/LoginForm.jsx b/web/src/components/LoginForm.jsx new file mode 100644 index 0000000..6b843bd --- /dev/null +++ b/web/src/components/LoginForm.jsx @@ -0,0 +1,122 @@ +import { useState } from 'react'; +import { Link } from 'react-router-dom'; + +// นำเข้า Hooks และ Library ที่จำเป็น +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; + +// นำเข้า Hook API และ Components +import { useLoginMutation } from '../services/authApi'; +import LandingIntro from './LandingIntro'; +import InputText from './InputText'; + +import { loginSchema } from '../schemas/authSchema'; + +export default function LoginForm() { + // 1. Hook สำหรับเรียก API ล็อกอิน + const loginMutation = useLoginMutation(); + const [apiErrorMessage, setApiErrorMessage] = useState(""); + + // 2. Hook Form Setup + const { + register, + handleSubmit, + formState: { errors } + } = useForm({ + resolver: yupResolver(loginSchema), + defaultValues: { + username: '', + password: '' + } + }); + + // 3. Form Submission Logic + const onSubmit = (data) => { + setApiErrorMessage(""); + + // เรียกใช้ Mutation (Token + Fetch User) + loginMutation.mutate({ + // ส่ง 'username' และ 'password' ตรงตาม API + username: data.username, + password: data.password + }, { + onError: (error) => { + setApiErrorMessage(error.message || "การล็อกอินล้มเหลว กรุณาตรวจสอบข้อมูล"); + } + }); + } + + const loading = loginMutation.isPending; + + return ( +
+
+ +
+ +
+ +
+

เข้าสู่ระบบ DDO Console

+ +
+ + {/* API Error Alert */} + {apiErrorMessage && ( +
+ + {apiErrorMessage} +
+ )} + +
+ {/* Username Input (เชื่อม RHF) */} + + + {/* Password Input (เชื่อม RHF) */} + +
+ +
+ + + ลืมรหัสผ่าน? + + +
+ + {/* ปุ่ม Submit */} + + +
+ ยังไม่มีบัญชีใช่ไหม? + + + ลงทะเบียน + + +
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/web/src/components/SidebarSubmenu.jsx b/web/src/components/SidebarSubmenu.jsx new file mode 100644 index 0000000..9b78ccb --- /dev/null +++ b/web/src/components/SidebarSubmenu.jsx @@ -0,0 +1,87 @@ +// src/components/SidebarSubmenu.jsx (ปรับปรุงสำหรับ RBAC) + +import ChevronDownIcon from '@heroicons/react/24/outline/ChevronDownIcon'; +import { useEffect, useState } from 'react'; +import { NavLink, useLocation } from 'react-router-dom'; +import { useSelector } from 'react-redux'; + +// Component นี้คาดหวังว่าฟังก์ชัน canAccess จะถูกส่งมาจาก MainLayout หรือสร้างขึ้นใหม่ + +function SidebarSubmenu({ submenu, name, icon, closeMobileSidebar }) { + const location = useLocation(); + const [isExpanded, setIsExpanded] = useState(false); + const role = useSelector(state => state.auth.role); // ดึง Role จาก Redux + + // ฟังก์ชันตรวจสอบสิทธิ์ (ควรมาจาก MainLayout แต่เราจะใช้ Logic พื้นฐาน) + const canAccess = (requiredRole) => { + if (role === 'admin') return true; + if (!requiredRole) return true; + const allowedRoles = Array.isArray(requiredRole) ? requiredRole : [requiredRole]; + return allowedRoles.includes(role); + }; + + // เปิด Submenu หาก Path ปัจจุบันอยู่ใน Submenu นั้น + useEffect(() => { + // ตรวจสอบว่ามีเมนูย่อยใดที่ผู้ใช้เข้าถึงได้และเป็น Path ปัจจุบันหรือไม่ + const isActive = submenu.some( + m => canAccess(m.requiredRole) && m.path === location.pathname + ); + if (isActive) { + setIsExpanded(true); + } + }, [location.pathname, submenu, role]); // เพิ่ม role ใน dependency array + + return ( +
+ {/** Route header */} + setIsExpanded(!isExpanded)} + > +
+ {icon} + {name} +
+ +
+ + {/** Submenu list */} +
+
    + {submenu.map((m, k) => { + // กรองเมนูย่อยตามสิทธิ์ (RBAC) + if (!canAccess(m.requiredRole)) return null; + + return ( +
  • + {/* ใช้ NavLink เพื่อแสดงสถานะ Active และใช้ onClick เพื่อปิด Sidebar (สำหรับ Mobile) */} + + `text-base ${isActive ? 'bg-base-200 text-primary font-semibold' : 'hover:bg-base-400'}` + } + > + {m.icon} {m.name} + + {/* แถบสี Primary แสดงสถานะ Active */} + {location.pathname === m.path ? ( + + ) : null} + +
  • + ); + })} +
+
+
+ ); +} + +export default SidebarSubmenu; \ No newline at end of file diff --git a/web/src/components/Subtitle.jsx b/web/src/components/Subtitle.jsx new file mode 100644 index 0000000..c2db806 --- /dev/null +++ b/web/src/components/Subtitle.jsx @@ -0,0 +1,12 @@ +import React from 'react'; + +function Subtitle({ styleClass, children }) { + return ( + // ใช้ text-2xl เพื่อให้ดูโดดเด่นขึ้นสำหรับหัวข้อหน้า +
+ {children} +
+ ); +} + +export default Subtitle; diff --git a/web/src/components/TemplatePointers.jsx b/web/src/components/TemplatePointers.jsx new file mode 100644 index 0000000..3b2e94f --- /dev/null +++ b/web/src/components/TemplatePointers.jsx @@ -0,0 +1,34 @@ +function TemplatePointers(){ + return( + <> +

DDO Console Features

+ + {/* 1. ส่วน A: Dashboard & Monitoring */} +

+ ✓ ความน่าเชื่อถือของข้อมูล (HA Data Layer): ใช้ CockroachDB Cluster (3 Node HA) เพื่อรับประกันความต่อเนื่องของบริการฐานข้อมูล +

+ + {/* 2. ส่วน B: Control & Management (MLOps Flow) */} +

+ ✓ Asynchronous AI Processing: ประมวลผลงานหนักผ่าน Celery เพื่อให้ Frontend ตอบสนองทันที และจัดการคิวงานได้ +

+ + {/* 3. ส่วน C: Data Governance & Discovery (เน้น Medical/AI) */} +

+ ✓ AI Model Serving Layer: บริการ Model Inference พร้อมจัดการไฟล์ภาพขนาดใหญ่ด้วย MinIO (S3) +

+ + {/* 4. ส่วน Security (การยืนยันตัวตนและการเข้าถึง) */} +

+ ✓ Security & Gateway: การจัดการผู้ใช้และสิทธิ์ (JWT/RBAC) ผ่าน Django DRF ซึ่งทำหน้าที่เป็น Lightweight Gateway หลัก +

+ + {/* 5. ส่วนสถาปัตยกรรมกระจายศูนย์ */} +

+ ✓ สถาปัตยกรรมกระจายศูนย์ (Distributed): สร้างบนเทคโนโลยีหลัก เช่น MONAI, Django DRF, CockroachDB HA, Redis Cache และ MinIO Object Storage +

+ + ) +} + +export default TemplatePointers \ No newline at end of file diff --git a/web/src/components/TitleCard.jsx b/web/src/components/TitleCard.jsx new file mode 100644 index 0000000..ecfd5bc --- /dev/null +++ b/web/src/components/TitleCard.jsx @@ -0,0 +1,33 @@ +import React from 'react'; +import Subtitle from './Subtitle'; + +function TitleCard({ title, children, topMargin, TopSideButtons }) { + return ( +
+ + {/* Title และ Top Side Buttons */} +
+ + {title} + + + {/* Top side button, show only if present */} + {TopSideButtons && ( +
+ {TopSideButtons} +
+ )} +
+ + {/* Divider (เส้นแบ่ง) */} +
+ + {/* Card Body */} +
+ {children} +
+
+ ); +} + +export default TitleCard; diff --git a/web/src/config/sidebarRoutes.jsx b/web/src/config/sidebarRoutes.jsx new file mode 100644 index 0000000..a70ff52 --- /dev/null +++ b/web/src/config/sidebarRoutes.jsx @@ -0,0 +1,108 @@ +import { FaTachometerAlt, FaCog, FaDatabase, FaCogs, FaProjectDiagram, FaFlask, + FaClipboardList, FaHeartbeat } from 'react-icons/fa'; + + +const routes = [ + { + path: '/dashboard', + icon: , + name: 'แดชบอร์ด/ภาพรวม', + // ไม่ต้องระบุ requiredRole (viewer/admin เข้าถึงได้เสมอ) + }, + + // ----------------================-- + // กลุ่ม: Data & MLOps + // ---------------------------------- + { + path: '', + icon: , + name: 'ข้อมูล & AI/MLOps', // ปรับชื่อเล็กน้อย + // Roles: ใครก็ตามที่จัดการข้อมูล/โมเดล ควรเข้าถึงได้ + requiredRole: ['viewer', 'admin', 'manager'], + submenu: [ + // เพิ่ม Endpoint สำหรับเรียกใช้ AI Inference Proxy + { + path: + '/dashboard/inference-run', + name: 'AI Inference (Run)', // ชื่อสำหรับเรียกใช้ AI จริง + requiredRole: ['viewer', 'admin', 'manager'], // ผู้ใช้ทั่วไปก็ควรเรียกได้ + }, + { + path: + '/dashboard/model-registry', + name: 'Model Registry & Control', // รวม CRUD และ Control ไว้ในหน้าเดียว + // Roles: จำกัดเฉพาะผู้ที่มีสิทธิ์จัดการโมเดล (Admin/Manager) + requiredRole: ['manager', 'admin'], + }, + { + path: + '/dashboard/datasets', + name: 'Dataset Catalog (CKAN)', + requiredRole: ['viewer', 'admin', 'manager'], + }, + { + path: + '/dashboard/lineage', + name: 'Dataset Lineage', + requiredRole: ['viewer', 'admin', 'manager'], + }, + // Note: ลบ /dashboard/predict ออก เนื่องจาก /inference-run ควรจะครอบคลุม + ], + }, + + // ---------------------------------- + // กลุ่ม: Pipelines & Logs + // ---------------------------------- + { + path: '', + icon: , + name: 'Pipelines & Log', + requiredRole: ['viewer', 'admin', 'manager'], + submenu: [ + { + path: + '/dashboard/pipeline/trigger', + name: 'Pipeline Control', + // Roles: จำกัดเฉพาะผู้ที่สั่งรันได้ (Admin/Manager) + requiredRole: ['manager', 'admin'], + }, + { + path: + '/dashboard/pipeline/logs', + name: 'Pipeline Logs', + requiredRole: ['viewer', 'admin', 'manager'], + }, + { + path: + '/dashboard/pipeline/status', + name: 'Pipeline Run Status', + requiredRole: ['viewer', 'admin', 'manager'], + }, + ], + }, + + // ---------------------------------- + // กลุ่ม: การดูแลระบบ + // ---------------------------------- + { + path: '/dashboard/health', + icon: , + name: 'สถานะระบบ (Health)', + requiredRole: ['viewer', 'admin', 'manager'], + }, + { + path: '/dashboard/settings', + icon: , + name: 'ตั้งค่าระบบ', + requiredRole: ['admin'], // สำหรับ Superuser/Admin เท่านั้น + }, + +]; + + +export default routes; \ No newline at end of file diff --git a/web/src/features/auth/authSlice.js b/web/src/features/auth/authSlice.js new file mode 100644 index 0000000..b49d7a8 --- /dev/null +++ b/web/src/features/auth/authSlice.js @@ -0,0 +1,81 @@ +import { createSlice } from '@reduxjs/toolkit'; + +// ---------------------------------------------------- +// Helper Function: กำหนดบทบาท (Role) จาก Django User Object +// ---------------------------------------------------- +const determineRole = (user) => { + if (!user || !user.id) { + return 'guest'; + } + + // 1. ใช้ฟิลด์ 'role' ที่ส่งมาจาก Backend โดยตรง (ถ้ามี) + if (user.role) { + return user.role.toLowerCase(); // เช่น 'ADMIN' -> 'admin' + } + + // 2. ใช้ฟิลด์ is_superuser/is_staff เป็น Fallback + if (user.is_superuser) { + return 'admin'; + } + if (user.is_staff) { + return 'manager'; + } + // ผู้ใช้ทั่วไป + return 'viewer'; +}; + +// ---------------------------------------------------- +// ฟังก์ชันช่วยในการอ่านค่าจาก Local Storage เพื่อกำหนดสถานะเริ่มต้น +// ---------------------------------------------------- +const getInitialAuthState = () => { + const token = localStorage.getItem('token'); + const user = JSON.parse(localStorage.getItem('user')); + + // ดึง Role + const role = determineRole(user); + + return { + isAuthenticated: !!token, + user: user || null, + role: role, + }; +}; + +const initialState = getInitialAuthState(); + +const authSlice = createSlice({ + name: 'auth', + initialState, + reducers: { + // Reducer สำหรับการล็อกอินสำเร็จ + loginSuccess: (state, action) => { + state.isAuthenticated = true; + state.user = action.payload.user; + state.role = action.payload.role; + }, + + // Reducer สำหรับการออกจากระบบ + logout: (state) => { + state.isAuthenticated = false; + state.user = null; + state.role = 'guest'; + // ลบข้อมูลจาก localStorage + localStorage.removeItem('token'); + localStorage.removeItem('user'); + }, + + // Reducer สำหรับอัปเดตข้อมูลผู้ใช้ (เช่น หลังอัปเดตโปรไฟล์) + updateUser: (state, action) => { + state.user = action.payload.user; + // คำนวณ Role ใหม่จากข้อมูลที่อัปเดต + const newRole = determineRole(action.payload.user); + state.role = newRole; + localStorage.setItem('user', JSON.stringify(action.payload.user)); + // ไม่ต้องยุ่งกับ token/role storage ในนี้ถ้ามี loginSuccess/logout จัดการแล้ว + } + }, +}); + +export const { loginSuccess, logout, updateUser } = authSlice.actions; + +export default authSlice.reducer; \ No newline at end of file diff --git a/web/src/layouts/AuthLayout.jsx b/web/src/layouts/AuthLayout.jsx new file mode 100644 index 0000000..8d7faac --- /dev/null +++ b/web/src/layouts/AuthLayout.jsx @@ -0,0 +1,16 @@ +import {Outlet} from "react-router-dom"; + +export default function AuthLayout(){ + return( + <> + {/* 1. Div หลัก: จัดให้อยู่ตรงกลางจอ (ใช้ flex h-screen) */} +
+ + {/* 2. Div ภาชนะสำหรับเนื้อหา: กำหนดขนาดสูงสุด */} +
+ +
+
+ + ) +} \ No newline at end of file diff --git a/web/src/layouts/MainLayout.jsx b/web/src/layouts/MainLayout.jsx new file mode 100644 index 0000000..b80a1fa --- /dev/null +++ b/web/src/layouts/MainLayout.jsx @@ -0,0 +1,176 @@ +import React from 'react'; +import { Link, Outlet, useNavigate, NavLink, useLocation } from 'react-router-dom'; +import { useSelector, useDispatch } from 'react-redux'; +import { logout } from '../features/auth/authSlice'; +import { FaSignOutAlt, FaUserCircle } from 'react-icons/fa'; +import Bars3Icon from '@heroicons/react/24/outline/Bars3Icon'; +import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; + +import routes from '../config/sidebarRoutes'; +import SidebarSubmenu from '../components/SidebarSubmenu'; + + +export default function MainLayout() { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const location = useLocation(); // Hook สำหรับตรวจสอบ Path ปัจจุบัน + + // ดึงข้อมูลผู้ใช้และ Role จาก Redux Store + const user = useSelector(state => state.auth.user); + const role = useSelector(state => state.auth.role); + + const handleLogout = () => { + dispatch(logout()); + navigate('/login', { replace: true }); + }; + + // Logic: ฟังก์ชันตรวจสอบสิทธิ์ (RBAC) + const canAccess = (requiredRole) => { + if (role === 'admin') return true; + if (!requiredRole) return true; + + // ตรวจสอบ Role ของผู้ใช้กับ Role ที่จำเป็น + const allowedRoles = Array.isArray(requiredRole) ? requiredRole : [requiredRole]; + return allowedRoles.includes(role); + }; + + // ฟังก์ชันปิด Sidebar ใน Mobile + const closeMobileSidebar = () => { + document.getElementById('my-drawer-2').checked = false; + } + + // ฟังก์ชันสำหรับดึงชื่อเมนูตาม Path ปัจจุบัน (สำหรับ Header) + const getPageTitle = (pathname) => { + let title = "DDO Console"; + routes.forEach((route) => { + if (route.path && route.path === pathname) { + title = route.name; + } else if (route.submenu) { + route.submenu.forEach((submenuRoute) => { + if (submenuRoute.path === pathname) { + title = submenuRoute.name; + } + }); + } + }); + return title; + }; + + const currentTitle = getPageTitle(location.pathname); + + + return ( +
+ {/* 1. Drawer Toggle */} + + + {/* 2. Main Content Area */} +
+ {/* Header/Navbar */} +
+
+ {/* Mobile Toggle Button (ใช้ Heroicon) */} + +
+ {/* แสดงชื่อหน้าปัจจุบัน */} +
+ {currentTitle} +
+ + {/* User Profile/Logout Dropdown */} +
+
+
+ + {user ? user.username : 'ผู้ใช้งาน'} + {role} +
+
    +
  • + + โปรไฟล์ + +
  • +
    +
  • + +
  • +
+
+
+
+ + {/* Page Content (Outlet) */} +
+ +
+ + {/* Footer (Optional) */} +
+ +
+
+ + {/* 3. Sidebar (ปรับโครงสร้างใหม่) */} +
+ +
    + + {/* ปุ่มปิด Sidebar สำหรับ Mobile */} + + + {/* ส่วนโลโก้ DDO Console */} +
  • + + DDO Console Logo + DDO Console + +
  • + + {/* การวนลูปเมนูจาก sidebarRoutes.jsx */} +
  • เมนูหลัก
  • + {routes.map((route, k) => { + // 1. ตรวจสอบสิทธิ์เมนูหลัก + if (!canAccess(route.requiredRole)) return null; + + return ( +
  • + {route.submenu ? + // 2. ถ้ามี Submenu ใช้ SidebarSubmenu Component + : + ( + // 3. ถ้าไม่มี Submenu ใช้ NavLink ธรรมดา + + `text-base ${isActive ? 'bg-base-200 text-primary font-semibold' : 'hover:bg-base-400'}` + } + > + {route.icon} {route.name} + + ) + } +
  • + ); + })} +
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/main.jsx b/web/src/main.jsx index ba17548..9ab579f 100644 --- a/web/src/main.jsx +++ b/web/src/main.jsx @@ -4,8 +4,19 @@ import './index.css' import App from './App.jsx' import './styles.css' +import { Provider } from 'react-redux'; +import { store } from './app/store'; +// TanStack Query +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +const queryClient = new QueryClient(); + createRoot(document.getElementById('root')).render( - + + + + + , ) diff --git a/web/src/pages/BlankPage.jsx b/web/src/pages/BlankPage.jsx new file mode 100644 index 0000000..90a2a75 --- /dev/null +++ b/web/src/pages/BlankPage.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import TitleCard from '../components/TitleCard'; +import { useLocation } from 'react-router-dom'; + +function BlankPage({ title, message }) { + const location = useLocation(); + + // ตั้งค่า Default Message ตามประเภทของหน้า + const defaultTitle = title || "Feature Under Development"; + const defaultMessage = message || + `เส้นทางปัจจุบัน: ${location.pathname} ยังไม่มีเนื้อหาที่พร้อมใช้งาน กรุณากลับไปที่หน้าหลักหรือเมนูอื่น`; + + return ( + // ใช้ TitleCard ห่อหุ้มเนื้อหาเพื่อให้มีโครงสร้างเหมือน Page อื่นๆ + +
+ + {/* Icon แจ้งเตือน */} + + + + +

+ {defaultTitle} +

+ +

+ {defaultMessage} +

+ + +
+
+ ); +} + +export default BlankPage; diff --git a/web/src/pages/Dashboard.jsx b/web/src/pages/Dashboard.jsx new file mode 100644 index 0000000..b67052c --- /dev/null +++ b/web/src/pages/Dashboard.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import TitleCard from '../components/TitleCard'; + +function Dashboard() { + const TopButtons = ( + + ); + + return ( +
+ {/* ใช้งาน TitleCard พร้อมปุ่มด้านบน */} + +

+ แสดงสถิติสำคัญและ Model ทั้งหมด +

+ {/* เพิ่มส่วนของการแสดง Metric สำคัญ เช่น Stats Component */} +
+
+ ); +} + +export default Dashboard; diff --git a/web/src/routes/AuthRoutes.jsx b/web/src/routes/AuthRoutes.jsx new file mode 100644 index 0000000..0714003 --- /dev/null +++ b/web/src/routes/AuthRoutes.jsx @@ -0,0 +1,23 @@ +import { Route, Routes, Navigate } from "react-router-dom"; +import AuthLayout from "../layouts/AuthLayout.jsx"; +import LoginForm from "../components/LoginForm.jsx"; + + +export default function AuthRoutes() { + return( + + {/* 1. Root Path ('/') นำทางไปยัง /login ทันที */} + } /> + + {/* 2. AuthLayout สำหรับหน้า Login, Register, Forgot Password */} + }> + }/> + หน้าลงทะเบียน}/> + หน้าลืมรหัสผ่าน}/> + + + {/* 3. Fallback สำหรับเส้นทางที่ไม่รู้จักในส่วน Public */} + 404 Not Found}/> + + ); +} \ No newline at end of file diff --git a/web/src/routes/PrivateRoutes.jsx b/web/src/routes/PrivateRoutes.jsx new file mode 100644 index 0000000..60c1dfc --- /dev/null +++ b/web/src/routes/PrivateRoutes.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { Routes, Route } from "react-router-dom"; +import ProtectedRoute from "./ProtectedRoute.jsx"; +import MainLayout from "../layouts/MainLayout.jsx"; + +// Import เส้นทางย่อยทั้งหมดที่กำหนดไว้ภายนอก +import pageRoutes from './pageRoutes.jsx'; + + +export default function PrivateRoutes() { + return ( + // 1. Routes หลักที่ครอบคลุมทั้งหมดภายใต้ /dashboard/* + + {/* 2. Layer ความปลอดภัย: MainLayout ถูกครอบด้วย ProtectedRoute */} + } />}> + + {/* 3. Layer เส้นทางย่อย: วนซ้ำ pageRoutes เพื่อสร้าง s */} + {pageRoutes.map((route, index) => ( + // สร้าง Route สำหรับแต่ละรายการใน pageRoutes + + ))} + + + + ); +} \ No newline at end of file diff --git a/web/src/routes/ProtectedRoute.jsx b/web/src/routes/ProtectedRoute.jsx new file mode 100644 index 0000000..b2debaf --- /dev/null +++ b/web/src/routes/ProtectedRoute.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { Navigate } from 'react-router-dom'; + +export default function ProtectedRoute({ element: Element }) { + // ดึงสถานะการล็อกอินจาก Redux Store + const isAuthenticated = useSelector(state => state.auth.isAuthenticated); + + if (!isAuthenticated) { + // ถ้ายังไม่ได้ล็อกอิน ให้นำทางกลับไปที่หน้า /login + // replace: true ป้องกันการย้อนกลับไปหน้า Dashboard ใน History + return ; + } + + // ถ้าล็อกอินแล้ว อนุญาตให้แสดง Element (Layout/Page) + return Element; +} diff --git a/web/src/routes/pageRoutes.jsx b/web/src/routes/pageRoutes.jsx new file mode 100644 index 0000000..3febe42 --- /dev/null +++ b/web/src/routes/pageRoutes.jsx @@ -0,0 +1,18 @@ +import Dashboard from '../pages/Dashboard'; +import BlankPage from '../pages/BlankPage'; + +// Array ของเส้นทางย่อยภายใต้ /dashboard/ +const pageRoutes = [ + // --- Dashboard --- + { + path: '', // ตรงกับ /dashboard + element: , + }, + // Fallback สำหรับเส้นทางที่ไม่ตรงกับเมนูใดๆ + { + path: '*', + element: , + } +]; + +export default pageRoutes; diff --git a/web/src/schemas/authSchema.js b/web/src/schemas/authSchema.js new file mode 100644 index 0000000..d663bc8 --- /dev/null +++ b/web/src/schemas/authSchema.js @@ -0,0 +1,9 @@ +import * as yup from 'yup'; + +// ---------------------------------------------------------------------- +// Schema สำหรับตรวจสอบข้อมูล Login (ใช้ Yup) +// ---------------------------------------------------------------------- +export const loginSchema = yup.object().shape({ + username: yup.string().required('กรุณากรอกชื่อผู้ใช้งาน'), + password: yup.string().required('กรุณากรอกรหัสผ่าน'), +}); \ No newline at end of file diff --git a/web/src/services/authApi.js b/web/src/services/authApi.js new file mode 100644 index 0000000..ef97530 --- /dev/null +++ b/web/src/services/authApi.js @@ -0,0 +1,139 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useDispatch } from 'react-redux'; +import { loginSuccess } from '../features/auth/authSlice'; +import { useNavigate } from 'react-router-dom'; +import axios from 'axios'; // ใช้ Axios ธรรมดาสำหรับการเรียกที่ยังไม่มี Token + +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; + +// ---------------------------------------------------- +// Helper Functions +// ---------------------------------------------------- + +/** + * แปลง Object ให้เป็นฟอร์มข้อมูล (x-www-form-urlencoded) + */ +const toFormUrlEncoded = (data) => { + return Object.keys(data) + .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])) + .join('&'); +}; + +/** + * กำหนดบทบาท (Role) จาก Django User Object ที่สมบูรณ์ + * @param {object} user - User Object จาก /users/me/ + */ +const determineRole = (user) => { + if (!user || !user.id) { + return 'guest'; + } + + // 1. ใช้ฟิลด์ 'role' ที่ส่งมาจาก Backend โดยตรง (ถ้ามี) + if (user.role) { + return user.role.toLowerCase(); // เช่น 'ADMIN' -> 'admin' + } + + // 2. ใช้ฟิลด์ is_superuser/is_staff เป็น Fallback/เกณฑ์มาตรฐาน + if (user.is_superuser) { + return 'admin'; + } + if (user.is_staff) { + // ถ้าเป็น is_staff แต่ไม่ใช่ superuser + return 'manager'; + } + + // ผู้ใช้ทั่วไป + return 'viewer'; +}; + + +/** + * ฟังก์ชันหลักในการล็อกอิน: ขั้นตอนที่ 1 (รับ Token) และ ขั้นตอนที่ 2 (รับ User Object) + */ +const loginUser = async (credentials) => { + // credentials จะเป็น { username, password } + const formData = toFormUrlEncoded(credentials); + + let access, refresh; + + // --------------------------------------------- + // ขั้นตอนที่ 1: รับ Access/Refresh Token (POST /jwt/create/) + // --------------------------------------------- + try { + const tokenResponse = await axios.post(`${API_BASE_URL}/api/v1/auth/jwt/create/`, formData, { + headers: { 'Content-Type': 'application/x-www-form-urlencoded' } + }); + + access = tokenResponse.data.access; + refresh = tokenResponse.data.refresh; + + } catch (error) { + // จัดการ Error จากการล็อกอิน + const errorMessage = error.response?.data?.detail || "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"; + throw new Error(errorMessage); + } + + // --------------------------------------------- + // ขั้นตอนที่ 2: ใช้ Access Token เพื่อดึง User Object (GET /users/me/) + // --------------------------------------------- + let user; + try { + const userResponse = await axios.get(`${API_BASE_URL}/api/v1/auth/users/me/`, { + headers: { + // ใช้ JWT เพื่อยืนยันตัวตน + 'Authorization': `Bearer ${access}`, + }, + }); + + user = userResponse.data; + + } catch (error) { + console.error("Failed to fetch user data after token creation:", error); + throw new Error("ล็อกอินสำเร็จ แต่ไม่สามารถดึงข้อมูลผู้ใช้ได้ (กรุณาติดต่อผู้ดูแลระบบ)"); + } + + // --------------------------------------------- + // ขั้นตอนที่ 3: คำนวณ Role และส่งกลับข้อมูล + // --------------------------------------------- + const userRole = determineRole(user); + + return { + access_token: access, + refresh_token: refresh, + user: user, + role: userRole, + }; +}; + + +// ---------------------------------------------------- +// Custom Hook สำหรับจัดการการล็อกอิน +// ---------------------------------------------------- +export const useLoginMutation = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: loginUser, + onSuccess: (data) => { + + // 1. จัดการ Token และ User Data + localStorage.setItem('token', data.access_token); + localStorage.setItem('user', JSON.stringify(data.user)); + localStorage.setItem('role', data.role); // บันทึก Role ที่ถูกต้อง + + // 2. อัปเดต Redux State + dispatch(loginSuccess({ user: data.user, role: data.role })); + + // 3. นำทางผู้ใช้ + navigate('/dashboard', { replace: true }); + queryClient.invalidateQueries({ queryKey: ['userData'] }); + }, + onError: (error) => { + // error.message ถูกโยนมาจาก loginUser function + console.error('Login API Error:', error.message); + throw new Error(error.message); + }, + }); +}; \ No newline at end of file diff --git a/web/src/services/axiosClient.js b/web/src/services/axiosClient.js new file mode 100644 index 0000000..bff0a1c --- /dev/null +++ b/web/src/services/axiosClient.js @@ -0,0 +1,58 @@ +import axios from 'axios'; +import { getStore } from '../app/store'; +import { logout } from '../features/auth/authSlice'; + +// 1. สร้าง Axios Instance โดยใช้ Base URL จาก .env + +const axiosClient = axios.create({ + baseURL: import.meta.env.VITE_API_BASE_URL, + // กำหนด Timeout เพื่อป้องกันการค้าง + timeout: 15000, +}); + + +// 2. เพิ่ม Interceptor เพื่อแนบ Token ใน Header +axiosClient.interceptors.request.use( + (config) => { + // ดึง Token จาก Local Storage + const token = localStorage.getItem('token'); + + // ถ้ามี Token ให้แนบไปใน Header 'Authorization' + if (token) { + // รูปแบบจากเป็น 'Bearer' + // ตามที่กำหนดใน Django DRF/Djoser settings (JWTAuthentication) + config.headers.Authorization = `Bearer ${token}`; + } + + return config; + }, + (error) => { + return Promise.reject(error); + } +); + + +// 3. (Optional) Interceptor สำหรับ Response (จัดการ Token Expired) + +axiosClient.interceptors.response.use( + (response) => response, + (error) => { + const status = error.response ? error.response.status : null; + + // ถ้าได้รับ 401 หรือ 403 (Token หมดอายุ/ไม่มีสิทธิ์) + if (status === 401 || status === 403) { + // Logic สำหรับการจัดการ Token หมดอายุ (เช่น Redirect ไปหน้า Login) + console.error("Authorization Failed: Token expired or insufficient roles."); + + // บังคับ Logout + const storeInstance = getStore(); // เรียกใช้ store instance + if (storeInstance) { + storeInstance.dispatch(logout()); // เรียก Redux Action + } + } + return Promise.reject(error); + } +); + + +export default axiosClient; \ No newline at end of file