update
This commit is contained in:
46
templates/base.html
Normal file
46
templates/base.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}Arbit{% endblock %}</title>
|
||||
<style>
|
||||
:root { color-scheme: light; --bg: #f6f2ea; --panel: #fffaf2; --ink: #1f2937; --muted: #6b7280; --accent: #1f6f78; --border: #d6cbbd; }
|
||||
body { margin: 0; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: linear-gradient(180deg, #f8f3ea 0%, #f2ece1 100%); color: var(--ink); }
|
||||
header, main { max-width: 1200px; margin: 0 auto; padding: 1.25rem; }
|
||||
.shell { display: grid; gap: 1rem; }
|
||||
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 16px; padding: 1rem; box-shadow: 0 10px 30px rgba(31, 41, 55, 0.05); }
|
||||
.grid { display: grid; gap: 1rem; }
|
||||
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||
input, select, textarea, button { font: inherit; padding: 0.75rem 0.85rem; border-radius: 10px; border: 1px solid var(--border); width: 100%; box-sizing: border-box; }
|
||||
button { background: var(--accent); color: white; border: none; cursor: pointer; }
|
||||
a { color: var(--accent); text-decoration: none; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th, td { text-align: left; border-bottom: 1px solid var(--border); padding: 0.75rem 0.5rem; vertical-align: top; }
|
||||
.muted { color: var(--muted); }
|
||||
.row { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center; }
|
||||
.spaced { display: flex; justify-content: space-between; gap: 1rem; align-items: center; }
|
||||
@media (max-width: 820px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="spaced">
|
||||
<div>
|
||||
<strong>Arbit</strong>
|
||||
<div class="muted">Thrift inventory and resale tracking</div>
|
||||
</div>
|
||||
<nav class="row">
|
||||
{% if user.is_authenticated %}
|
||||
<span class="muted">Signed in as {{ user.username }}</span>
|
||||
<a href="{% url 'logout' %}">Log out</a>
|
||||
{% else %}
|
||||
<a href="{% url 'login' %}">Log in</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
11
templates/inventory/add_hub.html
Normal file
11
templates/inventory/add_hub.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Add | Arbit{% endblock %}
|
||||
{% block content %}
|
||||
<div class="card" style="max-width:720px; margin:2rem auto;">
|
||||
<h1>Add</h1>
|
||||
<div class="grid">
|
||||
<a href="{% url 'item-create' %}" class="card" style="display:block; padding:1rem; text-align:center;">New item</a>
|
||||
<a href="{% url 'template-create' %}" class="card" style="display:block; padding:1rem; text-align:center;">New template</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
62
templates/inventory/dashboard.html
Normal file
62
templates/inventory/dashboard.html
Normal file
@@ -0,0 +1,62 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Dashboard | Arbit{% endblock %}
|
||||
{% block content %}
|
||||
<section class="grid grid-3">
|
||||
<div class="card"><div class="muted">Items</div><h2>{{ stats.item_count }}</h2></div>
|
||||
<div class="card"><div class="muted">Sold</div><h2>{{ stats.sold_count }}</h2></div>
|
||||
<div class="card"><div class="muted">Inventory cost</div><h2>${{ stats.inventory_value }}</h2></div>
|
||||
</section>
|
||||
|
||||
<section style="margin-top: 1rem; display:flex; justify-content:space-between; align-items:center; gap:1rem;">
|
||||
<div style="flex:1">
|
||||
<h2>Current items</h2>
|
||||
<div class="muted">Focus on inventory, suggested resale pricing, and quick actions.</div>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{% url 'item-create' %}" style="background:var(--accent); color:white; padding:0.6rem 1rem; border-radius:10px;">Add item</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card" style="margin-top: 1rem;">
|
||||
<h3>Search inventory</h3>
|
||||
<form method="get" class="grid grid-3">
|
||||
{{ item_filter.query.label_tag }}{{ item_filter.query }}
|
||||
{{ item_filter.status.label_tag }}{{ item_filter.status }}
|
||||
{{ item_filter.category.label_tag }}{{ item_filter.category }}
|
||||
{{ item_filter.created_by.label_tag }}{{ item_filter.created_by }}
|
||||
{{ item_filter.min_purchase_price.label_tag }}{{ item_filter.min_purchase_price }}
|
||||
{{ item_filter.max_purchase_price.label_tag }}{{ item_filter.max_purchase_price }}
|
||||
{{ item_filter.min_profit.label_tag }}{{ item_filter.min_profit }}
|
||||
<div style="grid-column: 1 / -1;"><button type="submit">Filter</button></div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="card" style="margin-top: 1rem; overflow-x: auto;">
|
||||
<h3>Latest items</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Title</th><th>Category</th><th>Status</th><th>Cost</th><th>Creator</th><th>Profit</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td><a href="{{ item.get_absolute_url }}">{{ item.title }}</a></td>
|
||||
<td>{{ item.category }}</td>
|
||||
<td>{{ item.get_status_display }}</td>
|
||||
<td>${{ item.purchase_price }}</td>
|
||||
<td>{{ item.created_by.username }}</td>
|
||||
<td>{% if item.profit is not None %}${{ item.profit }}{% else %}<span class="muted">Pending sale</span>{% endif %}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="6" class="muted">No items yet.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section class="grid grid-3" style="margin-top: 1rem;">
|
||||
<div class="card"><div class="muted">Inventory cost</div><h2>${{ stats.inventory_value }}</h2></div>
|
||||
<div class="card"><div class="muted">Profit total</div><h2>${{ stats.profit_total }}</h2></div>
|
||||
<div class="card"><div class="muted">Sold count</div><h2>{{ stats.sold_count }}</h2></div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
74
templates/inventory/item_detail.html
Normal file
74
templates/inventory/item_detail.html
Normal file
@@ -0,0 +1,74 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ object.title }} | Arbit{% endblock %}
|
||||
{% block content %}
|
||||
<section class="grid grid-2">
|
||||
<div class="card">
|
||||
<div class="spaced">
|
||||
<div>
|
||||
<h1>{{ object.title }}</h1>
|
||||
<div class="muted">Added by {{ object.created_by.username }} on {{ object.created_at }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<a href="{% url 'item-edit' object.pk %}">Edit</a>
|
||||
<a href="{% url 'item-mark-sold' object.pk %}">Mark sold</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dl class="grid grid-2">
|
||||
<div><dt class="muted">Category</dt><dd>{{ object.category }}</dd></div>
|
||||
<div><dt class="muted">Status</dt><dd>{{ object.get_status_display }}</dd></div>
|
||||
<div><dt class="muted">Purchase price</dt><dd>${{ object.purchase_price }}</dd></div>
|
||||
<div><dt class="muted">Estimated resale</dt><dd>{% if object.estimated_resale_price %}${{ object.estimated_resale_price }}{% else %}<span class="muted">Not set</span>{% endif %}</dd></div>
|
||||
<div><dt class="muted">Sold price</dt><dd>{% if object.sold_price %}${{ object.sold_price }}{% else %}<span class="muted">Not sold</span>{% endif %}</dd></div>
|
||||
<div><dt class="muted">Profit</dt><dd>{% if object.profit is not None %}${{ object.profit }}{% else %}<span class="muted">Pending sale</span>{% endif %}</dd></div>
|
||||
</dl>
|
||||
|
||||
<p>{{ object.notes|linebreaksbr }}</p>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<h2>Sold details</h2>
|
||||
<div class="muted">Suggested price: ${{ pricing_suggestion.price }} from {{ pricing_suggestion.source }}</div>
|
||||
<p class="muted">{{ pricing_suggestion.notes }}</p>
|
||||
<form method="post" action="{% url 'item-mark-sold' object.pk %}" class="grid">
|
||||
{% csrf_token %}
|
||||
{{ sold_form.as_p }}
|
||||
<button type="submit">Save sold details</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Add note</h2>
|
||||
<form method="post" action="{% url 'item-note-create' object.pk %}" class="grid">
|
||||
{% csrf_token %}
|
||||
{{ note_form.as_p }}
|
||||
<button type="submit">Save note</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="grid grid-2" style="margin-top: 1rem;">
|
||||
<div class="card">
|
||||
<h2>Price history</h2>
|
||||
<ul>
|
||||
{% for estimate in price_estimates %}
|
||||
<li>{{ estimate.source }}: ${{ estimate.estimated_price }} on {{ estimate.retrieved_at }}</li>
|
||||
{% empty %}
|
||||
<li class="muted">No price estimates yet.</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>Notes</h2>
|
||||
<ul>
|
||||
{% for note in notes %}
|
||||
<li><strong>{{ note.created_by.username }}</strong> - {{ note.body }} <span class="muted">({{ note.created_at }})</span></li>
|
||||
{% empty %}
|
||||
<li class="muted">No notes yet.</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
49
templates/inventory/item_form.html
Normal file
49
templates/inventory/item_form.html
Normal file
@@ -0,0 +1,49 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h1>{% if object %}Edit item{% else %}New item{% endif %}</h1>
|
||||
<form method="post" class="grid">
|
||||
{% csrf_token %}
|
||||
<div>
|
||||
{{ form.template.label_tag }}
|
||||
{{ form.template }}
|
||||
</div>
|
||||
<div>
|
||||
{{ form.title.label_tag }}
|
||||
{{ form.title }}
|
||||
</div>
|
||||
<div class="grid grid-3">
|
||||
<div>{{ form.brand.label_tag }}{{ form.brand }}</div>
|
||||
<div>{{ form.category.label_tag }}{{ form.category }}</div>
|
||||
<div>{{ form.condition.label_tag }}{{ form.condition }}</div>
|
||||
</div>
|
||||
<div class="grid grid-3">
|
||||
<div>{{ form.size.label_tag }}{{ form.size }}</div>
|
||||
<div>{{ form.color.label_tag }}{{ form.color }}</div>
|
||||
<div>{{ form.purchase_price.label_tag }}{{ form.purchase_price }}</div>
|
||||
</div>
|
||||
<div>{{ form.estimated_resale_price.label_tag }}{{ form.estimated_resale_price }}</div>
|
||||
|
||||
{% if template_obj and template_obj.field_definitions %}
|
||||
<fieldset class="card">
|
||||
<legend>Template properties ({{ template_obj.name }})</legend>
|
||||
{% for fd in template_obj.field_definitions %}
|
||||
<div>
|
||||
<label for="id_prop_{{ fd.name }}">{{ fd.label|default:fd.name }}</label>
|
||||
{% if fd.type == 'boolean' %}
|
||||
<input type="checkbox" name="prop_{{ fd.name }}" id="id_prop_{{ fd.name }}" {% if fd.default %}checked{% endif %} />
|
||||
{% elif fd.type == 'number' %}
|
||||
<input type="number" step="0.01" name="prop_{{ fd.name }}" id="id_prop_{{ fd.name }}" value="{{ fd.default|default:'' }}" />
|
||||
{% else %}
|
||||
<input type="text" name="prop_{{ fd.name }}" id="id_prop_{{ fd.name }}" value="{{ fd.default|default:'' }}" />
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
|
||||
<div>{{ form.notes.label_tag }}{{ form.notes }}</div>
|
||||
<button type="submit">{% if object %}Update item{% else %}Create item{% endif %}</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
11
templates/inventory/item_sold_form.html
Normal file
11
templates/inventory/item_sold_form.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h1>Sold details</h1>
|
||||
<form method="post" class="grid">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
11
templates/inventory/note_form.html
Normal file
11
templates/inventory/note_form.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h1>New note</h1>
|
||||
<form method="post" class="grid">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">Save note</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
11
templates/inventory/template_form.html
Normal file
11
templates/inventory/template_form.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
<h1>{% if object %}Edit template{% else %}New template{% endif %}</h1>
|
||||
<form method="post" class="grid">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">{% if object %}Update template{% else %}Save template{% endif %}</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
12
templates/registration/login.html
Normal file
12
templates/registration/login.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Log in | Arbit{% endblock %}
|
||||
{% block content %}
|
||||
<div class="card" style="max-width: 420px; margin: 8vh auto;">
|
||||
<h1>Log in</h1>
|
||||
<form method="post" class="grid">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">Log in</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user