From 1ae79df149c4f19b6c2b50b885d5cbf9d9f24f33 Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Mon, 5 Oct 2026 12:56:32 +0200 Subject: [PATCH 1/5] midlertidig login --- client/src/App.tsx | 2 ++ client/src/routes/LoginPage.tsx | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 client/src/routes/LoginPage.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index ef1b528..090dc2c 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -9,6 +9,7 @@ import NewRecipePage from './routes/NewRecipePage' import ProfilePage from './routes/ProfilePage' import NotFoundPage from './routes/NotFoundPage' import DesignTestPage from './routes/DesignTestPage' +import LoginPage from './routes/LoginPage' //flyttet testsiden til designTestPage under routes export default function App() { @@ -24,6 +25,7 @@ export default function App() { } /> } /> } /> + } /> {/* Testside for designsystemet. Finnes bare i utvikling (npm run dev) */} {import.meta.env.DEV && } />} {/* Hvis det er noen stier som ikke matcher de over */} diff --git a/client/src/routes/LoginPage.tsx b/client/src/routes/LoginPage.tsx new file mode 100644 index 0000000..bf39878 --- /dev/null +++ b/client/src/routes/LoginPage.tsx @@ -0,0 +1,22 @@ +import { Button } from '../components/ui/Button'; + +// Innloggingsside +export default function LoginPage() { + return ( +
+

Logg inn

+

Logg inn for å lagre favoritter og egne oppskrifter.

+ + {/* Midlertidig: Knappene kobles til backend senere */} + + + +
+ ); +} \ No newline at end of file From ec29e184b62f96aefcdf9789e13d48b3b64dedf3 Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Mon, 5 Oct 2026 13:12:28 +0200 Subject: [PATCH 2/5] midlertidig app --- client/src/App.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/App.tsx b/client/src/App.tsx index b1fdf0b..e5a1653 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -9,6 +9,7 @@ import ProfilePage from './routes/ProfilePage' import NotFoundPage from './routes/NotFoundPage' import DesignTestPage from './routes/DesignTestPage' import LoginPage from './routes/LoginPage' +import NewRecipePage from './routes/NewRecipePage' // Flyttet testsiden til DesignTestPage under routes export default function App() { @@ -21,10 +22,12 @@ export default function App() { {/* Oppskrifter */} } /> } /> + { /* TODO: fiks problemet med dette: } /> */ } } /> } /> } /> + } /> {/* Testside for designsystemet */} {import.meta.env.DEV && ( From c84b3572eb5a9bae402ae479848e7b395439dbbf Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Mon, 5 Oct 2026 17:54:20 +0200 Subject: [PATCH 3/5] mock bruker og hook --- client/src/App.tsx | 30 +++++----- client/src/components/layout/Header.tsx | 73 +++++++++---------------- client/src/lib/useCurrentUser.ts | 16 ++++++ client/src/routes/LoginPage.tsx | 2 +- client/src/types/user.ts | 7 +++ 5 files changed, 64 insertions(+), 64 deletions(-) create mode 100644 client/src/lib/useCurrentUser.ts create mode 100644 client/src/types/user.ts diff --git a/client/src/App.tsx b/client/src/App.tsx index e5a1653..f494794 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,15 +1,15 @@ -import { Route, Routes } from 'react-router' -import Layout from './components/layout/Layout' -import HomePage from './routes/HomePage' -import RecipeListPage from './routes/RecipeListPage' -import RecipeDetailPage from './routes/RecipeDetailPage' -import FavoritesPage from './routes/FavoritesPage' -import ShoppingListPage from './routes/ShoppingListPage' -import ProfilePage from './routes/ProfilePage' -import NotFoundPage from './routes/NotFoundPage' -import DesignTestPage from './routes/DesignTestPage' -import LoginPage from './routes/LoginPage' -import NewRecipePage from './routes/NewRecipePage' +import { Route, Routes } from 'react-router'; +import Layout from './components/layout/Layout'; +import HomePage from './routes/HomePage'; +import RecipeListPage from './routes/RecipeListPage'; +import RecipeDetailPage from './routes/RecipeDetailPage'; +import FavoritesPage from './routes/FavoritesPage'; +import ShoppingListPage from './routes/ShoppingListPage'; +import ProfilePage from './routes/ProfilePage'; +import NotFoundPage from './routes/NotFoundPage'; +import DesignTestPage from './routes/DesignTestPage'; +import LoginPage from './routes/LoginPage'; +/* import NewRecipePage from './routes/NewRecipePage' */ // Flyttet testsiden til DesignTestPage under routes export default function App() { @@ -22,7 +22,7 @@ export default function App() { {/* Oppskrifter */} } /> } /> - { /* TODO: fiks problemet med dette: } /> */ } + {/* TODO: fiks problemet med dette: } /> */} } /> } /> @@ -38,5 +38,5 @@ export default function App() { } /> - ) -} \ No newline at end of file + ); +} diff --git a/client/src/components/layout/Header.tsx b/client/src/components/layout/Header.tsx index 654a49e..ed66e22 100644 --- a/client/src/components/layout/Header.tsx +++ b/client/src/components/layout/Header.tsx @@ -1,48 +1,47 @@ -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 from '../../routes/NewRecipePage' -import { RecipeStepIndicator } from '../new-recipe/RecipeStepIndicator' +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 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 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`; } // Styling for knapper/lenker i header -const buttonBase = `whitespace-nowrap rounded-medium px-3 py-2 text-sm font-body transition-colors ${focusRing}` +const buttonBase = `whitespace-nowrap rounded-medium px-3 py-2 text-sm font-body transition-colors ${focusRing}`; // 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 - const [searchParams] = useSearchParams() - const query = searchParams.get('q') ?? '' + const [searchParams] = useSearchParams(); + const query = searchParams.get('q') ?? ''; // Holder styr på hvilket steg i Ny oppskrift brukeren er på - const [currentStep, setCurrentStep] = useState(1) + const [currentStep, setCurrentStep] = useState(1); return (
- {/* Logo */} {/* Søkefelt */} - + {/* Navigasjon */}
- ) -} \ No newline at end of file + ); +} diff --git a/client/src/lib/useCurrentUser.ts b/client/src/lib/useCurrentUser.ts new file mode 100644 index 0000000..b359c94 --- /dev/null +++ b/client/src/lib/useCurrentUser.ts @@ -0,0 +1,16 @@ +import type { User } from '../types/user'; + +// Midlertidig bruker til backend er klar. Sett til null for å teste som utlogget. +const MOCK_USER: User | null = { + id: '1', + name: 'testesen', + authProvider: 'TEST', +}; + +// Hvem som er innlogget +export function useCurrentUser() { + return { + user: MOCK_USER, + loading: 'false', + }; +} \ No newline at end of file diff --git a/client/src/routes/LoginPage.tsx b/client/src/routes/LoginPage.tsx index bf39878..e644d11 100644 --- a/client/src/routes/LoginPage.tsx +++ b/client/src/routes/LoginPage.tsx @@ -19,4 +19,4 @@ export default function LoginPage() { ); -} \ No newline at end of file +} diff --git a/client/src/types/user.ts b/client/src/types/user.ts new file mode 100644 index 0000000..71431ca --- /dev/null +++ b/client/src/types/user.ts @@ -0,0 +1,7 @@ +export type AuthProvider = 'GOOGLE' | 'GUEST' | 'TEST' + +export type User = { + id: string + name: string + authProvider: AuthProvider +}; From 7354f55510c1a3a119cbc400ba5a8eaa518aac63 Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Thu, 8 Oct 2026 21:10:17 +0200 Subject: [PATCH 4/5] fiks av innloggingsside --- client/.env.example | 2 +- client/src/App.tsx | 14 +++- client/src/components/layout/Header.tsx | 8 +- client/src/components/layout/RequireAuth.tsx | 17 ++++ client/src/lib/useCurrentUser.ts | 8 +- client/src/routes/LoginPage.tsx | 66 +++++++++++---- client/src/routes/TestUserLoginPage.tsx | 85 ++++++++++++++++++++ client/vite.config.ts | 9 +++ 8 files changed, 183 insertions(+), 26 deletions(-) create mode 100644 client/src/components/layout/RequireAuth.tsx create mode 100644 client/src/routes/TestUserLoginPage.tsx diff --git a/client/.env.example b/client/.env.example index f40b204..0ba98e5 100644 --- a/client/.env.example +++ b/client/.env.example @@ -1,2 +1,2 @@ # Adressen til Graphql backend. Kopier dette til .env.local -VITE_GRAPHQL_URL=http://localhost:3001/graphql \ No newline at end of file +VITE_GRAPHQL_URL=/project2/graphql \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx index f494794..3351b80 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -9,7 +9,8 @@ import ProfilePage from './routes/ProfilePage'; import NotFoundPage from './routes/NotFoundPage'; import DesignTestPage from './routes/DesignTestPage'; import LoginPage from './routes/LoginPage'; -/* import NewRecipePage from './routes/NewRecipePage' */ +import TestUserLoginPage from './routes/TestUserLoginPage'; +import RequireAuth from './components/layout/RequireAuth'; // Flyttet testsiden til DesignTestPage under routes export default function App() { @@ -22,12 +23,17 @@ export default function App() { {/* Oppskrifter */} } /> } /> - {/* TODO: fiks problemet med dette: } /> */} - } /> } /> - } /> + } /> + } /> + + {/* alle sidene som krever innlogging */} + }> + } /> + } /> + {/* Testside for designsystemet */} {import.meta.env.DEV && ( diff --git a/client/src/components/layout/Header.tsx b/client/src/components/layout/Header.tsx index ed66e22..032d8cc 100644 --- a/client/src/components/layout/Header.tsx +++ b/client/src/components/layout/Header.tsx @@ -5,6 +5,7 @@ import { Button } from '../ui/Button'; import { Dialog } from '../ui/Dialog'; import NewRecipePage from '../../routes/NewRecipePage'; import { RecipeStepIndicator } from '../new-recipe/RecipeStepIndicator'; +import { useCurrentUser } from '../../lib/useCurrentUser'; // Fokusmarkering ved tastaturnavigasjon const focusRing = @@ -32,6 +33,8 @@ function userClass({ isActive }: { isActive: boolean }) { } export default function Header() { + //hvem som er logget inn + const { user } = useCurrentUser(); // Søkeordet fra URL-en const [searchParams] = useSearchParams(); const query = searchParams.get('q') ?? ''; @@ -93,10 +96,9 @@ export default function Header() { /> -
  • - - Bruker + + {user ? 'Bruker' : 'Logg inn'}
  • diff --git a/client/src/components/layout/RequireAuth.tsx b/client/src/components/layout/RequireAuth.tsx new file mode 100644 index 0000000..2fdf75c --- /dev/null +++ b/client/src/components/layout/RequireAuth.tsx @@ -0,0 +1,17 @@ +import { Navigate, Outlet } from 'react-router'; +import { useCurrentUser } from '../../lib/useCurrentUser'; + +// Sender utloggede brukere til innloggingssiden +export default function RequireAuth() { + const { user, loading } = useCurrentUser(); + + // venter på svar om hvem som logger inn + if (loading) { return null; } + + // hvis ikke innlogget, sender til innloggingsside + if (!user) { return ; } + + + // hvis innlogget, vis side + return ; +} \ No newline at end of file diff --git a/client/src/lib/useCurrentUser.ts b/client/src/lib/useCurrentUser.ts index b359c94..f7f9875 100644 --- a/client/src/lib/useCurrentUser.ts +++ b/client/src/lib/useCurrentUser.ts @@ -1,16 +1,16 @@ import type { User } from '../types/user'; // Midlertidig bruker til backend er klar. Sett til null for å teste som utlogget. -const MOCK_USER: User | null = { +/* const MOCK_USER: User | null = { id: '1', name: 'testesen', authProvider: 'TEST', -}; +}; */ // Hvem som er innlogget export function useCurrentUser() { return { - user: MOCK_USER, - loading: 'false', + user: null, + loading: false, }; } \ No newline at end of file diff --git a/client/src/routes/LoginPage.tsx b/client/src/routes/LoginPage.tsx index e644d11..086a6e4 100644 --- a/client/src/routes/LoginPage.tsx +++ b/client/src/routes/LoginPage.tsx @@ -1,22 +1,60 @@ +import { useNavigate } from 'react-router'; import { Button } from '../components/ui/Button'; // Innloggingsside export default function LoginPage() { + const navigate = useNavigate(); + return ( -
    -

    Logg inn

    -

    Logg inn for å lagre favoritter og egne oppskrifter.

    +
    +

    Velkommen tilbake

    +

    + Logg inn med Google, utforsk oppskriftene som gjest eller testbruker. +

    + + {/* Midlertidig: Google og gjest kobles til backend senere */} +
    + +

    + Lagre favorittene dine og del egne oppskrifter. +

    +
    + + {/* Skiller Google innlogging fra de andre valgene */} +
    + + eller + +
    + +
    + +

    Se oppskrifter uten å logge inn.

    +
    - {/* Midlertidig: Knappene kobles til backend senere */} - - - +
    + {/* Går til logg inn siden for testbrukeren */} + +

    Prøv med en ferdig testkonto.

    +
    ); -} +} \ No newline at end of file diff --git a/client/src/routes/TestUserLoginPage.tsx b/client/src/routes/TestUserLoginPage.tsx new file mode 100644 index 0000000..99b362d --- /dev/null +++ b/client/src/routes/TestUserLoginPage.tsx @@ -0,0 +1,85 @@ +import { useState, type SubmitEvent } from 'react'; +import { Link } from 'react-router'; +import VisibilityIcon from '@mui/icons-material/Visibility'; +import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; +import { Button } from '../components/ui/Button'; +import { Field } from '../components/ui/Field'; +import { Input } from '../components/ui/Input'; + +// Innlogging for testbrukeren +export default function TestUserLoginPage() { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + // Om passordet vises som tekst eller prikker + const [showPassword, setShowPassword] = useState(false); + + function handleSubmit(event: SubmitEvent) { + // Hindrer at siden lastes på nytt + event.preventDefault(); + + // Midlertidig: kobles til backend senere + console.log('testbruker', username); + } + + return ( +
    +

    Innlogging

    +

    + Logg inn med testbrukeren for en ferdiglaget bruker med oppskrifter. +

    + +
    + + setUsername(event.target.value)} + placeholder="Brukernavn" + autoComplete="username" + required + /> + + + +
    + setPassword(event.target.value)} + placeholder="Passord" + autoComplete="current-password" + className="pr-12" + required + /> + {/* Øyeknapp som viser eller skjuler passordet */} + +
    +
    + + +
    + + + Tilbake til innloggingsvalg + +
    + ); +} \ No newline at end of file diff --git a/client/vite.config.ts b/client/vite.config.ts index 3f961fd..f2af69c 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -6,4 +6,13 @@ import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [react(), tailwindcss()], base: '/project2/', + // sender graphql videre til backend + server: { + proxy: { + '/project2/graphql': { + target: 'http://localhost:3001', + rewrite: (path) => path.replace(/^\/project2/, ''), + }, + }, + }, }); From 48fd22c7564074418826c18ed79e220e710df6d0 Mon Sep 17 00:00:00 2001 From: Mari Zhevagin Date: Thu, 8 Oct 2026 21:15:46 +0200 Subject: [PATCH 5/5] =?UTF-8?q?kj=C3=B8rte=20prettier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.tsx | 4 ++-- client/src/components/layout/RequireAuth.tsx | 11 +++++++---- client/src/lib/apolloClient.ts | 1 - client/src/lib/useCurrentUser.ts | 7 +++++-- client/src/routes/LoginPage.tsx | 2 +- client/src/routes/TestUserLoginPage.tsx | 2 +- client/src/types/user.ts | 8 ++++---- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index 3351b80..4723f7e 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -31,8 +31,8 @@ export default function App() { {/* alle sidene som krever innlogging */} }> - } /> - } /> + } /> + } /> {/* Testside for designsystemet */} diff --git a/client/src/components/layout/RequireAuth.tsx b/client/src/components/layout/RequireAuth.tsx index 2fdf75c..7d355ed 100644 --- a/client/src/components/layout/RequireAuth.tsx +++ b/client/src/components/layout/RequireAuth.tsx @@ -6,12 +6,15 @@ export default function RequireAuth() { const { user, loading } = useCurrentUser(); // venter på svar om hvem som logger inn - if (loading) { return null; } + if (loading) { + return null; + } // hvis ikke innlogget, sender til innloggingsside - if (!user) { return ; } - + if (!user) { + return ; + } // hvis innlogget, vis side return ; -} \ No newline at end of file +} diff --git a/client/src/lib/apolloClient.ts b/client/src/lib/apolloClient.ts index 860cdd4..f4dbc89 100644 --- a/client/src/lib/apolloClient.ts +++ b/client/src/lib/apolloClient.ts @@ -1,6 +1,5 @@ import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client'; - // adressen til graphql backend const httpLink = new HttpLink({ uri: import.meta.env.VITE_GRAPHQL_URL, diff --git a/client/src/lib/useCurrentUser.ts b/client/src/lib/useCurrentUser.ts index f7f9875..b10dd7e 100644 --- a/client/src/lib/useCurrentUser.ts +++ b/client/src/lib/useCurrentUser.ts @@ -1,6 +1,9 @@ import type { User } from '../types/user'; // Midlertidig bruker til backend er klar. Sett til null for å teste som utlogget. + +const MOCK_USER: User | null = null; + /* const MOCK_USER: User | null = { id: '1', name: 'testesen', @@ -10,7 +13,7 @@ import type { User } from '../types/user'; // Hvem som er innlogget export function useCurrentUser() { return { - user: null, + user: MOCK_USER, loading: false, }; -} \ No newline at end of file +} diff --git a/client/src/routes/LoginPage.tsx b/client/src/routes/LoginPage.tsx index 086a6e4..97731a4 100644 --- a/client/src/routes/LoginPage.tsx +++ b/client/src/routes/LoginPage.tsx @@ -57,4 +57,4 @@ export default function LoginPage() {
    ); -} \ No newline at end of file +} diff --git a/client/src/routes/TestUserLoginPage.tsx b/client/src/routes/TestUserLoginPage.tsx index 99b362d..ff341e1 100644 --- a/client/src/routes/TestUserLoginPage.tsx +++ b/client/src/routes/TestUserLoginPage.tsx @@ -82,4 +82,4 @@ export default function TestUserLoginPage() { ); -} \ No newline at end of file +} diff --git a/client/src/types/user.ts b/client/src/types/user.ts index 71431ca..0098090 100644 --- a/client/src/types/user.ts +++ b/client/src/types/user.ts @@ -1,7 +1,7 @@ -export type AuthProvider = 'GOOGLE' | 'GUEST' | 'TEST' +export type AuthProvider = 'GOOGLE' | 'GUEST' | 'TEST'; export type User = { - id: string - name: string - authProvider: AuthProvider + id: string; + name: string; + authProvider: AuthProvider; };