Added more frontend and some more login logic
This commit is contained in:
23
frontend/htmx/404.html
Normal file
23
frontend/htmx/404.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>404 - Page Not Found | MiauInv</title>
|
||||
<link rel="stylesheet" href="/assets/css/theme.css">
|
||||
<link rel="stylesheet" href="/assets/css/error404.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main class="card">
|
||||
<div class="error-code">404</div>
|
||||
<h1>Page Not Found</h1>
|
||||
<p class="subtitle" style="margin-bottom: 2rem;">The page you are looking for does not exist or has been moved to another address.</p>
|
||||
|
||||
<a href="/dashboard" class="btn btn-secondary">
|
||||
Back to Dashboard
|
||||
</a>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,27 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
{{ define "base.html" }}
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ .Title }}</title>
|
||||
|
||||
<title>{{ .Title }} | MiauInv</title>
|
||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/theme.css">
|
||||
<link rel="stylesheet" href="/assets/css/dashboard.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<a href="/dashboard">Dashboard</a>
|
||||
<a href="/items">Inventar</a>
|
||||
<a href="/projects">Projekte</a>
|
||||
<a href="/locations">Orte</a>
|
||||
</nav>
|
||||
<header>
|
||||
<div class="nav-container">
|
||||
<div class="nav-left">
|
||||
<div class="brand">Miau<span>Inv</span></div>
|
||||
<nav id="main-nav">
|
||||
<a href="/dashboard">Dashboard</a>
|
||||
<a href="/inventory">Inventory</a>
|
||||
<a href="/projects">Projects</a>
|
||||
<a href="/locations">Locations</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="profile-dropdown">
|
||||
<button class="profile-trigger" id="profile-btn">
|
||||
<div class="avatar">M</div>
|
||||
<span class="username">Profile</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" id="dropdown-menu">
|
||||
<a href="/profile/settings">Account Settings</a>
|
||||
<a href="/profile/activity">Activity Log</a>
|
||||
<hr class="dropdown-divider">
|
||||
<button class="logout-btn"
|
||||
hx-post="/api/logout"
|
||||
hx-trigger="click"
|
||||
hx-on::after-request="
|
||||
if (event.detail.successful) {
|
||||
localStorage.removeItem('access_token');
|
||||
localStorage.removeItem('refresh_token');
|
||||
document.cookie = 'access_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;';
|
||||
document.cookie = 'refresh_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;';
|
||||
window.location.href = '/login';
|
||||
} else {
|
||||
alert('Logout failed. Please try again.');
|
||||
}
|
||||
">
|
||||
Log Out
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{{ template "content" . }}
|
||||
</main>
|
||||
|
||||
<script>
|
||||
document.querySelectorAll('#main-nav a').forEach(link => {
|
||||
if (link.getAttribute('href') === window.location.pathname) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
});
|
||||
|
||||
const profileBtn = document.getElementById('profile-btn');
|
||||
const dropdownMenu = document.getElementById('dropdown-menu');
|
||||
|
||||
profileBtn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
dropdownMenu.classList.toggle('show');
|
||||
});
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
if (dropdownMenu.classList.contains('show')) {
|
||||
dropdownMenu.classList.remove('show');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
{{ end }}
|
||||
@@ -1,24 +1,20 @@
|
||||
{{ define "content" }}
|
||||
|
||||
<h1>Dashboard</h1>
|
||||
|
||||
<div class="cards">
|
||||
|
||||
<div class="card">
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<h2>{{ .Stats.Items }}</h2>
|
||||
<p>Items</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="stat-card">
|
||||
<h2>{{ .Stats.Projects }}</h2>
|
||||
<p>Projekte</p>
|
||||
<p>Projects</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="stat-card">
|
||||
<h2>{{ .Stats.Locations }}</h2>
|
||||
<p>Orte</p>
|
||||
<p>Locations</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
@@ -1,21 +1,24 @@
|
||||
{{ define "content" }}
|
||||
<h1>Inventory</h1>
|
||||
|
||||
<h1>Inventar</h1>
|
||||
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
placeholder="Suchen..."
|
||||
hx-get="/api/items/search"
|
||||
hx-trigger="keyup changed delay:300ms"
|
||||
hx-target="#items"
|
||||
>
|
||||
|
||||
<div
|
||||
id="items"
|
||||
hx-get="/api/items"
|
||||
hx-trigger="load"
|
||||
>
|
||||
<div class="action-bar">
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
class="search-input"
|
||||
placeholder="Search..."
|
||||
hx-get="/api/item/search"
|
||||
hx-trigger="keyup changed delay:300ms"
|
||||
hx-target="#items"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<div
|
||||
id="items"
|
||||
hx-get="/api/item"
|
||||
hx-trigger="load"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
@@ -1,32 +1,20 @@
|
||||
<table>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Kategorie</th>
|
||||
<th>Gesamt</th>
|
||||
<th>Frei</th>
|
||||
<th>Category</th>
|
||||
<th>Total</th>
|
||||
<th>Free</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
{{ range . }}
|
||||
|
||||
<tr>
|
||||
|
||||
<td>{{ .Name }}</td>
|
||||
|
||||
<td>{{ .Category }}</td>
|
||||
|
||||
<td>{{ .TotalQuantity }}</td>
|
||||
|
||||
<td>{{ .FreeQuantity }}</td>
|
||||
|
||||
<td style="font-weight: 600;">{{ .Name }}</td>
|
||||
<td><span style="color: var(--text-muted);">{{ .Category }}</span></td>
|
||||
<td style="font-family: monospace;">{{ .TotalQuantity }}</td>
|
||||
<td style="font-family: monospace; color: var(--success);">{{ .FreeQuantity }}</td>
|
||||
</tr>
|
||||
|
||||
{{ end }}
|
||||
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
@@ -1,11 +1,11 @@
|
||||
{{ define "content" }}
|
||||
<h1>Locations</h1>
|
||||
|
||||
<h1>Lagerorte</h1>
|
||||
|
||||
<div
|
||||
hx-get="/api/locations"
|
||||
hx-trigger="load"
|
||||
>
|
||||
<div class="table-container">
|
||||
<div
|
||||
hx-get="/api/locations"
|
||||
hx-trigger="load"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
@@ -1,21 +1,22 @@
|
||||
{{ define "content" }}
|
||||
|
||||
<h1>Projekte</h1>
|
||||
|
||||
<button
|
||||
hx-get="/projects/new"
|
||||
hx-target="#modal"
|
||||
>
|
||||
Neues Projekt
|
||||
</button>
|
||||
<div class="action-bar">
|
||||
<h1>Projects</h1>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
style="width: auto; padding: 0.6rem 1.2rem; font-size: 0.95rem;"
|
||||
hx-get="/project/new"
|
||||
hx-target="#modal"
|
||||
>
|
||||
New Project
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
hx-get="/api/projects"
|
||||
hx-get="/api/project"
|
||||
hx-trigger="load"
|
||||
hx-target="this"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div id="modal"></div>
|
||||
|
||||
{{ end }}
|
||||
@@ -1,6 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Hallo, {{.Name}}!</h1>
|
||||
</body>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MiauInv | Private Instance</title>
|
||||
<script src="/assets/js/auth.js"></script>
|
||||
<link rel="stylesheet" href="/assets/css/theme.css">
|
||||
<link rel="stylesheet" href="/assets/css/home.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main class="card">
|
||||
<div class="header">
|
||||
<h1 class="brand-title">Miau<span>Inv</span></h1>
|
||||
<p class="subtitle">Private Instance</p>
|
||||
</div>
|
||||
|
||||
<div class="home-actions">
|
||||
<a href="/login" class="btn btn-primary">Sign In</a>
|
||||
<a href="/register" class="btn btn-secondary">Create Account</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
43
frontend/htmx/login.html
Normal file
43
frontend/htmx/login.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sign In | MiauInv</title>
|
||||
|
||||
<script src="/assets/js/auth.js" defer></script>
|
||||
<script src="/assets/js/login.js" defer></script>
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/theme.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main class="card">
|
||||
<div class="header">
|
||||
<h1>Welcome back</h1>
|
||||
<p class="subtitle">Sign in to your account</p>
|
||||
</div>
|
||||
|
||||
<form id="login-form">
|
||||
<div class="form-group">
|
||||
<label for="username" class="sr-only">Username</label>
|
||||
<input type="text" id="username" placeholder="Username" autocomplete="username" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password" class="sr-only">Password</label>
|
||||
<input type="password" id="password" placeholder="Password" autocomplete="current-password" required>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Sign In</button>
|
||||
</form>
|
||||
|
||||
<div id="error" class="message error"></div>
|
||||
|
||||
<p class="footer-text">
|
||||
Don't have an account yet? <a href="/register">Create account</a>
|
||||
</p>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
41
frontend/htmx/register.html
Normal file
41
frontend/htmx/register.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Register | MiauInv</title>
|
||||
<script src="/assets/js/auth.js"></script>
|
||||
<link rel="stylesheet" href="/assets/css/theme.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main class="card">
|
||||
<div class="header">
|
||||
<h1>Create Account</h1>
|
||||
<p class="subtitle">Register to continue</p>
|
||||
</div>
|
||||
|
||||
<form id="register-form">
|
||||
<div class="form-group">
|
||||
<label for="username" class="sr-only">Username</label>
|
||||
<input type="text" id="username" placeholder="Username" autocomplete="username" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password" class="sr-only">Password</label>
|
||||
<input type="password" id="password" placeholder="Password" autocomplete="new-password" required>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Register</button>
|
||||
</form>
|
||||
|
||||
<div id="message" class="message"></div>
|
||||
|
||||
<p class="footer-text">
|
||||
Already have an account? <a href="/login">Sign in here</a>
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<script src="/assets/js/register.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user