Netdeploy2 Babyyyy

This commit is contained in:
Ben Mosley
2026-02-03 17:41:29 -06:00
commit c77674b86d
23 changed files with 659 additions and 0 deletions

31
templates/base.html Normal file
View File

@@ -0,0 +1,31 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>QuoteApp</title>
<style>
body { font-family: system-ui, -apple-system, sans-serif; margin: 20px; color:#111; }
nav a { margin-right: 10px; }
table { border-collapse: collapse; width: 100%; max-width: 900px; }
th, td { border: 1px solid #ddd; padding: 8px; }
th { background: #f5f5f5; text-align: left; }
input, select, button { padding: 6px; }
button { cursor: pointer; }
</style>
</head>
<body>
<nav>
<a href="{{ url_for('quotes.dashboard') }}">Dashboard</a> |
<a href="{{ url_for('clients.list_clients') }}">Clients</a> |
<a href="{{ url_for('quotes.dashboard') }}">Quotes</a> |
<a href="{{ url_for('invoices.list_invoices') }}">Invoices</a>
</nav>
<hr>
{% block content %}{% endblock %}
</body>
</html>

View File

@@ -0,0 +1,32 @@
{% extends "base.html" %}
{% block content %}
<h2>Clients</h2>
<p>
<a href="{{ url_for('clients.new_client') }}">+ New Client</a>
</p>
<table border="1" cellpadding="6">
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Kind</th>
</tr>
{% for c in clients %}
<tr>
<td>{{ c.id }}</td>
<td>{{ c.name }}</td>
<td>{{ c.email or "" }}</td>
<td>{{ c.kind }}</td>
</tr>
{% else %}
<tr>
<td colspan="4">No clients yet.</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -0,0 +1,23 @@
{% extends "base.html" %}
{% block content %}
<h2>New Client</h2>
<form method="POST">
<p>
<label>Name<br>
<input name="name" required style="width: 360px;">
</label>
</p>
<p>
<label>Email<br>
<input name="email" style="width: 360px;">
</label>
</p>
<button type="submit">Create Client</button>
<a href="{{ url_for('clients.list_clients') }}" style="margin-left: 10px;">Cancel</a>
</form>
{% endblock %}

View File

@@ -0,0 +1,34 @@
{% extends "base.html" %}
{% block content %}
<h2>Invoices</h2>
<table border="1" cellpadding="6">
<tr>
<th>ID</th>
<th>Client</th>
<th>Status</th>
<th>Total</th>
<th>Paid</th>
<th></th>
</tr>
{% for inv in invoices %}
<tr>
<td>{{ inv.id }}</td>
<td>{{ inv.client.name if inv.client else "" }}</td>
<td>{{ inv.status }}</td>
<td>${{ inv.total }}</td>
<td>${{ inv.amount_paid }}</td>
<td>
<a href="{{ url_for('invoices.view_invoice', invoice_id=inv.id) }}">View</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="6">No invoices yet.</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block content %}
<h2>Invoice #{{ inv.id }}</h2>
<p>
<strong>Client:</strong> {{ inv.client.name if inv.client else "" }}<br>
<strong>Status:</strong> {{ inv.status }}<br>
<strong>Total:</strong> ${{ inv.total }}<br>
<strong>Paid:</strong> ${{ inv.amount_paid }}<br>
</p>
<h3>Lines</h3>
<table border="1" cellpadding="6">
<tr>
<th>Description</th>
<th>Qty</th>
<th>Unit Price</th>
<th>Line Total</th>
</tr>
{% for l in inv.lines %}
<tr>
<td>{{ l.description }}</td>
<td>{{ l.qty }}</td>
<td>${{ l.unit_price }}</td>
<td>${{ (l.qty or 0) * (l.unit_price or 0) }}</td>
</tr>
{% else %}
<tr>
<td colspan="4">No lines found.</td>
</tr>
{% endfor %}
</table>
<p style="margin-top: 16px;">
<a href="{{ url_for('invoices.list_invoices') }}">Back to invoices</a>
</p>
{% endblock %}

View File

@@ -0,0 +1,58 @@
{% extends "base.html" %}
{% block content %}
<h2>Dashboard</h2>
<p>
<a href="{{ url_for('quotes.new_quote') }}">+ New Quote</a>
</p>
<h3>Draft / Sent Quotes</h3>
<table border="1" cellpadding="6">
<tr>
<th>ID</th>
<th>Title</th>
<th>Status</th>
<th>Total</th>
<th></th>
</tr>
{% for q in quotes if q.status in ['draft','sent'] %}
<tr>
<td>{{ q.id }}</td>
<td>{{ q.title }}</td>
<td>{{ q.status }}</td>
<td>${{ q.total }}</td>
<td><a href="{{ url_for('quotes.edit_quote', quote_id=q.id) }}">Open</a></td>
</tr>
{% else %}
<tr><td colspan="5">None</td></tr>
{% endfor %}
</table>
<hr>
<h3>Approved Quotes (Ready for Invoice)</h3>
<table border="1" cellpadding="6">
<tr>
<th>ID</th>
<th>Title</th>
<th>Total</th>
<th></th>
</tr>
{% for q in quotes if q.status == 'approved' %}
<tr>
<td>{{ q.id }}</td>
<td>{{ q.title }}</td>
<td>${{ q.total }}</td>
<td><a href="{{ url_for('quotes.edit_quote', quote_id=q.id) }}">View</a></td>
</tr>
{% else %}
<tr><td colspan="4">None</td></tr>
{% endfor %}
</table>
{% endblock %}

View File

@@ -0,0 +1,72 @@
{% extends "base.html" %}
{% block content %}
<h2>Edit Quote #{{ q.id }}</h2>
<form method="POST">
<p>
<label>
Title<br>
<input name="title" value="{{ q.title or '' }}" style="width: 420px;">
</label>
</p>
<p>
<strong>Category:</strong> {{ q.category }}<br>
<strong>Status:</strong> {{ q.status }}
</p>
<h3>Line Items</h3>
<table>
<tr>
<th>Description</th>
<th style="width:110px;">Qty</th>
<th style="width:140px;">Unit Price</th>
<th style="width:140px;">Line Total</th>
</tr>
{% for item in q.items %}
<tr>
<td>
<!-- THIS is what makes saving work -->
<input type="hidden" name="item_id" value="{{ item.id }}">
<input name="description" value="{{ item.description or '' }}" style="width: 100%;">
</td>
<td>
<input name="qty" type="number" step="0.01" value="{{ item.qty or 0 }}" style="width: 100px;">
</td>
<td>
<input name="unit_price" type="number" step="0.01" value="{{ item.unit_price or 0 }}" style="width: 120px;">
</td>
<td>
${{ ((item.qty or 0) * (item.unit_price or 0)) }}
</td>
</tr>
{% else %}
<tr>
<td colspan="4">No items yet. Click “Add Item”.</td>
</tr>
{% endfor %}
</table>
<p style="margin-top: 10px;">
<button type="submit">Save Quote</button>
<a href="{{ url_for('quotes.dashboard') }}" style="margin-left:10px;">Back</a>
</p>
</form>
<form method="POST" action="{{ url_for('quotes.add_item', quote_id=q.id) }}">
<button type="submit">Add Item</button>
</form>
<hr>
<h3>Total: ${{ q.total }}</h3>
<form method="POST" action="{{ url_for('invoices.create_from_quote', quote_id=q.id) }}">
<button type="submit">Create Invoice from Quote</button>
</form>
{% endblock %}

38
templates/quotes/new.html Normal file
View File

@@ -0,0 +1,38 @@
{% extends "base.html" %}
{% block content %}
<h2>New Quote</h2>
<form method="POST">
<p>
<label>Title<br>
<input name="title" required style="width: 360px;">
</label>
</p>
<p>
<label>Category<br>
<select name="category" required>
<option value="web_design">Web Design</option>
<option value="it_services">IT Services</option>
<option value="pc_repair">PC Repair</option>
</select>
</label>
</p>
<p>
<label>Client<br>
<select name="client_id" required>
{% for c in clients %}
<option value="{{ c.id }}">{{ c.name }}</option>
{% endfor %}
</select>
</label>
</p>
<button type="submit">Create Quote</button>
<a href="{{ url_for('quotes.dashboard') }}" style="margin-left: 10px;">Cancel</a>
</form>
{% endblock %}