Initial commit

This commit is contained in:
2026-03-25 11:37:46 -04:00
commit dfdbb54875
41 changed files with 5079 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>Login — TechDesk</title>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600&display=swap" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet"/>
<style>
:root{--bg:#f0f4f8;--surface:#ffffff;--border:#e2e8f0;--border2:#cbd5e1;--accent:#2563eb;--accent-h:#1d4ed8;--text:#0f172a;--text2:#334155;--muted:#64748b;}
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;overflow:hidden;}
.bg-grid{position:fixed;inset:0;background-image:linear-gradient(var(--border) 1px,transparent 1px),linear-gradient(90deg,var(--border) 1px,transparent 1px);background-size:48px 48px;opacity:.6;pointer-events:none;}
.bg-glow{position:fixed;width:700px;height:700px;border-radius:50%;background:radial-gradient(circle,rgba(37,99,235,.06) 0%,transparent 70%);top:-300px;right:-200px;pointer-events:none;}
.card{background:#fff;border:1px solid var(--border);border-radius:16px;padding:40px;width:100%;max-width:420px;position:relative;z-index:1;box-shadow:0 4px 24px rgba(0,0,0,.08);}
.brand{text-align:center;margin-bottom:32px;}
.logo{width:52px;height:52px;background:var(--accent);border-radius:12px;display:flex;align-items:center;justify-content:center;font-family:'Space Mono',monospace;font-weight:700;font-size:17px;color:#fff;margin:0 auto 12px;box-shadow:0 2px 10px rgba(37,99,235,.35);}
h1{font-size:21px;font-weight:700;color:var(--text);}
.subtitle{font-size:13px;color:var(--muted);margin-top:4px;}
.form-group{margin-bottom:18px;}
label{display:block;font-size:12px;font-weight:600;letter-spacing:.4px;color:var(--text2);text-transform:uppercase;margin-bottom:7px;}
input{width:100%;background:#fff;border:1px solid var(--border);color:var(--text);border-radius:9px;padding:11px 14px;font-size:14px;font-family:inherit;transition:border-color .15s,box-shadow .15s;box-shadow:0 1px 3px rgba(0,0,0,.06);}
input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(37,99,235,.1);}
input::placeholder{color:#94a3b8;}
.btn{width:100%;background:var(--accent);border:none;color:#fff;border-radius:9px;padding:12px;font-size:14px;font-weight:600;cursor:pointer;transition:background .15s;font-family:inherit;margin-top:4px;box-shadow:0 2px 6px rgba(37,99,235,.3);}
.btn:hover{background:var(--accent-h);}
.links{text-align:center;margin-top:20px;font-size:13px;color:var(--muted);}
.links a{color:var(--accent);}
.checkbox-row{display:flex;align-items:center;gap:8px;margin-bottom:20px;}
.checkbox-row input[type=checkbox]{width:auto;accent-color:var(--accent);}
.checkbox-row label{margin:0;font-size:13px;text-transform:none;letter-spacing:0;color:var(--text2);}
.alert{border-radius:8px;padding:11px 14px;font-size:13px;margin-bottom:18px;}
.alert-danger{background:#fef2f2;color:#dc2626;border:1px solid #fecaca;}
.alert-success{background:#ecfdf5;color:#059669;border:1px solid #a7f3d0;}
.alert-info{background:#f0f9ff;color:#0284c7;border:1px solid #bae6fd;}
</style>
</head>
<body>
<div class="bg-grid"></div>
<div class="bg-glow"></div>
<div class="card">
<div class="brand">
<div class="logo">TD</div>
<h1>TechDesk</h1>
<p class="subtitle">IT Helpdesk Portal — Sign in to continue</p>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% for cat, msg in messages %}
<div class="alert alert-{{ cat }}"><i class="bi bi-exclamation-circle me-2"></i>{{ msg }}</div>
{% endfor %}
{% endwith %}
<form method="POST">
<div class="form-group">
<label>Email Address</label>
<input type="email" name="email" required placeholder="you@company.com" autofocus/>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" required placeholder="••••••••"/>
</div>
<div class="checkbox-row">
<input type="checkbox" name="remember" id="remember"/>
<label for="remember">Keep me signed in</label>
</div>
<button type="submit" class="btn"><i class="bi bi-box-arrow-in-right me-2"></i>Sign In</button>
</form>
<div class="links">
Don't have an account? <a href="{{ url_for('auth.register') }}">Register here</a>
</div>
</div>
</body>
</html>
+79
View File
@@ -0,0 +1,79 @@
{% extends "base.html" %}
{% block title %}My Profile{% endblock %}
{% block page_title %}My Profile{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-7">
<div class="card">
<div class="card-header"><i class="bi bi-person-circle me-2"></i>Account Settings</div>
<div class="card-body">
<form method="POST">
<!-- Avatar placeholder -->
<div class="text-center mb-4">
<div style="width:80px;height:80px;border-radius:50%;background:var(--accent2);display:flex;align-items:center;justify-content:center;font-size:32px;font-weight:700;color:#fff;margin:0 auto 10px;">
{{ current_user.full_name[0].upper() }}
</div>
<div style="font-size:12px;color:var(--muted);">{{ current_user.email }}</div>
<div style="font-size:11px;background:rgba(0,180,216,.1);color:var(--accent3);display:inline-block;padding:2px 10px;border-radius:12px;margin-top:4px;">
{{ current_user.role.replace('_',' ').upper() }}
</div>
</div>
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Full Name</label>
<input type="text" class="form-control" name="full_name" value="{{ current_user.full_name }}" required/>
</div>
<div class="col-md-6">
<label class="form-label">Department</label>
<input type="text" class="form-control" name="department" value="{{ current_user.department or '' }}"/>
</div>
<div class="col-md-6">
<label class="form-label">Phone</label>
<input type="text" class="form-control" name="phone" value="{{ current_user.phone or '' }}"/>
</div>
<div class="col-md-6">
<label class="form-label">Username</label>
<input type="text" class="form-control" value="{{ current_user.username }}" disabled/>
</div>
</div>
<hr style="border-color:var(--border);margin:24px 0;"/>
<h6 style="font-size:14px;font-weight:700;margin-bottom:16px;">Notification Preferences</h6>
<div class="d-flex flex-column gap-2 mb-4">
<label style="display:flex;align-items:center;gap:10px;cursor:pointer;">
<input type="checkbox" name="email_notif" {% if current_user.email_notif %}checked{% endif %}
style="accent-color:var(--accent3);width:16px;height:16px;"/>
<span style="font-size:14px;"><i class="bi bi-envelope me-2" style="color:var(--accent3);"></i>Email Notifications</span>
</label>
<label style="display:flex;align-items:center;gap:10px;cursor:pointer;">
<input type="checkbox" name="web_notif" {% if current_user.web_notif %}checked{% endif %}
style="accent-color:var(--accent3);width:16px;height:16px;"/>
<span style="font-size:14px;"><i class="bi bi-bell me-2" style="color:var(--accent3);"></i>In-App Notifications</span>
</label>
</div>
<hr style="border-color:var(--border);margin:24px 0;"/>
<h6 style="font-size:14px;font-weight:700;margin-bottom:16px;">Change Password <span style="font-size:12px;color:var(--muted);font-weight:400;">(leave blank to keep current)</span></h6>
<div class="row g-3 mb-4">
<div class="col-md-6">
<label class="form-label">New Password</label>
<input type="password" class="form-control" name="new_password" placeholder="Min. 8 characters"/>
</div>
<div class="col-md-6">
<label class="form-label">Confirm Password</label>
<input type="password" class="form-control" name="confirm_password" placeholder="Repeat password"/>
</div>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary"><i class="bi bi-check2 me-2"></i>Save Changes</button>
<a href="{{ url_for('tickets.dashboard') }}" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
+87
View File
@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>Register — TechDesk</title>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600&display=swap" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet"/>
<style>
:root{--bg:#f0f4f8;--surface:#ffffff;--border:#e2e8f0;--border2:#cbd5e1;--accent:#2563eb;--accent-h:#1d4ed8;--text:#0f172a;--text2:#334155;--muted:#64748b;}
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:'DM Sans',sans-serif;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px;}
.bg-grid{position:fixed;inset:0;background-image:linear-gradient(var(--border) 1px,transparent 1px),linear-gradient(90deg,var(--border) 1px,transparent 1px);background-size:48px 48px;opacity:.6;pointer-events:none;}
.card{background:#fff;border:1px solid var(--border);border-radius:16px;padding:40px;width:100%;max-width:500px;position:relative;z-index:1;box-shadow:0 4px 24px rgba(0,0,0,.08);}
.brand{text-align:center;margin-bottom:28px;}
.logo{width:46px;height:46px;background:var(--accent);border-radius:11px;display:flex;align-items:center;justify-content:center;font-family:'Space Mono',monospace;font-weight:700;font-size:15px;color:#fff;margin:0 auto 10px;box-shadow:0 2px 10px rgba(37,99,235,.3);}
h1{font-size:20px;font-weight:700;color:var(--text);}
.subtitle{font-size:13px;color:var(--muted);margin-top:4px;}
.row{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.form-group{margin-bottom:16px;}
label{display:block;font-size:12px;font-weight:600;letter-spacing:.4px;color:var(--text2);text-transform:uppercase;margin-bottom:6px;}
input,select{width:100%;background:#fff;border:1px solid var(--border);color:var(--text);border-radius:8px;padding:10px 13px;font-size:14px;font-family:inherit;transition:border-color .15s,box-shadow .15s;box-shadow:0 1px 3px rgba(0,0,0,.05);}
input:focus,select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(37,99,235,.1);}
input::placeholder{color:#94a3b8;}
.btn{width:100%;background:var(--accent);border:none;color:#fff;border-radius:9px;padding:12px;font-size:14px;font-weight:600;cursor:pointer;transition:background .15s;font-family:inherit;margin-top:4px;box-shadow:0 2px 6px rgba(37,99,235,.3);}
.btn:hover{background:var(--accent-h);}
.links{text-align:center;margin-top:18px;font-size:13px;color:var(--muted);}
.links a{color:var(--accent);}
.alert{border-radius:8px;padding:10px 13px;font-size:13px;margin-bottom:16px;}
.alert-danger{background:#fef2f2;color:#dc2626;border:1px solid #fecaca;}
</style>
</head>
<body>
<div class="bg-grid"></div>
<div class="card">
<div class="brand">
<div class="logo">TD</div>
<h1>Create Account</h1>
<p class="subtitle">Join TechDesk to submit IT support requests</p>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% for cat, msg in messages %}
<div class="alert alert-{{ cat }}">{{ msg }}</div>
{% endfor %}
{% endwith %}
<form method="POST">
<div class="row">
<div class="form-group">
<label>Full Name *</label>
<input type="text" name="full_name" required placeholder="Jane Smith"/>
</div>
<div class="form-group">
<label>Username *</label>
<input type="text" name="username" required placeholder="jsmith"/>
</div>
</div>
<div class="form-group">
<label>Work Email *</label>
<input type="email" name="email" required placeholder="jane.smith@company.com"/>
</div>
<div class="row">
<div class="form-group">
<label>Department</label>
<input type="text" name="department" placeholder="Finance"/>
</div>
<div class="form-group">
<label>Phone</label>
<input type="text" name="phone" placeholder="+1 555 000 0000"/>
</div>
</div>
<div class="row">
<div class="form-group">
<label>Password *</label>
<input type="password" name="password" required placeholder="Min. 8 characters"/>
</div>
<div class="form-group">
<label>Confirm Password *</label>
<input type="password" name="confirm_password" required placeholder="Repeat password"/>
</div>
</div>
<button type="submit" class="btn"><i class="bi bi-person-plus me-2"></i>Create Account</button>
</form>
<div class="links">Already have an account? <a href="{{ url_for('auth.login') }}">Sign in</a></div>
</div>
</body>
</html>