jobs/src/App.vue

173 lines
3.3 KiB
Vue
Raw Normal View History

2025-03-30 11:52:59 +00:00
<script setup>
import SideNav from './components/SideNav.vue'
import { ref, provide, onMounted, computed } from 'vue'
2025-04-02 10:42:04 +00:00
import { useRoute } from 'vue-router'
2025-03-30 11:52:59 +00:00
2025-04-02 10:42:04 +00:00
// Current route
const route = useRoute()
2025-03-30 11:52:59 +00:00
// Theme state
const isDarkMode = ref(false)
// Initialize theme on mount
onMounted(() => {
// Check for saved preference in localStorage
const savedTheme = localStorage.getItem('theme')
if (savedTheme) {
isDarkMode.value = savedTheme === 'dark'
} else {
// Use system preference as fallback
isDarkMode.value = window.matchMedia('(prefers-color-scheme: dark)').matches
}
// Apply initial theme
applyTheme(isDarkMode.value)
})
// Apply theme to document
const applyTheme = (dark) => {
document.documentElement.classList.toggle('dark-mode', dark)
document.documentElement.classList.toggle('light-mode', !dark)
localStorage.setItem('theme', dark ? 'dark' : 'light')
}
// Handle theme toggle from SideNav
const handleThemeToggle = (dark) => {
isDarkMode.value = dark
applyTheme(dark)
}
// Provide theme state to components
provide('isDarkMode', isDarkMode)
provide('toggleTheme', handleThemeToggle)
2025-04-02 10:42:04 +00:00
// Computed active section from route
const activeSection = computed(() => route.name)
2025-03-30 11:52:59 +00:00
2025-04-02 10:42:04 +00:00
// Provide active section to components that might need it
provide('activeSection', activeSection)
2025-03-30 11:52:59 +00:00
</script>
<template>
<div class="app-container">
2025-04-02 10:42:04 +00:00
<SideNav />
2025-03-30 11:52:59 +00:00
<div class="content-wrapper">
2025-04-02 08:17:31 +00:00
<nav class="breadcrumb">
<ul>
<li v-if="activeSection === 'dashboard'" class="active">Home</li>
<li v-else class="active">
{{ activeSection === 'saved' ? 'Saved Jobs' : activeSection.charAt(0).toUpperCase() + activeSection.slice(1) }}
</li>
</ul>
</nav>
2025-03-30 11:52:59 +00:00
<main>
2025-04-02 10:42:04 +00:00
<!-- Router view will render the appropriate component based on the current route -->
<router-view></router-view>
2025-03-30 11:52:59 +00:00
</main>
</div>
</div>
</template>
<style scoped lang="scss">
.app-container {
display: flex;
min-height: 100vh;
}
.content-wrapper {
flex: 1;
margin-left: 240px;
transition: margin-left 0.3s ease;
display: flex;
flex-direction: column;
min-height: 100vh;
.side-nav.collapsed + & {
margin-left: 60px;
}
}
2025-04-02 08:17:31 +00:00
.breadcrumb {
2025-03-30 11:52:59 +00:00
padding: 1.5rem 2rem;
margin-bottom: 1rem;
2025-04-02 08:17:31 +00:00
border-bottom: 1px solid var(--card-border, #eee);
2025-03-30 11:52:59 +00:00
2025-04-02 08:17:31 +00:00
ul {
display: flex;
list-style: none;
padding: 0;
2025-03-30 11:52:59 +00:00
margin: 0;
2025-04-02 08:17:31 +00:00
flex-wrap: wrap;
}
li {
display: flex;
align-items: center;
font-size: 0.95rem;
&:not(:last-child)::after {
content: '/';
margin: 0 0.75rem;
color: var(--text-color-tertiary, #aaa);
}
a {
color: var(--primary-color, #3498db);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
&.active {
color: var(--text-color, #333);
font-weight: 500;
}
2025-03-30 11:52:59 +00:00
}
}
main {
flex: 1;
padding: 0 2rem;
section {
margin-bottom: 2rem;
h2 {
margin-bottom: 1.5rem;
font-size: 1.4rem;
color: var(--text-color);
}
}
.dashboard-section {
width: 100%;
}
}
2025-04-02 08:17:31 +00:00
2025-03-30 11:52:59 +00:00
@media (prefers-color-scheme: dark) {
main section h2 {
color: #eee;
}
}
@media (max-width: 768px) {
.content-wrapper {
margin-left: 60px;
}
2025-04-02 08:17:31 +00:00
.breadcrumb {
2025-03-30 11:52:59 +00:00
padding: 1rem;
}
main {
padding: 0 1rem;
}
}
</style>