Skip to content

Commit 83a175f

Browse files
committed
commit 9f8c3e2d7b6a1e5f4c3e2d7b6a1e5f4c3e2d7b6a
1 parent 76255b8 commit 83a175f

16 files changed

+290
-31
lines changed

routes.py

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ def inject_globals():
1919
}
2020

2121
@main.route('/')
22+
def home():
23+
# Public landing page (keep product or marketing content)
24+
# If you prefer the root to redirect to dashboard for logged-in users,
25+
# we can change this to detect session and redirect.
26+
return render_template('product.html')
27+
28+
29+
@main.route('/dashboard')
2230
def dashboard():
2331
# require login to view dashboard
2432
user_id = session.get('user_id')
@@ -53,16 +61,23 @@ def signup():
5361
if request.method == 'POST':
5462
email = request.form.get('email')
5563
password = request.form.get('password')
64+
confirm = request.form.get('confirm_password')
5665
if not email or not password:
5766
flash('Email and password are required.', 'error')
58-
return render_template('signup.html')
67+
return render_template('signup.html', email=email)
68+
if confirm is None:
69+
# older forms may not include confirm field
70+
confirm = ''
71+
if password != confirm:
72+
flash('Passwords do not match. Please confirm your password.', 'error')
73+
return render_template('signup.html', email=email)
5974
success = create_user(email, password)
6075
if success:
6176
flash('Account created. Please log in.', 'success')
6277
return redirect(url_for('main.login'))
6378
else:
6479
flash('Email already exists.', 'error')
65-
return render_template('signup.html')
80+
return render_template('signup.html', email=email)
6681
return render_template('signup.html')
6782

6883

@@ -247,6 +262,77 @@ def complete_profile():
247262
return render_template('complete_profile.html')
248263

249264

265+
def _require_login():
266+
user_id = session.get('user_id')
267+
if not user_id:
268+
flash('Please log in to access this page.', 'error')
269+
return False
270+
return True
271+
272+
273+
@main.route('/dashboard/general')
274+
def dashboard_general():
275+
if not _require_login():
276+
return redirect(url_for('main.login', next=url_for('main.dashboard_general')))
277+
return render_template('dashboard_general.html')
278+
279+
280+
@main.route('/dashboard/account')
281+
def dashboard_account():
282+
if not _require_login():
283+
return redirect(url_for('main.login', next=url_for('main.dashboard_account')))
284+
return render_template('dashboard_account.html')
285+
286+
287+
@main.route('/dashboard/notifications')
288+
def dashboard_notifications():
289+
if not _require_login():
290+
return redirect(url_for('main.login', next=url_for('main.dashboard_notifications')))
291+
return render_template('dashboard_notifications.html')
292+
293+
294+
@main.route('/dashboard/api')
295+
def dashboard_api():
296+
if not _require_login():
297+
return redirect(url_for('main.login', next=url_for('main.dashboard_api')))
298+
return render_template('dashboard_api.html')
299+
300+
301+
@main.route('/dashboard/imports')
302+
def dashboard_imports():
303+
if not _require_login():
304+
return redirect(url_for('main.login', next=url_for('main.dashboard_imports')))
305+
return render_template('dashboard_imports.html')
306+
307+
308+
@main.route('/dashboard/group')
309+
def dashboard_group():
310+
if not _require_login():
311+
return redirect(url_for('main.login', next=url_for('main.dashboard_group')))
312+
return render_template('dashboard_group.html')
313+
314+
315+
@main.route('/dashboard/project')
316+
def dashboard_project():
317+
if not _require_login():
318+
return redirect(url_for('main.login', next=url_for('main.dashboard_project')))
319+
return render_template('dashboard_project.html')
320+
321+
322+
@main.route('/dashboard/environment')
323+
def dashboard_environment():
324+
if not _require_login():
325+
return redirect(url_for('main.login', next=url_for('main.dashboard_environment')))
326+
return render_template('dashboard_environment.html')
327+
328+
329+
@main.route('/dashboard/security')
330+
def dashboard_security():
331+
if not _require_login():
332+
return redirect(url_for('main.login', next=url_for('main.dashboard_security')))
333+
return render_template('dashboard_security.html')
334+
335+
250336
@main.route('/api/chat', methods=['POST'])
251337
def api_chat():
252338
data = request.get_json() or {}

static/css/style.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,19 @@ body{
219219
.muted{color:var(--muted)}
220220
.row{display:flex;gap:1rem}
221221

222+
/* Dashboard sidebar */
223+
.dashboard-sidebar{background:linear-gradient(180deg, rgba(255,255,255,0.01), rgba(255,255,255,0.005));border-radius:10px;padding:0.75rem;border:1px solid rgba(255,255,255,0.02)}
224+
.sidebar-list{display:flex;flex-direction:column;gap:0.25rem}
225+
.sidebar-link{display:block;padding:0.55rem 0.75rem;border-radius:8px;color:var(--muted);text-decoration:none;font-weight:600}
226+
.sidebar-link:hover,.sidebar-link:focus{color:var(--text);background:rgba(255,255,255,0.02);transform:translateX(4px)}
227+
.sidebar-link.active{background:linear-gradient(90deg,var(--accent),var(--accent-2));color:white;box-shadow:0 8px 20px rgba(124,92,255,0.06)}
228+
229+
@media (max-width:900px){
230+
.dashboard-sidebar{width:100%!important;flex:0 0 auto;margin-bottom:0.75rem;padding:0.5rem}
231+
.sidebar-list{flex-direction:row;flex-wrap:wrap;gap:0.5rem}
232+
.sidebar-link{padding:0.45rem 0.6rem;font-size:0.92rem}
233+
}
234+
222235
/* Responsive */
223236
@media (max-width:900px){
224237
.nav-list{display:none}

static/js/main.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,43 @@ document.addEventListener('DOMContentLoaded', function(){
139139
});
140140
});
141141
}
142+
143+
// Password visibility toggles
144+
document.querySelectorAll('.toggle-password').forEach(function(btn){
145+
btn.addEventListener('click', function(e){
146+
var targetId = btn.getAttribute('data-target');
147+
var input = document.getElementById(targetId);
148+
if(!input) return;
149+
if(input.type === 'password'){
150+
input.type = 'text';
151+
btn.textContent = '🙈';
152+
} else {
153+
input.type = 'password';
154+
btn.textContent = '👁️';
155+
}
156+
});
157+
});
158+
159+
// Signup confirm-password validation
160+
var signupForm = document.querySelector('form[action="/signup"]');
161+
if(signupForm){
162+
signupForm.addEventListener('submit', function(e){
163+
var pw = document.getElementById('password');
164+
var cpw = document.getElementById('confirm_password');
165+
// remove existing inline error
166+
var existing = signupForm.querySelector('.pw-error');
167+
if(existing) existing.remove();
168+
if(pw && cpw && pw.value !== cpw.value){
169+
e.preventDefault();
170+
var err = document.createElement('div');
171+
err.className = 'pw-error';
172+
err.style.color = 'var(--accent-2)';
173+
err.style.marginTop = '0.5rem';
174+
err.textContent = 'Passwords do not match';
175+
cpw.parentNode.appendChild(err);
176+
cpw.focus();
177+
return false;
178+
}
179+
});
180+
}
142181
});

templates/base.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@
6868
</div>
6969
</header>
7070

71-
<!-- Hero (show only on dashboard) -->
72-
{% if request.path == url_for('main.dashboard') %}
71+
<!-- Hero (show only on public home/product pages) -->
72+
{% if request.path == url_for('main.home') or request.path == url_for('main.product') %}
7373
<section class="hero">
7474
<div class="container full-width">
7575
<span class="kicker" data-i18n="kicker">Enterprise</span>

templates/dashboard.html

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,55 @@
11
{% extends 'base.html' %}
22
{% block content %}
33
<div class="container">
4-
<div class="card">
5-
<h1>Welcome back{% if session.get('user_email') %}, {{ session.get('user_email').split('@')[0]|capitalize }}{% endif %}</h1>
6-
<p class="muted">Quick actions and recent activity.</p>
4+
<div class="row" style="align-items:flex-start">
5+
<aside class="dashboard-sidebar" aria-label="Dashboard navigation" style="width:260px;flex:0 0 260px">
6+
<nav>
7+
<ul class="sidebar-list" style="list-style:none;padding:0;margin:0">
8+
<li><a href="{{ url_for('main.dashboard_general') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_general') %}active{% endif %}">General</a></li>
9+
<li><a href="{{ url_for('main.dashboard_account') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_account') %}active{% endif %}">Account setting</a></li>
10+
<li><a href="{{ url_for('main.dashboard_notifications') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_notifications') %}active{% endif %}">Notifications</a></li>
11+
<li><a href="{{ url_for('main.dashboard_api') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_api') %}active{% endif %}">API</a></li>
12+
<li><a href="{{ url_for('main.dashboard_imports') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_imports') %}active{% endif %}">Operation Import history</a></li>
13+
<li><a href="{{ url_for('main.dashboard_group') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_group') %}active{% endif %}">Group</a></li>
14+
<li><a href="{{ url_for('main.dashboard_project') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_project') %}active{% endif %}">Project</a></li>
15+
<li><a href="{{ url_for('main.dashboard_environment') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_environment') %}active{% endif %}">Environment</a></li>
16+
<li><a href="{{ url_for('main.dashboard_security') }}" class="sidebar-link {% if request.path == url_for('main.dashboard_security') %}active{% endif %}">Security</a></li>
17+
</ul>
18+
</nav>
19+
</aside>
720

8-
<div style="display:flex;gap:0.75rem;flex-wrap:wrap;margin-top:1rem">
9-
<a class="btn btn-primary" href="{{ url_for('main.upload_get') }}">Upload data</a>
10-
<a class="btn" href="{{ url_for('main.complete_profile') }}">Complete profile</a>
11-
<a class="btn" href="{{ url_for('main.logout') }}">Logout</a>
12-
</div>
21+
<main style="flex:1;min-width:0">
22+
<div class="card">
23+
<h1>Welcome back{% if session.get('user_email') %}, {{ session.get('user_email').split('@')[0]|capitalize }}{% endif %}</h1>
24+
<p class="muted">Quick actions and recent activity.</p>
1325

14-
<section style="margin-top:1.25rem">
15-
<h2>Upload a Document</h2>
16-
<form action="/upload" method="post" enctype="multipart/form-data">
17-
<input type="file" name="document">
18-
<button class="btn" type="submit">Process</button>
19-
</form>
20-
</section>
26+
<div style="display:flex;gap:0.75rem;flex-wrap:wrap;margin-top:1rem">
27+
<a class="btn btn-primary" href="{{ url_for('main.upload_get') }}">Upload data</a>
28+
<a class="btn" href="{{ url_for('main.complete_profile') }}">Complete profile</a>
29+
<a class="btn" href="{{ url_for('main.logout') }}">Logout</a>
30+
</div>
2131

22-
{% if result %}
23-
<div class="result" style="margin-top:1rem">
24-
<h3>AI Output:</h3>
25-
<p>{{ result }}</p>
26-
</div>
27-
{% endif %}
32+
<section style="margin-top:1.25rem">
33+
<h2>Upload a Document</h2>
34+
<form action="/upload" method="post" enctype="multipart/form-data">
35+
<input type="file" name="document">
36+
<button class="btn" type="submit">Process</button>
37+
</form>
38+
</section>
2839

29-
<section style="margin-top:1.5rem">
30-
<h3>Recent activity</h3>
31-
<div class="muted">No activity yet. Your uploads and analysis will appear here.</div>
32-
</section>
40+
{% if result %}
41+
<div class="result" style="margin-top:1rem">
42+
<h3>AI Output:</h3>
43+
<p>{{ result }}</p>
44+
</div>
45+
{% endif %}
46+
47+
<section style="margin-top:1.5rem">
48+
<h3>Recent activity</h3>
49+
<div class="muted">No activity yet. Your uploads and analysis will appear here.</div>
50+
</section>
51+
</div>
52+
</main>
3353
</div>
3454
</div>
3555
{% endblock %}

templates/dashboard_account.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% extends 'base.html' %}
2+
{% block content %}
3+
<div class="container">
4+
<div class="card">
5+
<h1>Account setting</h1>
6+
<p class="muted">Manage your account information and credentials.</p>
7+
<p>This is a placeholder page for Account settings.</p>
8+
</div>
9+
</div>
10+
{% endblock %}

templates/dashboard_api.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% extends 'base.html' %}
2+
{% block content %}
3+
<div class="container">
4+
<div class="card">
5+
<h1>API</h1>
6+
<p class="muted">API keys, docs, and integration settings.</p>
7+
<p>This is a placeholder page for API management.</p>
8+
</div>
9+
</div>
10+
{% endblock %}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% extends 'base.html' %}
2+
{% block content %}
3+
<div class="container">
4+
<div class="card">
5+
<h1>Environment</h1>
6+
<p class="muted">Deployment environments and configuration.</p>
7+
<p>This is a placeholder page for Environment settings.</p>
8+
</div>
9+
</div>
10+
{% endblock %}

templates/dashboard_general.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% extends 'base.html' %}
2+
{% block content %}
3+
<div class="container">
4+
<div class="card">
5+
<h1>General</h1>
6+
<p class="muted">Account overview and basic settings.</p>
7+
<p>This is a placeholder page for the General section of your dashboard.</p>
8+
</div>
9+
</div>
10+
{% endblock %}

templates/dashboard_group.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% extends 'base.html' %}
2+
{% block content %}
3+
<div class="container">
4+
<div class="card">
5+
<h1>Group</h1>
6+
<p class="muted">Team and group settings.</p>
7+
<p>This is a placeholder page for Group management.</p>
8+
</div>
9+
</div>
10+
{% endblock %}

0 commit comments

Comments
 (0)