diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 39f442f..e71ef1f 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -24,7 +24,8 @@ import {
Autocomplete,
CircularProgress,
ListItemAvatar,
- ListSubheader
+ ListSubheader,
+ alpha
} from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import SearchIcon from '@mui/icons-material/Search';
@@ -338,12 +339,18 @@ const App: React.FC = () => {
-
+ bgcolor: (theme) => alpha(theme.palette.background.paper, 0.8),
+ backdropFilter: 'blur(12px)',
+ color: 'text.primary',
+ zIndex: (theme) => theme.zIndex.drawer + 1
+ }}
+ >
diff --git a/frontend/src/pages/flavors/FlavorDetail.tsx b/frontend/src/pages/flavors/FlavorDetail.tsx
index 914a188..dca26f5 100644
--- a/frontend/src/pages/flavors/FlavorDetail.tsx
+++ b/frontend/src/pages/flavors/FlavorDetail.tsx
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
-import { useParams, Link } from 'react-router-dom';
+import { useParams, Link, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
Typography,
@@ -10,14 +10,19 @@ import {
Button,
TextField,
Avatar,
- Alert,
Paper,
CircularProgress,
- Container
+ Container,
+ Grid,
+ Chip,
+ Stack
} from '@mui/material';
import api from '../../api';
import { useTitle } from '../../hooks/useTitle';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
+import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
+import VerifiedIcon from '@mui/icons-material/Verified';
+import StarIcon from '@mui/icons-material/Star';
interface Reply {
id: number;
@@ -54,6 +59,7 @@ interface Flavor {
const FlavorDetail: React.FC = () => {
const { t } = useTranslation();
const { id } = useParams<{ id: string }>();
+ const navigate = useNavigate();
const [flavor, setFlavor] = useState(null);
const [loading, setLoading] = useState(true);
const [replyInputs, setReplyInputs] = useState<{[key: number]: string}>({});
@@ -146,186 +152,237 @@ const FlavorDetail: React.FC = () => {
}
};
+ const handleGoBack = () => {
+ if (window.history.length > 1) {
+ navigate(-1);
+ } else {
+ navigate(`/category/${flavor?.category_slug}`);
+ }
+ };
+
if (loading) return ;
if (!flavor) return Flavor not found;
return (
-
- }
- sx={{ mb: 2, textTransform: 'none', borderRadius: 2 }}
- >
- {t('common.backTo')} {flavor.category_name}
-
+
+ {/* Top Bar */}
+
+ }
+ sx={{ textTransform: 'none', color: 'text.secondary', '&:hover': { color: 'primary.main', bgcolor: 'transparent' } }}
+ >
+ {t('common.backTo')}
+
+
-
- {flavor.image_url && (
-
+ {/* Left: Image */}
+
+
-
-
- )}
-
- {!flavor.is_available && (
-
- {flavor.is_legacy ? "Unavailable (Legacy Flavor)" : "Out of Stock"}
-
- )}
-
- {flavor.name}
-
-
- {flavor.category_name}
-
-
-
-
-
- {(flavor.average_rating || 0).toFixed(1)} / 10
-
-
+ >
+ {!flavor.is_available && (
+
+ )}
+ {flavor.image_url ? (
+
+ ) : (
+ No Image
+ )}
+
+
-
- {flavor.description}
-
+ {/* Right: Info */}
+
+
+
+
+ {flavor.name}
+
+
+
+
+ {(flavor.average_rating || 0).toFixed(1)}
+ / 10
+
+
+
+ {flavor.ratings.length} {t('common.reviews')}
+
+
- {flavor.shop_url && (
-
- )}
-
-
+
+ {flavor.description}
+
- {/* New Rating Form */}
- {currentUser && flavor.user_rating === null && (
-
- Rate this flavor
-
-
- )}
+ {flavor.shop_url && (
+ }
+ sx={{
+ borderRadius: 3,
+ px: 4,
+ py: 1.5,
+ fontSize: '1rem',
+ fontWeight: 'bold',
+ boxShadow: '0 8px 20px rgba(0,0,0,0.15)'
+ }}
+ >
+ {t('common.buyNow')}
+
+ )}
+
+
+
-
- {t('home.communityVoice')}
-
-
- {flavor.ratings.length === 0 ? (
- {t('dashboard.noRatings')}
- ) : (
- flavor.ratings.map((rating: Rating) => (
-
-
- {editMode === rating.id ? (
-
- setEditScore(val || 0)} size="large" />
- setEditComment(e.target.value)}
- label="Your Comment"
- sx={{
- '& .MuiInputLabel-root': { bgcolor: 'background.paper', px: 0.5 }
- }}
- InputLabelProps={{ shrink: true }}
- />
-
-
-
-
-
- ) : (
- <>
-
-
-
- {!rating.user_avatar && rating.user.charAt(0).toUpperCase()}
-
-
-
-
-
- {rating.user}
-
-
-
- {rating.score}/10
-
-
-
- {new Date(rating.created_at).toLocaleDateString()}
-
+ {/* Reviews Section */}
+
+
+ {t('home.communityVoice')}
+
+
+ {/* New Rating Form */}
+ {currentUser && flavor.user_rating === null && (
+
+ Rate this flavor
+
+
+ )}
+
+
+ {flavor.ratings.length === 0 ? (
+
+ {t('dashboard.noRatings')}
+
+ ) : (
+ flavor.ratings.map((rating: Rating) => (
+
+
+ {editMode === rating.id ? (
+ // Edit Mode
+
+ setEditScore(val || 0)} size="large" />
+ setEditComment(e.target.value)}
+ />
+
+
+
- {rating.comment && (
-
- {rating.comment}
-
- )}
-
- {currentUser === rating.user && (
- <>
-
-
- >
- )}
-
- >
- )}
+ ) : (
+ // View Mode
+ <>
+
+
+
+
+ {!rating.user_avatar && rating.user.charAt(0).toUpperCase()}
+
+
+
+
+ {rating.user}
+
+
+ {new Date(rating.created_at).toLocaleDateString()}
+
+
+
+
+
+ {rating.score}/10
+
+
-
- {rating.replies.map((reply: any) => (
-
- {reply.user}
- {reply.text}
- {new Date(reply.created_at).toLocaleDateString()}
+ {rating.comment && (
+
+ {rating.comment}
+
+ )}
+
+
+ {/* Reply Actions or Metadata */}
+
+ {currentUser === rating.user && (
+
+
+
+
+ )}
+
+ >
+ )}
+
+ {/* Replies */}
+ {rating.replies.length > 0 && (
+
+ {rating.replies.map((reply: any) => (
+
+
+ {reply.user}
+ {reply.user === rating.user && }
+
+ {reply.text}
+
+ ))}
- ))}
+ )}
+
{currentUser && (
{
fullWidth
value={replyInputs[rating.id] || ''}
onChange={(e) => setReplyInputs({ ...replyInputs, [rating.id]: e.target.value })}
+ sx={{ '& .MuiOutlinedInput-root': { bgcolor: 'background.paper' } }}
/>
)}
-
-
-
- ))
- )}
-
+
+
+ ))
+ )}
+
+
);
};