feat: finalize UI/UX
This commit is contained in:
@@ -1,64 +1,64 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "portal_base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Profile{% endblock %}
|
||||
{% block title %}Profile & Account{% endblock %}
|
||||
{% block portal_title %}Profile & account{% endblock %}
|
||||
{% block portal_subtitle %}Build a complete professional profile so Tecvico can understand your work and communicate clearly.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="page-hero" aria-labelledby="profile-heading">
|
||||
<div class="container">
|
||||
<div class="page-hero-content">
|
||||
<h1 class="page-hero-title" id="profile-heading">Your Profile</h1>
|
||||
<p class="page-hero-subtitle">Keep your contact details up to date for project communication.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% block portal_content %}
|
||||
<div class="dashboard-form-layout">
|
||||
<section class="dashboard-panel dashboard-form-card" aria-labelledby="profile-details-title">
|
||||
<div class="dashboard-panel__header"><div><h2 id="profile-details-title">Professional profile</h2><p>Your profile information is visible only to you and the Tecvico team.</p></div></div>
|
||||
<form method="post" enctype="multipart/form-data" novalidate>
|
||||
{% csrf_token %}
|
||||
{% if form.non_field_errors %}<div class="form-errors">{{ form.non_field_errors }}</div>{% endif %}
|
||||
|
||||
<section class="section">
|
||||
<div class="container container--narrow">
|
||||
<div class="glass-card portal-card fade-in">
|
||||
<form method="post" novalidate>
|
||||
{% csrf_token %}
|
||||
<div class="profile-avatar-field form-group{% if form.avatar.errors %} has-error{% endif %}">
|
||||
<div class="profile-avatar-preview" aria-hidden="true">
|
||||
<img src="{% if user.client_profile.avatar %}{{ user.client_profile.avatar.url }}{% else %}{% static 'images/tecvico/default-avatar.png' %}{% endif %}" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_avatar">Profile picture</label>
|
||||
{{ form.avatar }}
|
||||
<p class="form-hint">JPG, PNG, or WebP. Maximum 5 MB. A square image works best.</p>
|
||||
{{ form.avatar.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-form-section">
|
||||
<h3>Identity</h3>
|
||||
<div class="form-grid form-grid--2">
|
||||
<div class="form-group">
|
||||
<label for="id_first_name">First name <span class="required-star">*</span></label>
|
||||
{{ form.first_name }}
|
||||
{{ form.first_name.errors }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="id_last_name">Last name <span class="required-star">*</span></label>
|
||||
{{ form.last_name }}
|
||||
{{ form.last_name.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="id_email">Email <span class="required-star">*</span></label>
|
||||
{{ form.email }}
|
||||
{{ form.email.errors }}
|
||||
<div class="form-group"><label for="id_first_name">First name <span class="required-star">*</span></label>{{ form.first_name }}{{ form.first_name.errors }}</div>
|
||||
<div class="form-group"><label for="id_last_name">Last name <span class="required-star">*</span></label>{{ form.last_name }}{{ form.last_name.errors }}</div>
|
||||
</div>
|
||||
<div class="form-group"><label for="id_email">Email address <span class="required-star">*</span></label>{{ form.email }}<p class="form-hint">Used for project updates and secure account communication.</p>{{ form.email.errors }}</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-form-section">
|
||||
<h3>Professional information</h3>
|
||||
<div class="form-grid form-grid--2">
|
||||
<div class="form-group">
|
||||
<label for="id_company">Company</label>
|
||||
{{ form.company }}
|
||||
{{ form.company.errors }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="id_phone">Phone</label>
|
||||
{{ form.phone }}
|
||||
{{ form.phone.errors }}
|
||||
</div>
|
||||
<div class="form-group"><label for="id_company">Organization</label>{{ form.company }}{{ form.company.errors }}</div>
|
||||
<div class="form-group"><label for="id_job_title">Role or job title</label>{{ form.job_title }}{{ form.job_title.errors }}</div>
|
||||
</div>
|
||||
<div class="form-group"><label for="id_bio">Professional bio</label>{{ form.bio }}<p class="form-hint">Up to 600 characters about your research, technical work, or project interests.</p>{{ form.bio.errors }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="id_timezone">Timezone <span class="required-star">*</span></label>
|
||||
{{ form.timezone }}
|
||||
{{ form.timezone.errors }}
|
||||
</div>
|
||||
<div class="profile-form-section">
|
||||
<h3>Contact details</h3>
|
||||
<div class="form-group"><label for="id_phone">Phone number</label>{{ form.phone }}{{ form.phone.errors }}</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-primary btn-submit">Save profile</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="dashboard-form-actions"><button type="submit" class="btn-primary">Save profile</button></div>
|
||||
</form>
|
||||
</section>
|
||||
<aside class="profile-context-card">
|
||||
<div class="profile-context-card__avatar"><img src="{% if user.client_profile.avatar %}{{ user.client_profile.avatar.url }}{% else %}{% static 'images/tecvico/default-avatar.png' %}{% endif %}" alt="" /></div>
|
||||
<h2>{{ user.get_full_name|default:user.username }}</h2>
|
||||
{% if user.client_profile.job_title or user.client_profile.company %}<p>{% if user.client_profile.job_title %}{{ user.client_profile.job_title }}{% endif %}{% if user.client_profile.job_title and user.client_profile.company %} · {% endif %}{% if user.client_profile.company %}{{ user.client_profile.company }}{% endif %}</p>{% else %}<p>{{ user.email }}</p>{% endif %}
|
||||
{% if user.client_profile.bio %}<div class="profile-context-card__expertise">{{ user.client_profile.bio|truncatechars:150 }}</div>{% endif %}
|
||||
<div class="profile-context-card__rule"></div>
|
||||
<span class="profile-context-card__label">Account status</span>
|
||||
<strong class="profile-status"><span></span> Active client account</strong>
|
||||
</aside>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -67,12 +67,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="id_timezone">Timezone <span class="required-star">*</span></label>
|
||||
{{ form.timezone }}
|
||||
{{ form.timezone.errors }}
|
||||
</div>
|
||||
|
||||
<div class="form-grid form-grid--2">
|
||||
<div class="form-group">
|
||||
<label for="id_password1">Password <span class="required-star">*</span></label>
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@
|
||||
<link rel="stylesheet" href="{% static 'css/main.css' %}" />
|
||||
{% block extra_css %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<body class="{% block body_class %}{% endblock %}">
|
||||
|
||||
{% include "partials/_navbar.html" %}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
{% include "partials/_footer.html" %}
|
||||
{% block footer %}{% include "partials/_footer.html" %}{% endblock %}
|
||||
|
||||
<script src="{% static 'js/main.js' %}"></script>
|
||||
{% block extra_js %}{% endblock %}
|
||||
|
||||
@@ -149,8 +149,8 @@
|
||||
<h3 class="modal-title" id="noEmailTitle">No reply address</h3>
|
||||
<p class="modal-body">You haven't provided an email address. Without it, we won't be able to respond to your message. Would you like to add one, or send without a reply address?</p>
|
||||
<div class="modal-actions">
|
||||
<button class="btn-ghost" id="modalAddEmail">Add Email</button>
|
||||
<button class="btn-primary" id="modalSendAnyway">Send Without Email</button>
|
||||
<button type="button" class="btn-ghost" id="modalAddEmail">Add Email</button>
|
||||
<button type="button" class="btn-primary" id="modalSendAnyway">Send Without Email</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -164,7 +164,7 @@
|
||||
</div>
|
||||
<h3 class="modal-title" id="successTitle">Message Sent!</h3>
|
||||
<p class="modal-body">Thank you for reaching out. We've received your message and will get back to you as soon as possible.</p>
|
||||
<button class="btn-primary" id="successClose">Done</button>
|
||||
<button type="button" class="btn-primary" id="successClose">Done</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
</div>
|
||||
<h3 class="modal-title" id="errorTitle">Something Went Wrong</h3>
|
||||
<p class="modal-body" id="errorModalMsg">Please check your answers and try again.</p>
|
||||
<button class="btn-ghost" id="errorClose">Try Again</button>
|
||||
<button type="button" class="btn-ghost" id="errorClose">Try Again</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
{% for entry in faq_entries %}
|
||||
<div class="faq-item glass-card fade-in">
|
||||
<button
|
||||
type="button"
|
||||
class="faq-question"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-{{ entry.pk }}"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% if site_contact.has_discord %}
|
||||
<a href="{{ site_contact.discord_url }}" class="{{ button_class|default:'btn-ghost btn-sm' }}" target="_blank" rel="noopener noreferrer">
|
||||
<a href="{{ site_contact.discord_url }}" class="{{ button_class|default:'btn-ghost btn--sm' }}" target="_blank" rel="noopener noreferrer">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057.1 18.08.114 18.1.133 18.11a19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/>
|
||||
</svg>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% include "partials/_brand_icon.html" with placement="navbar" %}
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggle" id="navbarToggle" aria-expanded="false" aria-controls="navbarMenu" aria-label="Toggle navigation">
|
||||
<button type="button" class="navbar-toggle" id="navbarToggle" aria-expanded="false" aria-controls="navbarMenu" aria-label="Toggle navigation">
|
||||
<span class="toggle-bar"></span>
|
||||
<span class="toggle-bar"></span>
|
||||
<span class="toggle-bar"></span>
|
||||
@@ -91,21 +91,31 @@
|
||||
</li>
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a href="{% url 'projects:dashboard' %}" class="nav-link {% if request.resolver_match.namespace == 'projects' %}active{% endif %}">
|
||||
My Projects
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="{% url 'accounts:profile' %}" class="nav-link {% if request.resolver_match.url_name == 'profile' %}active{% endif %}">
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<form method="post" action="{% url 'accounts:logout' %}" class="nav-logout-form">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="nav-link nav-link-button">Logout</button>
|
||||
</form>
|
||||
<li class="nav-item nav-item--account">
|
||||
<details class="navbar-account-menu">
|
||||
<summary class="navbar-account" aria-label="Open account menu">
|
||||
<span class="navbar-account__avatar" aria-hidden="true">
|
||||
<img src="{% if user.client_profile.avatar %}{{ user.client_profile.avatar.url }}{% else %}{% static 'images/tecvico/default-avatar.png' %}{% endif %}" alt="" />
|
||||
</span>
|
||||
<span class="navbar-account__status" aria-hidden="true"></span>
|
||||
</summary>
|
||||
<div class="navbar-account-dropdown">
|
||||
<div class="navbar-account-dropdown__identity">
|
||||
<img src="{% if user.client_profile.avatar %}{{ user.client_profile.avatar.url }}{% else %}{% static 'images/tecvico/default-avatar.png' %}{% endif %}" alt="" />
|
||||
<div><strong>{{ user.get_full_name|default:user.username }}</strong><span>{{ user.email }}</span></div>
|
||||
</div>
|
||||
<div class="navbar-account-dropdown__section">
|
||||
<a href="{% url 'projects:dashboard' %}"><span aria-hidden="true">⌂</span><span><strong>Workspace</strong><small>Projects and activity</small></span></a>
|
||||
<a href="{% url 'accounts:profile' %}"><span aria-hidden="true">○</span><span><strong>Your profile</strong><small>Identity and account details</small></span></a>
|
||||
<a href="{% url 'projects:create' %}"><span aria-hidden="true">+</span><span><strong>New project brief</strong><small>Start a scientific project</small></span></a>
|
||||
</div>
|
||||
<div class="navbar-account-dropdown__section navbar-account-dropdown__section--compact">
|
||||
<a href="{% url 'pages:faq' %}">Help center</a>
|
||||
<a href="{% url 'pages:contact' %}">Contact support</a>
|
||||
<form method="post" action="{% url 'accounts:logout' %}">{% csrf_token %}<button type="submit">Sign out</button></form>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
|
||||
@@ -507,6 +507,7 @@
|
||||
{% else %}
|
||||
<div class="faq-item glass-card fade-in">
|
||||
<button
|
||||
type="button"
|
||||
class="faq-question"
|
||||
aria-expanded="false"
|
||||
aria-controls="faq-answer-{{ section.pk }}-{{ item.pk }}"
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block body_class %}portal-body{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="dashboard-shell">
|
||||
<aside class="dashboard-sidebar" aria-label="Workspace navigation">
|
||||
<div class="dashboard-sidebar__profile">
|
||||
<div class="dashboard-avatar" aria-hidden="true">
|
||||
<img src="{% if user.client_profile.avatar %}{{ user.client_profile.avatar.url }}{% else %}{% static 'images/tecvico/default-avatar.png' %}{% endif %}" alt="" />
|
||||
</div>
|
||||
<div class="dashboard-sidebar__identity">
|
||||
<strong>{{ user.get_full_name|default:user.username }}</strong>
|
||||
<span>{{ user.email }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="dashboard-nav">
|
||||
<p class="dashboard-nav__label">Workspace</p>
|
||||
<a href="{% url 'projects:dashboard' %}" class="dashboard-nav__link{% if request.resolver_match.url_name == 'dashboard' or request.resolver_match.url_name == 'detail' %} is-active{% endif %}">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">⌂</span>
|
||||
<span>Overview</span>
|
||||
</a>
|
||||
<a href="{% url 'projects:dashboard' %}#project-briefs" class="dashboard-nav__link">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">▤</span>
|
||||
<span>Project briefs</span>
|
||||
</a>
|
||||
<a href="{% url 'projects:create' %}" class="dashboard-nav__link{% if request.resolver_match.url_name == 'create' %} is-active{% endif %}">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">+</span>
|
||||
<span>New project brief</span>
|
||||
</a>
|
||||
<a href="{% url 'accounts:profile' %}" class="dashboard-nav__link{% if request.resolver_match.url_name == 'profile' %} is-active{% endif %}">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">○</span>
|
||||
<span>Profile & account</span>
|
||||
</a>
|
||||
|
||||
<p class="dashboard-nav__label dashboard-nav__label--secondary">Resources</p>
|
||||
<a href="{% url 'products:overview' %}" class="dashboard-nav__link">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">◇</span>
|
||||
<span>Scientific products</span>
|
||||
</a>
|
||||
<a href="{% url 'pages:faq' %}" class="dashboard-nav__link">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">i</span>
|
||||
<span>Knowledge & FAQ</span>
|
||||
</a>
|
||||
<a href="{% url 'pages:contact' %}" class="dashboard-nav__link">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">?</span>
|
||||
<span>Help & support</span>
|
||||
</a>
|
||||
<a href="{% url 'pages:home' %}" class="dashboard-nav__link">
|
||||
<span class="dashboard-nav__icon" aria-hidden="true">↗</span>
|
||||
<span>Back to website</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="dashboard-sidebar__footer">
|
||||
<div class="dashboard-security-note">
|
||||
<span class="dashboard-security-note__mark" aria-hidden="true"></span>
|
||||
<span><strong>Secure workspace</strong>Your project data is private.</span>
|
||||
</div>
|
||||
<form method="post" action="{% url 'accounts:logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="dashboard-signout">Sign out</button>
|
||||
</form>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="dashboard-main">
|
||||
<header class="dashboard-header">
|
||||
<div>
|
||||
<p class="dashboard-eyebrow">Tecvico client workspace</p>
|
||||
<h1 id="dashboard-page-title">{% block portal_title %}Dashboard{% endblock %}</h1>
|
||||
<p>{% block portal_subtitle %}{% endblock %}</p>
|
||||
</div>
|
||||
<div class="dashboard-header__actions">{% block portal_actions %}{% endblock %}</div>
|
||||
</header>
|
||||
<div class="dashboard-content" aria-labelledby="dashboard-page-title">
|
||||
{% block portal_content %}{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}{% endblock %}
|
||||
@@ -1,33 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "portal_base.html" %}
|
||||
|
||||
{% block title %}{{ brief.title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="page-hero" aria-labelledby="brief-heading">
|
||||
<div class="container">
|
||||
<div class="page-hero-content page-hero-content--row">
|
||||
<div>
|
||||
{% if brief.category %}<div class="section-badge">{{ brief.get_category_display }}</div>{% endif %}
|
||||
<h1 class="page-hero-title" id="brief-heading">{{ brief.title }}</h1>
|
||||
<p class="page-hero-subtitle">
|
||||
<span class="status-pill status-pill--{{ brief.status }}">{{ brief.get_status_display }}</span>
|
||||
· Submitted {{ brief.submitted_at|date:"M j, Y" }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="portal-actions">
|
||||
<a href="{% url 'projects:dashboard' %}" class="btn-ghost">Back to list</a>
|
||||
{% if brief.is_editable_by_client %}
|
||||
<a href="{% url 'projects:edit' pk=brief.pk %}" class="btn-primary">Edit brief</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% block portal_title %}{{ brief.title }}{% endblock %}
|
||||
{% block portal_subtitle %}<span class="status-pill status-pill--{{ brief.status }}">{{ brief.get_status_display }}</span> <span class="dashboard-header__meta">Submitted {{ brief.submitted_at|date:"M j, Y" }}</span>{% endblock %}
|
||||
{% block portal_actions %}<a href="{% url 'projects:dashboard' %}" class="btn-ghost">Back to projects</a>{% if brief.is_editable_by_client %}<a href="{% url 'projects:edit' pk=brief.pk %}" class="btn-primary">Edit brief</a>{% endif %}{% endblock %}
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
{% block portal_content %}
|
||||
<div class="portal-detail-grid">
|
||||
<div class="glass-card portal-card fade-in">
|
||||
<div class="dashboard-panel portal-card">
|
||||
<h2 class="portal-section-title">Overview</h2>
|
||||
<dl class="portal-meta-list">
|
||||
{% if brief.budget_range %}<div><dt>Budget</dt><dd>{{ brief.get_budget_range_display }}</dd></div>{% endif %}
|
||||
@@ -56,19 +37,17 @@
|
||||
</div>
|
||||
|
||||
{% if brief.shows_quote_to_client %}
|
||||
<div class="glass-card portal-card fade-in">
|
||||
<div class="dashboard-panel portal-card">
|
||||
<h2 class="portal-section-title">Quote from Tecvico</h2>
|
||||
<p class="portal-body-text">{{ brief.quote_text|linebreaksbr }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if brief.has_website_notes %}
|
||||
<div class="glass-card portal-card fade-in">
|
||||
<div class="dashboard-panel portal-card">
|
||||
<h2 class="portal-section-title">Notes from Tecvico</h2>
|
||||
<p class="portal-body-text">{{ brief.website_notes|linebreaksbr }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "portal_base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}{{ form_title }}{% endblock %}
|
||||
@@ -7,19 +7,12 @@
|
||||
<link rel="stylesheet" href="{% static 'css/brief-wizard.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="page-hero" aria-labelledby="brief-form-heading">
|
||||
<div class="container">
|
||||
<div class="page-hero-content">
|
||||
<h1 class="page-hero-title" id="brief-form-heading">{{ form_title }}</h1>
|
||||
<p class="page-hero-subtitle">Complete each step to submit your project brief.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% block portal_title %}{{ form_title }}{% endblock %}
|
||||
{% block portal_subtitle %}Turn your scientific or technical challenge into a clear, review-ready scope.{% endblock %}
|
||||
|
||||
<section class="section">
|
||||
<div class="container container--narrow">
|
||||
<div class="glass-card portal-card fade-in">
|
||||
{% block portal_content %}
|
||||
<div class="dashboard-form-layout dashboard-form-layout--wizard">
|
||||
<section class="dashboard-panel dashboard-form-card">
|
||||
<form method="post" enctype="multipart/form-data" novalidate class="brief-wizard" data-brief-wizard data-initial-step="{{ initial_step }}">
|
||||
{% csrf_token %}
|
||||
|
||||
@@ -140,9 +133,18 @@
|
||||
<button type="submit" class="btn-primary btn-submit" data-wizard-submit hidden>{{ submit_label }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<aside class="brief-guidance-card">
|
||||
<span class="brief-guidance-card__eyebrow">Before you submit</span>
|
||||
<h2>A strong brief helps us respond precisely.</h2>
|
||||
<ul>
|
||||
<li><span>1</span><div><strong>Define the outcome</strong><p>Focus on the scientific or technical result you need.</p></div></li>
|
||||
<li><span>2</span><div><strong>Add useful context</strong><p>Include datasets, constraints, methods, or references.</p></div></li>
|
||||
<li><span>3</span><div><strong>Set expectations</strong><p>Share your preferred timeline and budget range.</p></div></li>
|
||||
</ul>
|
||||
<p class="brief-guidance-card__note">You can review every field in the final step before submission.</p>
|
||||
</aside>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
|
||||
@@ -1,70 +1,60 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "portal_base.html" %}
|
||||
|
||||
{% block title %}My Projects{% endblock %}
|
||||
{% block title %}Project Dashboard{% endblock %}
|
||||
{% block portal_title %}Welcome back{% if user.first_name %}, {{ user.first_name }}{% endif %}.{% endblock %}
|
||||
{% block portal_subtitle %}Manage your research and technology projects from one focused workspace.{% endblock %}
|
||||
{% block portal_actions %}<a href="{% url 'projects:create' %}" class="btn-primary">Start a new brief <span aria-hidden="true">→</span></a>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="page-hero" aria-labelledby="dashboard-heading">
|
||||
<div class="container">
|
||||
<div class="page-hero-content page-hero-content--row">
|
||||
<div>
|
||||
<div class="section-badge">Client Portal</div>
|
||||
<h1 class="page-hero-title" id="dashboard-heading">My Projects</h1>
|
||||
<p class="page-hero-subtitle">Track briefs you've submitted to the Tecvico team.</p>
|
||||
</div>
|
||||
<a href="{% url 'projects:create' %}" class="btn-primary">New project brief</a>
|
||||
</div>
|
||||
</div>
|
||||
{% block portal_content %}
|
||||
<section class="dashboard-metrics" aria-label="Workspace summary">
|
||||
<article class="metric-card">
|
||||
<div class="metric-card__top"><span class="metric-card__icon">P</span><span class="metric-card__trend">Portfolio</span></div>
|
||||
<strong>{{ page_obj.paginator.count|default:0 }}</strong>
|
||||
<span>Total project brief{{ page_obj.paginator.count|pluralize }}</span>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<div class="metric-card__top"><span class="metric-card__icon metric-card__icon--gold">R</span><span class="metric-card__trend">Structured</span></div>
|
||||
<strong>4 steps</strong>
|
||||
<span>From scientific scope to delivery</span>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<div class="metric-card__top"><span class="metric-card__icon metric-card__icon--green">✓</span><span class="metric-card__trend">Private</span></div>
|
||||
<strong>Secure</strong>
|
||||
<span>Visible only to you and Tecvico</span>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
{% if briefs %}
|
||||
<div class="portal-table-wrap glass-card fade-in">
|
||||
<table class="portal-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>Category</th>
|
||||
<th>Status</th>
|
||||
<th>Budget</th>
|
||||
<th>Submitted</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for brief in briefs %}
|
||||
<tr>
|
||||
<td>{{ brief.title }}</td>
|
||||
<td>{% if brief.category %}{{ brief.get_category_display }}{% else %}—{% endif %}</td>
|
||||
<td><span class="status-pill status-pill--{{ brief.status }}">{{ brief.get_status_display }}</span></td>
|
||||
<td>{% if brief.budget_range %}{{ brief.get_budget_range_display }}{% else %}—{% endif %}</td>
|
||||
<td>{{ brief.submitted_at|date:"M j, Y" }}</td>
|
||||
<td><a href="{% url 'projects:detail' pk=brief.pk %}" class="portal-link">View</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if page_obj.has_other_pages %}
|
||||
<div class="portal-pagination">
|
||||
{% if page_obj.has_previous %}
|
||||
<a href="?page={{ page_obj.previous_page_number }}" class="portal-link">Previous</a>
|
||||
{% endif %}
|
||||
<span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
|
||||
{% if page_obj.has_next %}
|
||||
<a href="?page={{ page_obj.next_page_number }}" class="portal-link">Next</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<div class="glass-card portal-card portal-empty fade-in">
|
||||
<h2>No project briefs yet</h2>
|
||||
<p class="portal-intro">Describe what you need and our team will review your request.</p>
|
||||
<a href="{% url 'projects:create' %}" class="btn-primary">Submit your first brief</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<section class="dashboard-panel" id="project-briefs" aria-labelledby="recent-projects-title">
|
||||
<div class="dashboard-panel__header">
|
||||
<div><h2 id="recent-projects-title">Your project briefs</h2><p>Track submissions, quotes, and delivery progress.</p></div>
|
||||
{% if briefs %}<span class="dashboard-panel__count">{{ page_obj.paginator.count }} total</span>{% endif %}
|
||||
</div>
|
||||
{% if briefs %}
|
||||
<div class="portal-table-wrap">
|
||||
<table class="portal-table">
|
||||
<thead><tr><th>Project</th><th>Field</th><th>Status</th><th>Budget</th><th>Submitted</th><th><span class="sr-only">Actions</span></th></tr></thead>
|
||||
<tbody>
|
||||
{% for brief in briefs %}
|
||||
<tr>
|
||||
<td><a class="project-title-link" href="{% url 'projects:detail' pk=brief.pk %}">{{ brief.title }}</a></td>
|
||||
<td>{% if brief.category %}{{ brief.get_category_display }}{% else %}<span class="table-muted">Not set</span>{% endif %}</td>
|
||||
<td><span class="status-pill status-pill--{{ brief.status }}">{{ brief.get_status_display }}</span></td>
|
||||
<td>{% if brief.budget_range %}{{ brief.get_budget_range_display }}{% else %}<span class="table-muted">Not set</span>{% endif %}</td>
|
||||
<td>{{ brief.submitted_at|date:"M j, Y" }}</td>
|
||||
<td><a href="{% url 'projects:detail' pk=brief.pk %}" class="table-action" aria-label="View {{ brief.title }}">View <span aria-hidden="true">→</span></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% if page_obj.has_other_pages %}<div class="portal-pagination">{% if page_obj.has_previous %}<a href="?page={{ page_obj.previous_page_number }}" class="portal-link">Previous</a>{% endif %}<span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>{% if page_obj.has_next %}<a href="?page={{ page_obj.next_page_number }}" class="portal-link">Next</a>{% endif %}</div>{% endif %}
|
||||
{% else %}
|
||||
<div class="portal-empty">
|
||||
<div class="portal-empty__symbol" aria-hidden="true">+</div>
|
||||
<h3>Create your first project brief</h3>
|
||||
<p>Define the scientific challenge, goals, timeline, and supporting materials. You can review everything before submitting.</p>
|
||||
<a href="{% url 'projects:create' %}" class="btn-primary">Create project brief</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user