Initial commit
This commit is contained in:
commit
983cee0320
322 changed files with 57174 additions and 0 deletions
199
app/templates/base.html
Normal file
199
app/templates/base.html
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="FINA - Track your expenses, manage your finances">
|
||||
<meta name="theme-color" content="#111a22">
|
||||
<title>{% block title %}FINA - Personal Finance Tracker{% endblock %}</title>
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='icons/favicon.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="{{ url_for('static', filename='icons/icon-96x96.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="{{ url_for('static', filename='icons/icon-192x192.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="512x512" href="{{ url_for('static', filename='icons/icon-512x512.png') }}">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='icons/apple-touch-icon.png') }}">
|
||||
|
||||
<!-- Preconnect for faster resource loading -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="preconnect" href="https://cdn.tailwindcss.com">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#2b8cee",
|
||||
"background-light": "#f6f7f8",
|
||||
"background-dark": "#111a22",
|
||||
"card-dark": "#1a2632",
|
||||
"card-light": "#ffffff",
|
||||
"sidebar-light": "#ffffff",
|
||||
"border-light": "#e2e8f0",
|
||||
"text-main": "#0f172a",
|
||||
"text-muted": "#64748b",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Inter", "sans-serif"]
|
||||
},
|
||||
borderRadius: {
|
||||
"DEFAULT": "0.25rem",
|
||||
"lg": "0.5rem",
|
||||
"xl": "0.75rem",
|
||||
"2xl": "1rem",
|
||||
"full": "9999px"
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* Dark theme scrollbar */
|
||||
.dark ::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
.dark ::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
.dark ::-webkit-scrollbar-thumb {
|
||||
background: #324d67;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.dark ::-webkit-scrollbar-thumb:hover {
|
||||
background: #4b6a88;
|
||||
}
|
||||
|
||||
/* Light theme scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #cbd5e1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbarlight dark:bg-background-dark text-text-main dark:text-white font-display overflow-hidden transition-colors duration-200
|
||||
background: #94a3b8;
|
||||
}
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
|
||||
}
|
||||
|
||||
/* Fix icon picker text overflow */
|
||||
#icon-grid .material-symbols-outlined {
|
||||
font-size: 24px !important;
|
||||
max-width: 32px !important;
|
||||
max-height: 32px !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: clip !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.glass {
|
||||
background: rgba(26, 38, 50, 0.7);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(35, 54, 72, 0.5);
|
||||
}
|
||||
|
||||
/* Optimize rendering */
|
||||
* {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% block extra_css %}{% endblock %}
|
||||
|
||||
<!-- Prevent theme flashing by applying theme before page render -->
|
||||
<script>
|
||||
(function() {
|
||||
const theme = localStorage.getItem('theme') || 'dark';
|
||||
if (theme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
// Sync user language preference from database to localStorage
|
||||
const dbLanguage = '{{ current_user.language }}';
|
||||
const storedLanguage = localStorage.getItem('language');
|
||||
|
||||
// Always use database language as source of truth
|
||||
if (dbLanguage && dbLanguage !== storedLanguage) {
|
||||
localStorage.setItem('language', dbLanguage);
|
||||
}
|
||||
{% endif %}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark text-text-main dark:text-white font-display overflow-hidden">
|
||||
{% block body %}{% endblock %}
|
||||
|
||||
<!-- Global Search Modal -->
|
||||
<div id="global-search-modal" class="hidden fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-start justify-center pt-20 opacity-0 transition-opacity duration-200">
|
||||
<div class="w-full max-w-2xl mx-4 bg-card-light dark:bg-card-dark rounded-2xl shadow-2xl overflow-hidden">
|
||||
<!-- Search Input -->
|
||||
<div class="p-4 border-b border-border-light dark:border-[#233648]">
|
||||
<div class="relative">
|
||||
<span class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-text-muted dark:text-[#92adc9]">search</span>
|
||||
<input
|
||||
type="text"
|
||||
id="global-search-input"
|
||||
placeholder="Search everything..."
|
||||
data-translate-placeholder="search.inputPlaceholder"
|
||||
class="w-full bg-slate-50 dark:bg-[#111a22] border border-border-light dark:border-[#233648] rounded-lg pl-10 pr-10 py-3 text-text-main dark:text-white focus:border-primary focus:ring-1 focus:ring-primary transition-all"
|
||||
/>
|
||||
<button id="global-search-close" class="absolute right-3 top-1/2 -translate-y-1/2 text-text-muted dark:text-[#92adc9] hover:text-text-main dark:hover:text-white transition-colors">
|
||||
<span class="material-symbols-outlined">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 text-xs text-text-muted dark:text-[#92adc9] flex items-center gap-4">
|
||||
<span data-translate="search.pressEnter">Press Enter to search</span>
|
||||
<span>•</span>
|
||||
<span data-translate="search.pressEsc">ESC to close</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search Results -->
|
||||
<div id="global-search-results" class="max-h-[60vh] overflow-y-auto">
|
||||
<div class="p-8 text-center">
|
||||
<span class="material-symbols-outlined text-5xl text-text-muted dark:text-[#92adc9] opacity-50 mb-3">search</span>
|
||||
<p class="text-text-muted dark:text-[#92adc9] text-sm" data-translate="search.placeholder">Search for transactions, documents, categories, or features</p>
|
||||
<p class="text-text-muted dark:text-[#92adc9] text-xs mt-2" data-translate="search.hint">Press Ctrl+K to open search</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast Notification Container -->
|
||||
<div id="toast-container" class="fixed top-4 right-4 z-50 space-y-2"></div>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/i18n.js') }}?v=2.0.3"></script>
|
||||
<script src="{{ url_for('static', filename='js/app.js') }}?v=2.0.3"></script>
|
||||
<script src="{{ url_for('static', filename='js/search.js') }}?v=2.0.3"></script>
|
||||
<script src="{{ url_for('static', filename='js/budget.js') }}?v=2.0.3"></script>
|
||||
<script src="{{ url_for('static', filename='js/notifications.js') }}?v=2.0.3"></script>
|
||||
<script src="{{ url_for('static', filename='js/pwa.js') }}?v=2.0.3"></script>
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue