From a983d49f2292419fb02b7d21261105df9f7b084c Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Thu, 1 Aug 2024 10:11:55 -0500 Subject: [PATCH] Styling and structure of main recipes page. --- src/components/footer/Footer.tsx | 11 ++++ src/components/footer/footer.module.css | 3 + src/components/header/Header.tsx | 27 +++++++++ src/components/header/header.module.css | 11 ++++ src/components/recipe-card/RecipeCard.tsx | 56 +++++++++++-------- .../recipe-card/recipe-card.module.css | 38 +++++++++++-- src/main.css | 24 ++++++++ src/main.tsx | 1 + src/pages/recipes/Recipes.tsx | 38 ++++++++----- src/pages/recipes/recipes.module.css | 23 ++++++++ src/routes/__root.module.css | 3 + src/routes/__root.tsx | 33 ++--------- 12 files changed, 199 insertions(+), 69 deletions(-) create mode 100644 src/components/footer/Footer.tsx create mode 100644 src/components/footer/footer.module.css create mode 100644 src/components/header/Header.tsx create mode 100644 src/components/header/header.module.css create mode 100644 src/main.css create mode 100644 src/pages/recipes/recipes.module.css create mode 100644 src/routes/__root.module.css diff --git a/src/components/footer/Footer.tsx b/src/components/footer/Footer.tsx new file mode 100644 index 0000000..2768e7a --- /dev/null +++ b/src/components/footer/Footer.tsx @@ -0,0 +1,11 @@ +import './footer.module.css' + +const Footer = () => { + return ( + + ) +} + +export default Footer diff --git a/src/components/footer/footer.module.css b/src/components/footer/footer.module.css new file mode 100644 index 0000000..47409f3 --- /dev/null +++ b/src/components/footer/footer.module.css @@ -0,0 +1,3 @@ +footer { + padding: 20px; +} diff --git a/src/components/header/Header.tsx b/src/components/header/Header.tsx new file mode 100644 index 0000000..14e6817 --- /dev/null +++ b/src/components/header/Header.tsx @@ -0,0 +1,27 @@ +import { useNavigate, useRouter } from '@tanstack/react-router' +import { useAuth } from '../../auth' +import classes from './header.module.css' + +const Header = () => { + const auth = useAuth() + const router = useRouter() + const navigate = useNavigate() + + const onLogout = async () => { + auth.clearToken(async () => { + await router.invalidate() + await navigate({ to: '/login' }) + }) + } + + return ( +
+

Meals Made Easy

+ +
+ ) +} + +export default Header diff --git a/src/components/header/header.module.css b/src/components/header/header.module.css new file mode 100644 index 0000000..67308f5 --- /dev/null +++ b/src/components/header/header.module.css @@ -0,0 +1,11 @@ +header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: var(--primary-red); + padding: 20px; +} + +.meals-made-easy { + color: var(--primary-white); +} diff --git a/src/components/recipe-card/RecipeCard.tsx b/src/components/recipe-card/RecipeCard.tsx index 04b977c..f550161 100644 --- a/src/components/recipe-card/RecipeCard.tsx +++ b/src/components/recipe-card/RecipeCard.tsx @@ -38,28 +38,40 @@ const RecipeCard = ({ />
- -

{title}

- - - - {starCount} - - - - {ownerUsername} - - {isPublic ? ( - - ) : ( - - )} +
+ +

{title}

+ + + + {starCount} + +
+
+ + + {ownerUsername} + + {isPublic ? ( + + ) : ( + + )} +
) diff --git a/src/components/recipe-card/recipe-card.module.css b/src/components/recipe-card/recipe-card.module.css index 25610a9..1d1dee4 100644 --- a/src/components/recipe-card/recipe-card.module.css +++ b/src/components/recipe-card/recipe-card.module.css @@ -1,18 +1,44 @@ .recipe-card { - max-width: 400px; - border: 1px solid black; + justify-self: stretch; } .recipe-image { - max-width: 100%; + width: 100%; + max-height: 200px; + object-fit: cover; } .info-container { - display: grid; - grid-template-columns: repeat(2, 1fr); - align-items: baseline; + display: flex; + flex-direction: column; + row-gap: 10px; +} + +.info-row { + display: flex; + justify-content: space-between; } .title { margin-block: 0; + font-size: 18px; +} + +.star-info { + display: flex; + column-gap: 5px; + align-items: center; +} + +.star { + color: var(--primary-yellow); +} + +.user-info { + display: flex; + column-gap: 5px; +} + +.user-icon { + color: var(--primary-red); } diff --git a/src/main.css b/src/main.css new file mode 100644 index 0000000..1d25cc8 --- /dev/null +++ b/src/main.css @@ -0,0 +1,24 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); + +:root { + --primary-white: #ffffff; + --primary-red: #91351d; + --primary-yellow: #ffb61d; +} + +body { + margin: 0; + font-family: 'Inter', sans-serif; +} + +a { + color: var(--primary-red); +} + +a:visited { + color: var(--primary-red); +} + +a:hover { + color: hsl(from var(--primary-red) h s l / 0.9); +} diff --git a/src/main.tsx b/src/main.tsx index 7d6e8e8..b25889d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,6 +6,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { AuthProvider, useAuth } from './auth' import { library } from '@fortawesome/fontawesome-svg-core' import { fas } from '@fortawesome/free-solid-svg-icons' +import './main.css' // Font-Awesome: load icons library.add(fas) diff --git a/src/pages/recipes/Recipes.tsx b/src/pages/recipes/Recipes.tsx index 25528d3..58cde4e 100644 --- a/src/pages/recipes/Recipes.tsx +++ b/src/pages/recipes/Recipes.tsx @@ -4,6 +4,7 @@ import { useState } from 'react' import { useAuth } from '../../auth' import { ApiError } from '../../api/ApiError' import RecipeCard from '../../components/recipe-card/RecipeCard' +import classes from './recipes.module.css' const Recipes = () => { const [pageNumber, setPageNumber] = useState(0) @@ -35,20 +36,29 @@ const Recipes = () => { return

Error: {error.message}

} } else { - return data.content.map(view => ( - - )) + return ( + <> +

Recipes

+
+ {data.content.map(view => ( + + ))} +
+ + ) } } diff --git a/src/pages/recipes/recipes.module.css b/src/pages/recipes/recipes.module.css new file mode 100644 index 0000000..0f8e170 --- /dev/null +++ b/src/pages/recipes/recipes.module.css @@ -0,0 +1,23 @@ +.recipe-list { + display: grid; + justify-content: space-evenly; + gap: 20px; +} + +@media screen and (min-width: 900px) { + .recipe-list { + grid-template-columns: repeat(2, 1fr); + } +} + +@media screen and (min-width: 1300px) { + .recipe-list { + grid-template-columns: repeat(3, 1fr); + } +} + +@media screen and (min-width: 1700px) { + .recipe-list { + grid-template-columns: repeat(4, 1fr); + } +} diff --git a/src/routes/__root.module.css b/src/routes/__root.module.css new file mode 100644 index 0000000..2690c4c --- /dev/null +++ b/src/routes/__root.module.css @@ -0,0 +1,3 @@ +main { + padding: 20px; +} diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 9da6112..044e0bb 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,39 +1,18 @@ -import { - Outlet, - createRootRouteWithContext, - useNavigate, - useRouter -} from '@tanstack/react-router' +import { Outlet, createRootRouteWithContext } from '@tanstack/react-router' import { TanStackRouterDevtools } from '@tanstack/router-devtools' import RouterContext from '../RouterContext' -import { useAuth } from '../auth' +import Header from '../components/header/Header' +import Footer from '../components/footer/Footer' +import './__root.module.css' const RootLayout = () => { - const auth = useAuth() - const router = useRouter() - const navigate = useNavigate() - - const onLogout = async () => { - auth.clearToken(async () => { - await router.invalidate() - await navigate({ to: '/login' }) - }) - } - return ( <> -
-

Meals Made Easy

- -
+
-
-

Copyright 2024 Jesse R. Brault. All rights reserved.

-
+