mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-24 15:20:52 -05:00
8b6e61873b
Display formats for dates and times now follow the system settings (Admin settings) by default. Users can override in their profile (User settings) or choose "Use system default" so their view matches the rest of the system. Backend: - User.date_format and User.time_format are nullable; null means use system. - Migration 120 makes these columns nullable (existing rows unchanged). - get_resolved_date_format_key() and get_resolved_time_format_key() in timezone utils return the effective key (user or system) for templates and API. - Context processor injects resolved_date_format_key and resolved_time_format_key so base.html and JS (window.userPrefs) always see the resolved format. - User settings form: "Use system default" option and save logic for null. - User.to_dict() includes resolved date_format, time_format, and timezone for API clients (e.g. mobile). Web: - base.html uses resolved keys for window.userPrefs (no hardcoded fallback). - Replaced display-only strftime() in templates with |user_date, |user_datetime, |user_time, and |format_date so all visible dates/times respect settings. Left <input type="date"> values and URL/API params as YYYY-MM-DD where required. Mobile: - ApiClient.getCurrentUser() and user prefs provider load resolved prefs from /api/v1/users/me. - date_format_utils maps API keys to intl patterns; formatDate, formatTime, formatDateTime, formatDateRange used for display. - Time entries screen (filter dialog), time entry form, time entry card, and home dashboard use user prefs for formatting; API requests still send ISO dates. Co-authored-by: Cursor <cursoragent@cursor.com>
93 lines
3.1 KiB
HTML
93 lines
3.1 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Quote Approved</title>
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
line-height: 1.6;
|
|
color: #333;
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
}
|
|
.container {
|
|
background-color: #ffffff;
|
|
border-radius: 8px;
|
|
padding: 30px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
.header {
|
|
border-bottom: 2px solid #10b981;
|
|
padding-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.header h1 {
|
|
color: #10b981;
|
|
margin: 0;
|
|
font-size: 24px;
|
|
}
|
|
.content {
|
|
margin-bottom: 20px;
|
|
}
|
|
.quote-details {
|
|
background-color: #f0fdf4;
|
|
border-left: 4px solid #10b981;
|
|
padding: 15px;
|
|
margin: 20px 0;
|
|
border-radius: 4px;
|
|
}
|
|
.quote-details p {
|
|
margin: 5px 0;
|
|
}
|
|
.button {
|
|
display: inline-block;
|
|
padding: 12px 24px;
|
|
background-color: #10b981;
|
|
color: #ffffff;
|
|
text-decoration: none;
|
|
border-radius: 4px;
|
|
margin: 20px 0;
|
|
}
|
|
.footer {
|
|
margin-top: 30px;
|
|
padding-top: 20px;
|
|
border-top: 1px solid #e0e0e0;
|
|
font-size: 12px;
|
|
color: #666;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>✓ {{ _('Quote Approved') }}</h1>
|
|
</div>
|
|
<div class="content">
|
|
<p>Hello {{ user.display_name or user.username }},</p>
|
|
<p><strong>Great news!</strong> Your quote has been approved and is ready to be sent.</p>
|
|
|
|
<div class="quote-details">
|
|
<p><strong>Quote Number:</strong> {{ quote.quote_number }}</p>
|
|
<p><strong>Title:</strong> {{ quote.title }}</p>
|
|
<p><strong>Client:</strong> {{ quote.client.name if quote.client else 'N/A' }}</p>
|
|
<p><strong>Total Amount:</strong> {{ quote.currency_code }} {{ "%.2f"|format(quote.total_amount) }}</p>
|
|
<p><strong>Approved By:</strong> {{ quote.approver.full_name or quote.approver.username if quote.approver else 'N/A' }}</p>
|
|
<p><strong>Approved At:</strong> {{ quote.approved_at|user_datetime if quote.approved_at else 'N/A' }}</p>
|
|
</div>
|
|
|
|
<p>You can now send this quote to the client.</p>
|
|
|
|
<a href="{{ url_for('quotes.view_quote', quote_id=quote.id, _external=True) }}" class="button">{{ _('View Quote') }}</a>
|
|
</div>
|
|
<div class="footer">
|
|
<p>TimeTracker - Time Tracking & Project Management</p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
|