Index: pages/auth/login/+Page.tsx
===================================================================
--- pages/auth/login/+Page.tsx	(revision 67dfe576d088a64527df41c04054063cbba96c6d)
+++ pages/auth/login/+Page.tsx	(revision 67dfe576d088a64527df41c04054063cbba96c6d)
@@ -0,0 +1,88 @@
+import React, { useState } from "react";
+import { Container, Box, Typography, TextField, Button, Paper, Alert } from "@mui/material";
+
+export default function LoginPage() {
+    const [error, setError] = useState<string | null>(null);
+
+    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
+        event.preventDefault();
+        setError(null);
+
+        const formData = new FormData(event.currentTarget);
+        const username = formData.get("username");
+        const password = formData.get("password");
+
+        const res = await fetch("/api/auth/callback/credentials", {
+            method: "POST",
+            headers: { "Content-Type": "application/json" },
+            body: JSON.stringify({
+                username,
+                password,
+                csrfToken: await getCsrfToken(),
+            }),
+        });
+
+        if (res.url.includes("error")) {
+            setError("Invalid username or password");
+        } else {
+            window.location.href = "/dashboard/user";
+        }
+    };
+
+    return (
+        <Container component="main" maxWidth="xs">
+            <Box sx={{ marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center" }}>
+                <Paper elevation={3} sx={{ p: 4, width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
+
+                    <Typography component="h1" variant="h5">
+                        Log in
+                    </Typography>
+
+                    {error && (
+                        <Alert severity="error" sx={{ mt: 2, width: '100%' }}>
+                            {error}
+                        </Alert>
+                    )}
+
+                    <Box component="form" onSubmit={handleSubmit} sx={{ mt: 1, width: '100%' }}>
+                        <TextField
+                            margin="normal"
+                            required
+                            fullWidth
+                            id="username"
+                            label="Username"
+                            name="username"
+                            autoComplete="username"
+                            autoFocus
+                        />
+                        <TextField
+                            margin="normal"
+                            required
+                            fullWidth
+                            name="password"
+                            label="Password"
+                            type="password"
+                            id="password"
+                            autoComplete="current-password"
+                        />
+
+                        <Button
+                            type="submit"
+                            fullWidth
+                            variant="contained"
+                            sx={{ mt: 3, mb: 2 }}
+                        >
+                            Sign In
+                        </Button>
+                    </Box>
+                </Paper>
+            </Box>
+        </Container>
+    );
+}
+
+async function getCsrfToken() {
+    const res = await fetch("/api/auth/csrf");
+    const data = await res.json();
+    return data.csrfToken;
+}
Index: pages/auth/register/+Page.tsx
===================================================================
--- pages/auth/register/+Page.tsx	(revision 67dfe576d088a64527df41c04054063cbba96c6d)
+++ pages/auth/register/+Page.tsx	(revision 67dfe576d088a64527df41c04054063cbba96c6d)
@@ -0,0 +1,88 @@
+import React, {useState} from "react";
+import {Container, Box, Typography, TextField, Button, Paper, Alert, AlertColor} from "@mui/material";
+import {registerNewUser} from "./register.telefunc";
+
+export default function RegisterPage() {
+    const [username, setUsername] = useState("");
+    const [email, setEmail] = useState("");
+    const [password, setPassword] = useState("");
+    const [loading, setLoading] = useState(false);
+    const [message, setMessage] = useState<string | null>(null);
+    const [severity, setSeverity] = useState<AlertColor>("info");
+
+    async function onSubmit(e: React.FormEvent) {
+        e.preventDefault();
+        setLoading(true);
+        setMessage(null);
+
+        try {
+            const result = await registerNewUser({username, email, password});
+            if (result?.success) {
+                setSeverity("success");
+                setMessage("Registration successful! Redirecting...");
+                window.location.href = "/auth/login";
+            } else {
+                setSeverity("error");
+                setMessage("Registration failed.");
+            }
+        } catch (err) {
+            setSeverity("error");
+            setMessage("An error occurred. Please try again.");
+        } finally {
+            setLoading(false);
+        }
+    }
+
+    return (
+        <Container component="main" maxWidth="xs">
+            <Box sx={{marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center", color: "white"}}>
+                <Paper elevation={3} sx={{p: 4, width: '100%'}}>
+                    <Typography component="h1" variant="h5" align="center">
+                        Register
+                    </Typography>
+
+                    <Box component="form" onSubmit={onSubmit} sx={{mt: 3}}>
+                        <TextField
+                            margin="normal"
+                            required
+                            fullWidth
+                            label="Username"
+                            value={username}
+                            onChange={(e) => setUsername(e.target.value)}
+                        />
+                        <TextField
+                            margin="normal"
+                            required
+                            fullWidth
+                            label="Email Address"
+                            type="email"
+                            value={email}
+                            onChange={(e) => setEmail(e.target.value)}
+                        />
+                        <TextField
+                            margin="normal"
+                            required
+                            fullWidth
+                            label="Password"
+                            type="password"
+                            value={password}
+                            onChange={(e) => setPassword(e.target.value)}
+                        />
+
+                        <Button
+                            type="submit"
+                            fullWidth
+                            variant="contained"
+                            disabled={loading}
+                            sx={{mt: 3, mb: 2, color: "white"}}
+                        >
+                            {loading ? "Registering..." : "Register"}
+                        </Button>
+
+                        {message && <Alert severity={severity}>{message}</Alert>}
+                    </Box>
+                </Paper>
+            </Box>
+        </Container>
+    );
+}
