Add subscription management system with website URL functionality

- Complete subscription tracking with monthly/annual billing cycles
- Dashboard integration with simplified card-based layout
- Website URL fields with clickable links for easy service access
- Comprehensive form validation and error handling
- Database schema with proper website_url column support
- Responsive design with mobile-friendly interface
- Export functionality for subscription data management
- Real-time dashboard summaries showing total costs and service counts

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kris
2025-09-18 09:29:34 +00:00
co-authored by Claude
parent 711826010f
commit 8a3631d5f5
4 changed files with 2414 additions and 552 deletions
+269 -82
View File
@@ -41,6 +41,14 @@
<span class="menu-icon">📋</span>
<span class="menu-text">Trade History</span>
</li>
<li class="menu-item" data-page="subscriptions">
<span class="menu-icon">📱</span>
<span class="menu-text">Subscriptions</span>
</li>
<li class="menu-item" data-page="add-subscription">
<span class="menu-icon"></span>
<span class="menu-text">Add Subscription</span>
</li>
<li class="menu-item menu-separator" data-page="cgt-settings">
<span class="menu-icon">🧮</span>
<span class="menu-text">CGT Settings</span>
@@ -94,95 +102,45 @@
<!-- Dashboard Page -->
<div id="dashboard-page" class="page">
<div class="dashboard-grid">
<div class="dashboard-card total-value">
<h3>Current Portfolio Value</h3>
<div class="metric-value" id="dashboard-current-value">€0.00</div>
<div class="metric-detail" id="dashboard-last-updated">Using cost basis</div>
</div>
<div class="dashboard-card total-gains">
<h3>Total Gains/Losses</h3>
<div class="metric-value" id="dashboard-total-gains">€0.00</div>
<div class="metric-change" id="dashboard-gains-percentage">0.0%</div>
</div>
<div class="dashboard-card monthly-investment">
<h3>Monthly Investment</h3>
<div class="metric-value" id="monthly-investment">€0.00</div>
<div class="metric-detail" id="monthly-trades">0 trades</div>
</div>
<div class="dashboard-card yearly-investment">
<h3>Yearly Investment</h3>
<div class="metric-value" id="yearly-investment">€0.00</div>
<div class="metric-detail" id="yearly-trades">0 trades</div>
</div>
<div class="dashboard-card total-shares">
<h3>Total Shares</h3>
<div class="metric-value" id="total-shares">0</div>
<div class="metric-detail" id="unique-etfs">0 ETFs</div>
</div>
<div class="dashboard-card cost-basis">
<h3>Total Investment</h3>
<div class="metric-value" id="dashboard-cost-basis">€0.00</div>
<div class="metric-detail" id="dashboard-avg-return">Avg return: 0.0%</div>
</div>
</div>
<!-- Total Holdings Card -->
<div class="total-holdings-section">
<div class="total-holdings-card">
<h3>Total Holdings</h3>
<div class="holdings-breakdown">
<div class="holdings-item">
<span class="holdings-label">Portfolio Value:</span>
<span class="holdings-value" id="total-holdings-portfolio">€0.00</span>
</div>
<div class="holdings-item">
<span class="holdings-label">Cash Savings:</span>
<span class="holdings-value" id="total-holdings-cash">€0.00</span>
</div>
<div class="holdings-divider"></div>
<div class="holdings-total">
<span class="holdings-label">Total Value:</span>
<span class="holdings-value total" id="total-holdings-combined">€0.00</span>
</div>
<div class="dashboard-summary">
<div class="summary-card portfolio-summary" onclick="app.navigateToPage('portfolio')">
<div class="summary-header">
<h3>Portfolio</h3>
</div>
<div class="summary-content">
<div class="primary-value" id="dashboard-current-value">€0.00</div>
<div class="secondary-value" id="dashboard-total-gains">€0.00</div>
</div>
</div>
</div>
<div class="cash-breakdown" id="cash-breakdown" style="display: none;">
<h3>Cash Savings Summary</h3>
<div class="cash-summary-overview">
<div class="cash-total-card">
<div class="cash-amount-line" id="dashboard-cash-eur-line">
<span class="currency-label">EUR:</span>
<span class="amount" id="dashboard-cash-eur">€0.00</span>
</div>
<div class="cash-amount-line" id="dashboard-cash-usd-line" style="display: none;">
<span class="currency-label">USD:</span>
<span class="amount" id="dashboard-cash-usd">$0.00</span>
</div>
<div class="summary-card cash-summary" onclick="app.navigateToPage('cash-accounts')">
<div class="summary-header">
<h3>Cash</h3>
</div>
<div class="cash-stats-card">
<span class="stat-detail" id="dashboard-account-count">0 accounts</span>
<span class="stat-detail" id="dashboard-avg-interest-display" style="display: none;">Avg: 0.0%</span>
<div class="summary-content">
<div class="primary-value" id="dashboard-cash-total">€0.00</div>
<div class="secondary-value" id="dashboard-account-count">0 accounts</div>
</div>
</div>
<div id="cash-accounts-breakdown" class="breakdown-list">
<div id="dashboard-cash-accounts-list">
<p class="no-data">No cash accounts yet</p>
<div class="summary-card subscriptions-summary" onclick="app.navigateToPage('subscriptions')">
<div class="summary-header">
<h3>Subscriptions</h3>
</div>
<div class="summary-content">
<div class="primary-value" id="dashboard-subscription-monthly">€0.00/mo</div>
<div class="secondary-value" id="dashboard-subscription-count">0 services</div>
</div>
</div>
</div>
<div class="etf-breakdown">
<h3>ETF Breakdown</h3>
<div id="etf-breakdown-list" class="breakdown-list">
<p class="no-data">No ETF positions yet</p>
<div class="summary-card total-summary">
<div class="summary-header">
<h3>Total Value</h3>
</div>
<div class="summary-content">
<div class="primary-value total" id="dashboard-total-combined">€0.00</div>
<div class="secondary-value" id="dashboard-performance">0.0%</div>
</div>
</div>
</div>
</div>
@@ -863,6 +821,235 @@ curl -H "Authorization: Bearer YOUR_TOKEN" \<br>
</div>
</div>
</div>
<!-- Subscriptions Page -->
<div id="subscriptions-page" class="page">
<div class="subscriptions-container">
<h2>Subscription Management</h2>
<div class="subscription-intro">
<p>Track and manage your recurring subscriptions. Monitor monthly and annual spending across different services.</p>
</div>
<div class="subscription-summary-cards">
<div class="subscription-summary-card total-monthly">
<h3>Monthly Total</h3>
<div class="subscription-amounts">
<div class="amount-line">
<span class="amount" id="monthly-total">€0.00</span>
</div>
</div>
</div>
<div class="subscription-summary-card total-annual">
<h3>Annual Total</h3>
<div class="subscription-amounts">
<div class="amount-line">
<span class="amount" id="annual-total">€0.00</span>
</div>
</div>
</div>
<div class="subscription-summary-card active-count">
<h3>Active Subscriptions</h3>
<div class="subscription-amounts">
<div class="amount-line">
<span class="amount" id="total-subscriptions">0</span>
</div>
</div>
</div>
</div>
<div class="subscriptions-controls">
<button onclick="app.showPage('add-subscription')" class="add-subscription-btn">Add New Subscription</button>
<button onclick="app.exportSubscriptions()" class="export-btn">Export Subscriptions</button>
</div>
<div class="subscriptions-list-section">
<h3>Your Subscriptions</h3>
<div id="subscriptions-list" class="subscriptions-list">
<p class="no-data">Loading subscriptions...</p>
</div>
</div>
</div>
<!-- Edit Subscription Modal -->
<div id="edit-subscription-modal" class="modal" style="display: none;">
<div class="modal-content">
<h3>Edit Subscription</h3>
<form id="edit-subscription-form">
<div class="form-row">
<div class="form-group">
<label for="edit-subscription-service-name">Service Name *</label>
<input type="text" id="edit-subscription-service-name" name="serviceName" required>
</div>
<div class="form-group">
<label for="edit-subscription-category">Category</label>
<select id="edit-subscription-category" name="category">
<option value="streaming">Streaming</option>
<option value="software">Software</option>
<option value="news">News & Media</option>
<option value="gaming">Gaming</option>
<option value="fitness">Fitness</option>
<option value="productivity">Productivity</option>
<option value="storage">Cloud Storage</option>
<option value="other">Other</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="edit-subscription-billing-cycle">Billing Cycle *</label>
<select id="edit-subscription-billing-cycle" name="billingCycle" required>
<option value="monthly">Monthly</option>
<option value="annual">Annual</option>
</select>
</div>
<div class="form-group">
<label for="edit-subscription-currency">Currency</label>
<select id="edit-subscription-currency" name="currency">
<option value="EUR">EUR (€)</option>
<option value="USD">USD ($)</option>
<option value="GBP">GBP (£)</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="edit-subscription-monthly-price">Monthly Price</label>
<input type="number" id="edit-subscription-monthly-price" name="monthlyPrice" step="0.01" min="0">
</div>
<div class="form-group">
<label for="edit-subscription-annual-price">Annual Price</label>
<input type="number" id="edit-subscription-annual-price" name="annualPrice" step="0.01" min="0">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="edit-subscription-start-date">Start Date *</label>
<input type="date" id="edit-subscription-start-date" name="startDate" required>
</div>
<div class="form-group">
<label for="edit-subscription-end-date">End Date (optional)</label>
<input type="date" id="edit-subscription-end-date" name="endDate">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="edit-subscription-free-trial">Free Trial Days</label>
<input type="number" id="edit-subscription-free-trial" name="freeTrialDays" min="0" value="0">
</div>
</div>
<div class="form-group">
<label for="edit-subscription-website-url">Website URL (optional)</label>
<input type="url" id="edit-subscription-website-url" name="websiteUrl" placeholder="https://example.com">
</div>
<div class="form-group">
<label for="edit-subscription-notes">Notes (optional)</label>
<textarea id="edit-subscription-notes" name="notes" rows="3"></textarea>
</div>
<div class="modal-actions">
<button type="submit" class="save-btn">Save Changes</button>
<button type="button" class="cancel-btn" onclick="app.closeEditSubscriptionModal()">Cancel</button>
</div>
</form>
</div>
</div>
</div>
<!-- Add Subscription Page -->
<div id="add-subscription-page" class="page">
<div class="add-subscription-container">
<h2>Add New Subscription</h2>
<form id="subscription-form" class="subscription-form">
<div class="form-row">
<div class="form-group">
<label for="subscription-service-name">Service Name *</label>
<input type="text" id="subscription-service-name" name="serviceName" required>
</div>
<div class="form-group">
<label for="subscription-category">Category</label>
<select id="subscription-category" name="category">
<option value="streaming">Streaming</option>
<option value="software">Software</option>
<option value="news">News & Media</option>
<option value="gaming">Gaming</option>
<option value="fitness">Fitness</option>
<option value="productivity">Productivity</option>
<option value="storage">Cloud Storage</option>
<option value="other">Other</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="subscription-billing-cycle">Billing Cycle *</label>
<select id="subscription-billing-cycle" name="billingCycle" required>
<option value="monthly">Monthly</option>
<option value="annual">Annual</option>
</select>
</div>
<div class="form-group">
<label for="subscription-currency">Currency</label>
<select id="subscription-currency" name="currency">
<option value="EUR">EUR (€)</option>
<option value="USD">USD ($)</option>
<option value="GBP">GBP (£)</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="subscription-monthly-price">Monthly Price</label>
<input type="number" id="subscription-monthly-price" name="monthlyPrice" step="0.01" min="0">
</div>
<div class="form-group">
<label for="subscription-annual-price">Annual Price</label>
<input type="number" id="subscription-annual-price" name="annualPrice" step="0.01" min="0">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="subscription-start-date">Start Date *</label>
<input type="date" id="subscription-start-date" name="startDate" required>
</div>
<div class="form-group">
<label for="subscription-end-date">End Date (optional)</label>
<input type="date" id="subscription-end-date" name="endDate">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="subscription-free-trial">Free Trial Days</label>
<input type="number" id="subscription-free-trial" name="freeTrialDays" min="0" value="0">
</div>
</div>
<div class="form-group">
<label for="subscription-website-url">Website URL (optional)</label>
<input type="url" id="subscription-website-url" name="websiteUrl" placeholder="https://example.com">
</div>
<div class="form-group">
<label for="subscription-notes">Notes (optional)</label>
<textarea id="subscription-notes" name="notes" rows="3" placeholder="Additional notes about this subscription..."></textarea>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">Add Subscription</button>
<button type="button" class="btn-secondary" onclick="app.showPage('subscriptions')">Cancel</button>
</div>
</form>
</div>
</div>
</main>
</div>
</div>