fix: guest and admin logic

This commit is contained in:
2026-06-22 11:41:34 +07:00
parent b1a539235b
commit 860395cb14
61 changed files with 1291 additions and 244 deletions
+28 -23
View File
@@ -61,7 +61,11 @@ function MapTracker() {
return null;
}
export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos, onLoginSuccess }: { onBack: () => void, onLogout?: () => void, user?: any, onViewTour: (id: string) => void, onOpenMyPhotos: () => void, onLoginSuccess?: (user: any) => void }) => {
export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos, onLoginSuccess, onGoToDashboard }: { onBack: () => void, onLogout?: () => void, user?: any, onViewTour: (id: string) => void, onOpenMyPhotos: () => void, onLoginSuccess?: (user: any) => void, onGoToDashboard?: () => void }) => {
// Check if user is logged in (real user) or is a guest
const guestToken = localStorage.getItem('guest_token');
const isLoggedInOrGuest = user || guestToken;
// Tối ưu hóa việc lấy dữ liệu từ store bằng selectors để tránh re-render thừa
const publicTours = useTourStore(state => state.publicTours);
const fetchPublicTours = useTourStore(state => state.fetchPublicTours);
@@ -701,7 +705,7 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos,
{/* Nhóm bên phải: Các thao tác người dùng */}
<div className="flex items-center gap-2 pointer-events-auto">
{/* Nút Ảnh của tôi */}
{user && (
{isLoggedInOrGuest && (
<button
onClick={() => {
console.log("Đang mở Ảnh của tôi...");
@@ -716,7 +720,7 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos,
)}
{/* Nút tạo Tour mới */}
{user && (
{user && !localStorage.getItem('guest_token') && (
<button
onClick={() => setIsCreateModalOpen(true)}
className="w-11 h-11 md:w-auto bg-green-600 p-0 md:px-4 md:py-3 rounded-2xl shadow-xl hover:bg-green-700 text-white transition-all flex items-center justify-center md:justify-start gap-2 font-bold shrink-0"
@@ -770,28 +774,29 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos,
</div>
{/* Nút quản lý người dùng cho Admin */}
{user && (
{user?.isAdmin && (
<button
onClick={() => {
if (user.isAdmin) {
setIsAdminModalOpen(true);
} else {
const key = window.prompt(t('enterSecretKey'));
if (key) {
handlePromoteAdmin(key);
}
}
}}
className={`w-11 h-11 md:w-auto p-0 md:px-4 md:py-3 rounded-2xl shadow-xl transition-all flex items-center justify-center md:justify-start gap-2 font-bold shrink-0 ${
user.isAdmin ? 'bg-blue-600 hover:bg-blue-700 text-white' : 'bg-slate-700 hover:bg-slate-800 text-slate-300 dark:bg-slate-800 dark:text-slate-200 dark:hover:bg-slate-750 dark:border-slate-700 border border-slate-600'
}`}
onClick={() => setIsAdminModalOpen(true)}
className="w-11 h-11 md:w-auto p-0 md:px-4 md:py-3 rounded-2xl shadow-xl transition-all flex items-center justify-center md:justify-start gap-2 font-bold shrink-0 bg-blue-600 hover:bg-blue-700 text-white"
title={t('systemBtn')}
>
{user.isAdmin ? <Settings className="w-5 h-5" /> : <Lock className="w-5 h-5" />}
<Settings className="w-5 h-5" />
<span className="hidden md:inline text-sm">{t('systemBtn')}</span>
</button>
)}
{/* Nút Bảng điều khiển của tôi - chỉ hiển thị cho người dùng đã đăng nhập (không phải khách) */}
{user && !localStorage.getItem('guest_token') && onGoToDashboard && (
<button
onClick={onGoToDashboard}
className="w-11 h-11 md:w-auto p-0 md:px-4 md:py-3 rounded-2xl shadow-xl transition-all flex items-center justify-center md:justify-start gap-2 font-bold shrink-0 bg-emerald-600 hover:bg-emerald-700 text-white"
title="Bảng điều khiển của tôi"
>
<Settings className="w-5 h-5" />
<span className="hidden md:inline text-sm">Bảng điều khiển của tôi</span>
</button>
)}
{/* Nút đăng xuất */}
{onLogout && (
<button
@@ -1059,7 +1064,7 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos,
))}
</div>
<div className="text-[10px] bg-emerald-50 text-emerald-700 px-1.5 py-0.5 rounded font-black uppercase tracking-wider mb-1 w-max">
{item.type === 'RESTAURANT' ? 'Nhà hàng' : item.type === 'HOTEL' ? 'Khách sạn' : 'Homestay'}
{item.type === 'RESTAURANT' ? t('businessRestaurant') : item.type === 'HOTEL' ? t('businessHotel') : t('businessHomestay')}
</div>
{item.address && (
<div className="text-[10px] text-gray-500 mb-1 font-semibold">{item.address}</div>
@@ -1291,7 +1296,7 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos,
<div className="flex items-start justify-between gap-1.5">
<span className="text-xs font-bold text-gray-800 dark:text-slate-200 truncate">{item.name}</span>
<span className="text-[8px] bg-emerald-50 dark:bg-emerald-950/40 text-emerald-600 dark:text-emerald-400 px-1.5 py-0.5 rounded font-black shrink-0">
{item.type === 'RESTAURANT' ? 'Nhà hàng' : item.type === 'HOTEL' ? 'Khách sạn' : 'Homestay'}
{item.type === 'RESTAURANT' ? t('businessRestaurant') : item.type === 'HOTEL' ? t('businessHotel') : t('businessHomestay')}
</span>
</div>
@@ -1446,9 +1451,9 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onOpenMyPhotos,
onChange={(e) => setProposeForm(prev => ({ ...prev, type: e.target.value }))}
className="w-full px-3 py-2 border border-gray-200 dark:border-slate-800 rounded-xl focus:outline-none focus:ring-1 focus:ring-emerald-500 bg-gray-50/20 dark:bg-slate-950/40 text-gray-900 dark:text-slate-100"
>
<option value="RESTAURANT">Nhà hàng</option>
<option value="HOTEL">Khách sạn</option>
<option value="HOMESTAY">Homestay</option>
<option value="RESTAURANT">{t('businessRestaurant')}</option>
<option value="HOTEL">{t('businessHotel')}</option>
<option value="HOMESTAY">{t('businessHomestay')}</option>
</select>
</div>
<div>