Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,34 @@ import RecipeListPage from './routes/RecipeListPage'
import RecipeDetailPage from './routes/RecipeDetailPage'
import FavoritesPage from './routes/FavoritesPage'
import ShoppingListPage from './routes/ShoppingListPage'
import NewRecipePage from './routes/NewRecipePage'
import ProfilePage from './routes/ProfilePage'
import NotFoundPage from './routes/NotFoundPage'
import DesignTestPage from './routes/DesignTestPage'

//flyttet testsiden til designTestPage under routes
// Flyttet testsiden til DesignTestPage under routes
export default function App() {
return (
<Routes>
{/* Layout-rute: alle sidene under vises inni Layout (med felles header) */}
{/* Alle sidene under vises inni Layout med felles header */}
<Route element={<Layout />}>
<Route index element={<HomePage />} />
{/* Alle oppskrifter, og søkeresultater med ?q=... */}

{/* Oppskrifter */}
<Route path="recipes" element={<RecipeListPage />} />
<Route path="recipes/:id" element={<RecipeDetailPage />} />

<Route path="favorites" element={<FavoritesPage />} />
<Route path="shopping-list" element={<ShoppingListPage />} />
<Route path="new-recipe" element={<NewRecipePage />} />
<Route path="profile" element={<ProfilePage />} />
{/* Testside for designsystemet. Finnes bare i utvikling (npm run dev) */}
{import.meta.env.DEV && <Route path="design" element={<DesignTestPage />} />}
{/* Hvis det er noen stier som ikke matcher de over */}

{/* Testside for designsystemet */}
{import.meta.env.DEV && (
<Route path="design" element={<DesignTestPage />} />
)}

{/* Hvis ingen av stiene over matcher */}
<Route path="*" element={<NotFoundPage />} />
</Route>
</Routes>
)
}
}
95 changes: 60 additions & 35 deletions client/src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,94 @@
import { useState } from 'react'
import { Link, NavLink, useSearchParams } from 'react-router'
import SearchBar from './SearchBar'
import { Button } from '../ui/Button'
import { Dialog } from '../ui/Dialog'
import NewRecipePage, {
RecipeStepIndicator,
} from '../../routes/NewRecipePage'
import NewRecipePage from '../../routes/NewRecipePage'
import { RecipeStepIndicator } from '../new-recipe/RecipeStepIndicator'

// Fokusmarkering ved tastaturnavigasjon
const focusRing =
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary';
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary'

// Aktiv lenke markeres med både farge og understrek, slik at det ikke bare er farge som skiller den ut. NavLink setter aria-current="page" automatisk.
// Aktiv lenke markeres med både farge og understrek
function navLinkClass({ isActive }: { isActive: boolean }) {
const base = `whitespace-nowrap font-body transition-colors hover:text-primary ${focusRing}`;
const base = `whitespace-nowrap font-body transition-colors hover:text-primary ${focusRing}`

return isActive
? `${base} text-primary underline underline-offset-4`
: `${base} text-text`;
: `${base} text-text`
}

// Lenkene er stylet som Button, men er lenker fordi de navigerer.
// whitespace-nowrap hindrer at teksten brytes over to linjer.
const buttonBase = `whitespace-nowrap rounded-medium px-3 py-2 text-sm font-body transition-colors ${focusRing}`;
// Styling for knapper/lenker i header
const buttonBase = `whitespace-nowrap rounded-medium px-3 py-2 text-sm font-body transition-colors ${focusRing}`

// Hovedknapp, understreket når siden er aktiv
/*function newRecipeClass({ isActive }: { isActive: boolean }) {
const base = `${buttonBase} bg-primary text-background hover:bg-primary-hover`;
return isActive ? `${base} underline underline-offset-4` : base;
}*/

// underknapp, fylt når siden er aktiv
// Brukerknapp
function userClass({ isActive }: { isActive: boolean }) {
const base = `${buttonBase} border border-primary`;
const base = `${buttonBase} border border-primary`

return isActive
? `${base} bg-primary text-background`
: `${base} text-primary hover:bg-pink-light`;
: `${base} text-primary hover:bg-pink-light`
}

export default function Header() {
// Søkeordet fra URL-en, slik at det viser gjeldende søk
const [searchParams] = useSearchParams();
const query = searchParams.get('q') ?? '';
// Søkeordet fra URL-en
const [searchParams] = useSearchParams()
const query = searchParams.get('q') ?? ''

// Holder styr på hvilket steg i Ny oppskrift brukeren er på
const [currentStep, setCurrentStep] = useState(1)

return (
<header className="border-b border-secondary bg-background px-6 py-4">
{/* På store skjermer ligger alt på én linje. På mindre skjermer flyttes søkefeltet under menyen. */}
<div className="mx-auto flex max-w-6xl flex-wrap items-center justify-between gap-x-8 gap-y-4">
{/* Logoen lenker til forsiden */}

{/* Logo */}
<Link
to="/"
className={`shrink-0 font-heading text-3xl text-primary ${focusRing}`}
>
Oppskriftsbok
</Link>

{/* key tvinger feltet til å oppdatere seg når søkeordet i URL-en endres, f.eks. ved tilbakeknappen */}
<SearchBar key={query} initialQuery={query} />
{/* Søkefelt */}
<SearchBar
key={query}
initialQuery={query}
/>

{/* Navigasjon */}
<nav aria-label="Hovedmeny">
<ul className="flex flex-wrap items-center gap-x-6 gap-y-3">

<li>
<NavLink to="/recipes" className={navLinkClass}>
<NavLink
to="/recipes"
className={navLinkClass}
>
Oppskrifter
</NavLink>
</li>

<li>
<NavLink to="/favorites" className={navLinkClass}>
<NavLink
to="/favorites"
className={navLinkClass}
>
Favoritter
</NavLink>
</li>

<li>
<NavLink to="/shopping-list" className={navLinkClass}>
<NavLink
to="/shopping-list"
className={navLinkClass}
>
Handleliste
</NavLink>
</li>

{/* Ny oppskrift */}
<li>
<Dialog
trigger={
Expand All @@ -87,19 +100,31 @@ export default function Header() {
</Button>
}
title="Ny oppskrift"
headerContent={<RecipeStepIndicator />}
headerContent={
<RecipeStepIndicator
currentStep={currentStep}
/>
}
>
<NewRecipePage />
<NewRecipePage
currentStep={currentStep}
setCurrentStep={setCurrentStep}
/>
</Dialog>
</li>

<li>
<NavLink to="/profile" className={userClass}>
<NavLink
to="/profile"
className={userClass}
>
Bruker
</NavLink>
</li>

</ul>
</nav>
</div>
</header>
);
}
)
}
Loading