diff --git a/backend/api/views.py b/backend/api/views.py index d8df648..54a0eb9 100644 --- a/backend/api/views.py +++ b/backend/api/views.py @@ -41,6 +41,13 @@ class FlavorViewSet(viewsets.ModelViewSet): serializer = self.get_serializer(top_flavors, many=True) return Response(serializer.data) + @action(detail=False, methods=['get'], permission_classes=[permissions.AllowAny]) + def newest(self, request): + # Get the 10 newest flavors + newest_flavors = Flavor.objects.select_related('category').order_by('-created_at')[:10] + serializer = self.get_serializer(newest_flavors, many=True) + return Response(serializer.data) + class CategoryViewSet(viewsets.ReadOnlyModelViewSet): queryset = Category.objects.all() serializer_class = CategorySerializer diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b4264c8..e24da42 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -33,7 +33,7 @@ import { getTheme, type CatppuccinTheme } from './theme'; import api from './api'; // Code splitting -const CategoryList = lazy(() => import('./pages/CategoryList')); +const MainPage = lazy(() => import('./pages/MainPage')); const CategoryFlavors = lazy(() => import('./pages/categories/CategoryFlavors')); const FlavorDetail = lazy(() => import('./pages/flavors/FlavorDetail')); const Dashboard = lazy(() => import('./pages/Dashboard')); @@ -394,7 +394,7 @@ const App: React.FC = () => { }> - } /> + } /> } /> } /> } /> diff --git a/frontend/src/pages/CategoryList.tsx b/frontend/src/pages/MainPage.tsx similarity index 90% rename from frontend/src/pages/CategoryList.tsx rename to frontend/src/pages/MainPage.tsx index 8ce0b26..855b2d5 100644 --- a/frontend/src/pages/CategoryList.tsx +++ b/frontend/src/pages/MainPage.tsx @@ -51,10 +51,11 @@ interface Review { flavor: number; } -const CategoryList: React.FC = () => { +const MainPage: React.FC = () => { const isMobileSize = useMediaQuery('(max-width:600px)'); const [categories, setCategories] = useState([]); const [topFlavors, setTopFlavors] = useState([]); + const [newestFlavors, setNewestFlavors] = useState([]); const [recentReviews, setRecentReviews] = useState([]); const [allFlavors, setAllFlavors] = useState([]); const [feedRatings, setFeedRatings] = useState([]); @@ -77,7 +78,8 @@ const CategoryList: React.FC = () => { const requests: any[] = [ api.get('categories/'), api.get('flavors/top/'), - api.get('ratings/recent/') + api.get('ratings/recent/'), + api.get('flavors/newest/') ]; if (isLoggedIn) { @@ -89,9 +91,10 @@ const CategoryList: React.FC = () => { setCategories(Array.isArray(results[0].data) ? results[0].data : (results[0].data.results || [])); setTopFlavors(Array.isArray(results[1].data) ? results[1].data : (results[1].data.results || [])); setRecentReviews(Array.isArray(results[2].data) ? results[2].data : (results[2].data.results || [])); + setNewestFlavors(Array.isArray(results[3].data) ? results[3].data : (results[3].data.results || [])); - if (isLoggedIn && results[3]) { - const feedData = Array.isArray(results[3].data) ? results[3].data : (results[3].data.results || []); + if (isLoggedIn && results[4]) { + const feedData = Array.isArray(results[4].data) ? results[4].data : (results[4].data.results || []); setFeedRatings(feedData.slice(0, 6)); // Show top 6 on home } } @@ -433,6 +436,45 @@ const CategoryList: React.FC = () => { + {/* Newest Arrivals */} + {newestFlavors.length > 0 && ( + + New Arrivals + + {newestFlavors.map(flavor => ( + + + + + + + + {flavor.name} + + {flavor.category_name} + + + + ))} + + + )} + {/* Recent Reviews */} {recentReviews.length > 0 && (