From 6913bbae48eac6d150aa0b3864fa0d0cbd67a44d Mon Sep 17 00:00:00 2001 From: locphamtran Date: Sat, 13 Jun 2026 17:41:11 +0700 Subject: [PATCH] =?UTF-8?q?S=E1=BB=ADa=20l=E1=BB=97i=20backend=20=C4=91?= =?UTF-8?q?=E1=BB=83=20ch=E1=BA=A1y=20ph=E1=BA=A7n=20=C4=91=C4=83ng=20k?= =?UTF-8?q?=C3=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.tsx | 20 +- ExpenseManager.tsx | 2 +- ExploreMap.tsx | 2 +- ItineraryTimeline.tsx | 2 +- LandingPage.tsx | 46 +- TourDetailPage.tsx | 6 +- admin.guard.ts | 2 +- dist/App.js | 28 +- dist/App.js.map | 2 +- dist/ExpenseManager.js | 26 +- dist/ExpenseManager.js.map | 2 +- dist/ExploreMap.d.ts | 5 + dist/ExploreMap.js | 50 ++ dist/ExploreMap.js.map | 1 + dist/ItineraryTimeline.js | 22 +- dist/ItineraryTimeline.js.map | 2 +- dist/LandingPage.d.ts | 3 + dist/LandingPage.js | 29 +- dist/LandingPage.js.map | 2 +- dist/LoginModal.d.ts | 1 + dist/LoginModal.js | 12 +- dist/LoginModal.js.map | 2 +- dist/SignupPage.d.ts | 7 + dist/SignupPage.js | 47 ++ dist/SignupPage.js.map | 1 + dist/TourDetailPage.js | 36 +- dist/TourDetailPage.js.map | 2 +- dist/admin.guard.d.ts | 7 + dist/admin.guard.js | 37 ++ dist/admin.guard.js.map | 1 + dist/expense-engine.service.js | 14 +- dist/expense-engine.service.js.map | 2 +- dist/index.d.ts | 1 + dist/index.js | 7 + dist/index.js.map | 1 + dist/jwt-auth.guard.d.ts | 4 + dist/jwt-auth.guard.js | 15 + dist/jwt-auth.guard.js.map | 1 + dist/jwt.strategy.d.ts | 19 + dist/jwt.strategy.js | 38 ++ dist/jwt.strategy.js.map | 1 + dist/main.js | 94 +++- dist/main.js.map | 2 +- dist/prisma.config.js | 8 +- dist/prisma.config.js.map | 2 +- dist/prisma.service.js | 25 +- dist/prisma.service.js.map | 2 +- dist/rbac.middleware.d.ts | 2 +- dist/rbac.middleware.js | 21 +- dist/rbac.middleware.js.map | 2 +- dist/seed.js | 16 +- dist/seed.js.map | 2 +- dist/tailwind.config.d.ts | 8 + dist/tailwind.config.js | 12 + dist/tailwind.config.js.map | 1 + dist/tsconfig.build.tsbuildinfo | 2 +- dist/useTourStore.d.ts | 2 + dist/useTourStore.js | 13 +- dist/useTourStore.js.map | 2 +- dist/vite.config.d.ts | 2 + dist/vite.config.js | 11 + dist/vite.config.js.map | 1 + index.tsx | 2 +- jwt.strategy.ts | 2 +- main.ts | 8 +- package-lock.json | 736 ++++++++++++++++++++++++++++- package.json | 7 +- rbac.middleware.ts | 2 +- schema.prisma | 3 +- tsconfig.json | 8 +- 70 files changed, 1296 insertions(+), 210 deletions(-) create mode 100644 dist/ExploreMap.d.ts create mode 100644 dist/ExploreMap.js create mode 100644 dist/ExploreMap.js.map create mode 100644 dist/SignupPage.d.ts create mode 100644 dist/SignupPage.js create mode 100644 dist/SignupPage.js.map create mode 100644 dist/admin.guard.d.ts create mode 100644 dist/admin.guard.js create mode 100644 dist/admin.guard.js.map create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/jwt-auth.guard.d.ts create mode 100644 dist/jwt-auth.guard.js create mode 100644 dist/jwt-auth.guard.js.map create mode 100644 dist/jwt.strategy.d.ts create mode 100644 dist/jwt.strategy.js create mode 100644 dist/jwt.strategy.js.map create mode 100644 dist/tailwind.config.d.ts create mode 100644 dist/tailwind.config.js create mode 100644 dist/tailwind.config.js.map create mode 100644 dist/vite.config.d.ts create mode 100644 dist/vite.config.js create mode 100644 dist/vite.config.js.map diff --git a/App.tsx b/App.tsx index 698149f..4450eac 100644 --- a/App.tsx +++ b/App.tsx @@ -1,17 +1,27 @@ -import React, { useState } from 'react'; -import { LandingPage } from './LandingPage'; -import { TourDetailPage } from './TourDetailPage'; -import { ExploreMap } from './ExploreMap'; -import { SignupPage } from './SignupPage'; +import React, { useState, useEffect } from 'react'; +import { LandingPage } from './LandingPage.js'; +import { TourDetailPage } from './TourDetailPage.js'; +import { ExploreMap } from './ExploreMap.js'; +import { SignupPage } from './SignupPage.js'; const App = () => { type View = 'landing' | 'explore' | 'detail' | 'signup'; const [view, setView] = useState('landing'); + const [isInitialSetup, setIsInitialSetup] = useState(false); + + useEffect(() => { + // Kiểm tra xem hệ thống đã được cài đặt chưa + fetch('http://localhost:3001/api/v1/auth/status') + .then(res => res.json()) + .then(data => setIsInitialSetup(data.isInitialSetup)) + .catch(() => setIsInitialSetup(false)); + }, [view]); return (
{view === 'landing' && ( setView('explore')} onGoToSignup={() => setView('signup')} onGoToMap={() => setView('explore')} diff --git a/ExpenseManager.tsx b/ExpenseManager.tsx index d9d3175..f390364 100644 --- a/ExpenseManager.tsx +++ b/ExpenseManager.tsx @@ -1,6 +1,6 @@ import React, { useState, useMemo } from 'react'; import { Wallet, Users, Info } from 'lucide-react'; -import { useTourStore } from './useTourStore'; +import { useTourStore } from './useTourStore.js'; export const ExpenseManager = () => { const { legs } = useTourStore(); diff --git a/ExploreMap.tsx b/ExploreMap.tsx index d262e15..b332a12 100644 --- a/ExploreMap.tsx +++ b/ExploreMap.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'; import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; -import { useTourStore } from './useTourStore'; +import { useTourStore } from './useTourStore.js'; import { X, Navigation, Image as ImageIcon } from 'lucide-react'; // Fix lỗi icon mặc định của Leaflet diff --git a/ItineraryTimeline.tsx b/ItineraryTimeline.tsx index c18a7ee..c401b98 100644 --- a/ItineraryTimeline.tsx +++ b/ItineraryTimeline.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { format, differenceInMinutes, parseISO } from 'date-fns'; import { CheckCircle2, Circle, Clock, MapPin, AlertCircle } from 'lucide-react'; -import { useTourStore } from './useTourStore'; +import { useTourStore } from './useTourStore.js'; const TimeVariance = ({ planned, actual }: { planned: string, actual: string | null }) => { if (!actual) return null; diff --git a/LandingPage.tsx b/LandingPage.tsx index e51d686..362576b 100644 --- a/LandingPage.tsx +++ b/LandingPage.tsx @@ -1,6 +1,6 @@ import React, { useState, useMemo } from 'react'; -import { LogIn, Compass, ArrowRight, Map as MapIcon, UserPlus } from 'lucide-react'; -import { LoginModal } from './LoginModal'; +import { LogIn, Compass, ArrowRight, Map as MapIcon, UserPlus, ShieldCheck } from 'lucide-react'; +import { LoginModal } from './LoginModal.js'; const TRAVEL_IMAGES = [ "https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?auto=format&fit=crop&q=80", @@ -15,9 +15,10 @@ interface LandingPageProps { onContinue?: () => void; onGoToSignup?: () => void; onGoToMap?: () => void; + isInitialSetup?: boolean; } -export const LandingPage: React.FC = ({ onContinue, onGoToSignup, onGoToMap }) => { +export const LandingPage: React.FC = ({ onContinue, onGoToSignup, onGoToMap, isInitialSetup }) => { const [isLoginModalOpen, setIsLoginModalOpen] = useState(false); // Chọn ngẫu nhiên một hình ảnh khi người dùng truy cập trang @@ -68,16 +69,41 @@ export const LandingPage: React.FC = ({ onContinue, onGoToSign
-

- Lên kế hoạch cho hành trình tiếp theo -

-

- Khám phá các địa điểm nổi bật qua bản đồ cộng đồng hoặc đăng nhập để bắt đầu tự tạo chuyến đi cho riêng mình. -

+ {isInitialSetup ? ( + <> +
+ CẤU HÌNH HỆ THỐNG LẦN ĐẦU +
+

+ Thiết lập Quản trị viên +

+

+ Chào mừng! Hệ thống vừa được cài đặt. Vui lòng tạo tài khoản đầu tiên để quản lý và vận hành trang web. +

+ + ) : ( + <> +

+ Lên kế hoạch cho hành trình tiếp theo +

+

+ Khám phá các địa điểm nổi bật qua bản đồ cộng đồng hoặc đăng nhập để bắt đầu tự tạo chuyến đi cho riêng mình. +

+ + )}
- {/* Nút Khám phá Bản đồ (Cho khách công cộng) */} + {isInitialSetup && ( + + )} +