diff --git a/backend/uploads/members/1457cea9-b624-4c1d-9cd5-4e91ec7650e7/originals/1782117859049-842649784.jpg b/backend/uploads/members/1457cea9-b624-4c1d-9cd5-4e91ec7650e7/originals/1782117859049-842649784.jpg new file mode 100644 index 0000000..10d36f7 Binary files /dev/null and b/backend/uploads/members/1457cea9-b624-4c1d-9cd5-4e91ec7650e7/originals/1782117859049-842649784.jpg differ diff --git a/backend/uploads/members/1457cea9-b624-4c1d-9cd5-4e91ec7650e7/originals/1782118011361-597767150.jpg b/backend/uploads/members/1457cea9-b624-4c1d-9cd5-4e91ec7650e7/originals/1782118011361-597767150.jpg new file mode 100644 index 0000000..8b4599d Binary files /dev/null and b/backend/uploads/members/1457cea9-b624-4c1d-9cd5-4e91ec7650e7/originals/1782118011361-597767150.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782115144211-874857358.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782115144211-874857358.jpg deleted file mode 100644 index bae79f7..0000000 Binary files a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782115144211-874857358.jpg and /dev/null differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782115196943-382735343.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782115196943-382735343.jpg deleted file mode 100644 index d07f423..0000000 Binary files a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782115196943-382735343.jpg and /dev/null differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118429736-724308606.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118429736-724308606.jpg new file mode 100644 index 0000000..976555e Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118429736-724308606.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118555622-169762497.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118555622-169762497.jpg new file mode 100644 index 0000000..870d946 Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118555622-169762497.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118586257-944146918.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118586257-944146918.jpg new file mode 100644 index 0000000..f78d65b Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782118586257-944146918.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782119277412-689188888.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782119277412-689188888.jpg new file mode 100644 index 0000000..b20d92a Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782119277412-689188888.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782119715899-406184214.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782119715899-406184214.jpg new file mode 100644 index 0000000..1e6e69a Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782119715899-406184214.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782120725208-869886522.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782120725208-869886522.jpg new file mode 100644 index 0000000..ec4c58b Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782120725208-869886522.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782120812146-600514666.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782120812146-600514666.jpg new file mode 100644 index 0000000..5b7b69f Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782120812146-600514666.jpg differ diff --git a/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782121821246-798259674.jpg b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782121821246-798259674.jpg new file mode 100644 index 0000000..85cec3f Binary files /dev/null and b/backend/uploads/members/2892ccf0-ead4-4a56-874c-d1f71adc7001/originals/1782121821246-798259674.jpg differ diff --git a/backend/uploads/members/c6828597-682c-4676-8375-523a274d3c7b/originals/1782117812897-398088187.jpg b/backend/uploads/members/c6828597-682c-4676-8375-523a274d3c7b/originals/1782117812897-398088187.jpg new file mode 100644 index 0000000..2006ca4 Binary files /dev/null and b/backend/uploads/members/c6828597-682c-4676-8375-523a274d3c7b/originals/1782117812897-398088187.jpg differ diff --git a/backend/uploads/tours/1782115144211-874857358.jpg b/backend/uploads/tours/1782115144211-874857358.jpg deleted file mode 100644 index db2d414..0000000 Binary files a/backend/uploads/tours/1782115144211-874857358.jpg and /dev/null differ diff --git a/backend/uploads/tours/1782115196943-382735343.jpg b/backend/uploads/tours/1782115196943-382735343.jpg deleted file mode 100644 index 50eebc3..0000000 Binary files a/backend/uploads/tours/1782115196943-382735343.jpg and /dev/null differ diff --git a/backend/uploads/tours/1782117812897-398088187.jpg b/backend/uploads/tours/1782117812897-398088187.jpg new file mode 100644 index 0000000..7b56ba2 Binary files /dev/null and b/backend/uploads/tours/1782117812897-398088187.jpg differ diff --git a/backend/uploads/tours/1782117859049-842649784.jpg b/backend/uploads/tours/1782117859049-842649784.jpg new file mode 100644 index 0000000..4f75551 Binary files /dev/null and b/backend/uploads/tours/1782117859049-842649784.jpg differ diff --git a/backend/uploads/tours/1782118011361-597767150.jpg b/backend/uploads/tours/1782118011361-597767150.jpg new file mode 100644 index 0000000..ae21e9c Binary files /dev/null and b/backend/uploads/tours/1782118011361-597767150.jpg differ diff --git a/backend/uploads/tours/1782118429736-724308606.jpg b/backend/uploads/tours/1782118429736-724308606.jpg new file mode 100644 index 0000000..5ce9ed6 Binary files /dev/null and b/backend/uploads/tours/1782118429736-724308606.jpg differ diff --git a/backend/uploads/tours/1782118555622-169762497.jpg b/backend/uploads/tours/1782118555622-169762497.jpg new file mode 100644 index 0000000..06bb255 Binary files /dev/null and b/backend/uploads/tours/1782118555622-169762497.jpg differ diff --git a/backend/uploads/tours/1782118586257-944146918.jpg b/backend/uploads/tours/1782118586257-944146918.jpg new file mode 100644 index 0000000..31f9d3c Binary files /dev/null and b/backend/uploads/tours/1782118586257-944146918.jpg differ diff --git a/backend/uploads/tours/1782119277412-689188888.jpg b/backend/uploads/tours/1782119277412-689188888.jpg new file mode 100644 index 0000000..db8db47 Binary files /dev/null and b/backend/uploads/tours/1782119277412-689188888.jpg differ diff --git a/backend/uploads/tours/1782119715899-406184214.jpg b/backend/uploads/tours/1782119715899-406184214.jpg new file mode 100644 index 0000000..5ecc1b8 Binary files /dev/null and b/backend/uploads/tours/1782119715899-406184214.jpg differ diff --git a/backend/uploads/tours/1782120725208-869886522.jpg b/backend/uploads/tours/1782120725208-869886522.jpg new file mode 100644 index 0000000..913928b Binary files /dev/null and b/backend/uploads/tours/1782120725208-869886522.jpg differ diff --git a/backend/uploads/tours/1782120812146-600514666.jpg b/backend/uploads/tours/1782120812146-600514666.jpg new file mode 100644 index 0000000..c484a7a Binary files /dev/null and b/backend/uploads/tours/1782120812146-600514666.jpg differ diff --git a/backend/uploads/tours/1782121821246-798259674.jpg b/backend/uploads/tours/1782121821246-798259674.jpg new file mode 100644 index 0000000..66b5bb6 Binary files /dev/null and b/backend/uploads/tours/1782121821246-798259674.jpg differ diff --git a/docker-compose-old.yml b/docker-compose-old.yml new file mode 100644 index 0000000..7017636 --- /dev/null +++ b/docker-compose-old.yml @@ -0,0 +1,73 @@ +services: + postgres: + image: postgres:15-alpine + container_name: yotrip-db + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + POSTGRES_DB: travel_db + ports: + - "5432:5432" + volumes: + - pg_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d travel_db"] + interval: 5s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + container_name: yotrip-redis + ports: + - "6379:6379" + + backend: + build: + context: ./backend + target: development + container_name: yotrip-backend + command: > + sh -c "npx prisma migrate dev --schema=prisma/schema.prisma && npm run start:dev" + ports: + - "3001:3001" + volumes: + - ./backend:/usr/src/app + - /usr/src/app/node_modules + environment: + DATABASE_URL: "postgresql://postgres:password@postgres:5432/travel_db?schema=public" + REDIS_URL: "redis://redis:6379" + PORT: 3001 + ADMIN_SECRET_KEY: "yotrip_secret_admin_key" + JWT_SECRET: "super-secret" + FRONTEND_URL: "http://localhost:5173" + NODE_ENV: development + SMTP_HOST: "${SMTP_HOST}" + SMTP_PORT: "${SMTP_PORT}" + SMTP_SECURE: "${SMTP_SECURE}" + SMTP_USER: "${SMTP_USER}" + SMTP_PASS: "${SMTP_PASS}" + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_started + + frontend: + build: + context: ./frontend + target: development + container_name: yotrip-frontend + command: npm run dev -- --host 0.0.0.0 + ports: + - "5173:5173" + volumes: + - ./frontend:/usr/src/app + - /usr/src/app/node_modules + environment: + VITE_API_URL: "http://localhost:3001" + depends_on: + - backend + +volumes: + pg_data: diff --git a/docker-compose.yml b/docker-compose.yml index a70ef67..842cd4a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,14 @@ -version: '3.8' - services: postgres: image: postgres:15-alpine - container_name: yotrip-db + container_name: yotrip-db-prod + restart: always environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: travel_db - ports: - - "5432:5432" volumes: - - pg_data:/var/lib/postgresql/data + - pg_data_prod:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d travel_db"] interval: 5s @@ -20,30 +17,29 @@ services: redis: image: redis:7-alpine - container_name: yotrip-redis - ports: - - "6379:6379" + container_name: yotrip-redis-prod + restart: always backend: build: context: ./backend - target: development - container_name: yotrip-backend + target: production + container_name: yotrip-backend-prod + restart: always command: > - sh -c "npx prisma migrate dev --schema=prisma/schema.prisma && npm run start:dev" + sh -c "npx prisma migrate deploy --schema=prisma/schema.prisma && node dist/src/main.js" ports: - "3001:3001" volumes: - - ./backend:/usr/src/app - - /usr/src/app/node_modules + - ./backend/uploads:/usr/src/app/uploads environment: DATABASE_URL: "postgresql://postgres:password@postgres:5432/travel_db?schema=public" REDIS_URL: "redis://redis:6379" PORT: 3001 - ADMIN_SECRET_KEY: "yotrip_secret_admin_key" + ADMIN_SECRET_KEY: "${ADMIN_SECRET_KEY}" JWT_SECRET: "super-secret" - FRONTEND_URL: "http://localhost:5173" - NODE_ENV: development + FRONTEND_URL: "${FRONTEND_URL}" + NODE_ENV: production SMTP_HOST: "${SMTP_HOST}" SMTP_PORT: "${SMTP_PORT}" SMTP_SECURE: "${SMTP_SECURE}" @@ -58,18 +54,15 @@ services: frontend: build: context: ./frontend - target: development - container_name: yotrip-frontend - command: npm run dev -- --host 0.0.0.0 + target: production + args: + - VITE_GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} + container_name: yotrip-frontend-prod + restart: always ports: - - "5173:5173" - volumes: - - ./frontend:/usr/src/app - - /usr/src/app/node_modules - environment: - VITE_API_URL: "http://localhost:3001" + - "3002:80" depends_on: - backend volumes: - pg_data: + pg_data_prod: diff --git a/frontend/src/pages/LandingPage.tsx b/frontend/src/pages/LandingPage.tsx index dac2c43..7a08329 100644 --- a/frontend/src/pages/LandingPage.tsx +++ b/frontend/src/pages/LandingPage.tsx @@ -175,19 +175,23 @@ export const LandingPage: React.FC = ({ onGoToSignup, onGoToMa new Promise((resolve) => setTimeout(() => resolve(null), 4500)) ]); - // 1. Tạo tài khoản khách và lấy token - let guestToken = localStorage.getItem('guest_token'); - let guestUser = JSON.parse(localStorage.getItem('guest_user') || 'null'); - - if (!guestToken) { - const guestRes = await fetch('/api/v1/auth/create-guest', { method: 'POST' }); - if (!guestRes.ok) throw new Error('Không thể tạo phiên khách.'); - const guestData = await guestRes.json(); - guestToken = guestData.access_token; - guestUser = guestData.user; - localStorage.setItem('guest_token', guestToken!); - localStorage.setItem('guest_user', JSON.stringify(guestUser)); - } +// 1. Xóa token cũ nếu có để đảm bảo guest không bị nhầm lẫn + localStorage.removeItem('token'); + localStorage.removeItem('user'); + + // 2. Tạo tài khoản khách và lấy token + let guestToken = localStorage.getItem('guest_token'); + let guestUser = JSON.parse(localStorage.getItem('guest_user') || 'null'); + + if (!guestToken) { + const guestRes = await fetch('/api/v1/auth/create-guest', { method: 'POST' }); + if (!guestRes.ok) throw new Error('Không thể tạo phiên khách.'); + const guestData = await guestRes.json(); + guestToken = guestData.access_token; + guestUser = guestData.user; + localStorage.setItem('guest_token', guestToken!); + localStorage.setItem('guest_user', JSON.stringify(guestUser)); + } // 2. Tải ảnh lên const formData = new FormData(); @@ -230,18 +234,17 @@ export const LandingPage: React.FC = ({ onGoToSignup, onGoToMa throw new Error(errorData.message || 'Tải ảnh thất bại.'); } - notify({ title: 'Thành công!', message: 'Ảnh của bạn đã được tải lên.', type: 'success' }); - - // Cập nhật lại danh sách ảnh lập tức - await fetchPublicPhotos(); - setCurrentBgIndex(0); +notify({ title: 'Thành công!', message: 'Ảnh của bạn đã được tải lên.', type: 'success' }); - // Đăng nhập luôn bằng tài khoản khách này để người dùng xem được ảnh của mình trên bản đồ - localStorage.setItem('token', guestToken!); - localStorage.setItem('user', JSON.stringify(guestUser)); - if (onLoginSuccess) { - onLoginSuccess(guestUser); - } + // Xóa pendingInviteToken và parameter token khỏi URL để tránh tự động chuyển sang JoinTourPage + localStorage.removeItem('pendingInviteToken'); + const url = new URL(window.location.href); + url.searchParams.delete('token'); + window.history.replaceState({}, '', url.toString()); + + // Cập nhật lại danh sách ảnh lập tức + await fetchPublicPhotos(); + setCurrentBgIndex(0); } catch (error: any) { notify({ title: 'Lỗi', message: error.message, type: 'error' });