Move job applications to /cv/jobs route and add layout system
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m41s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m41s
- Add DefaultLayout and CVLayout with nested routing - Job applications is now a standalone page at /cv/jobs with a back link - Remove JobApplications embed from CV.vue Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,32 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { RouterView } from "vue-router";
|
import { RouterView } from "vue-router";
|
||||||
import Navbar from "@/components/Navbar.vue";
|
|
||||||
import Footer from "@/components/Footer.vue";
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="app-layout halftone">
|
<RouterView />
|
||||||
<Navbar class="no-print sticky top-0 z-50" />
|
|
||||||
<main class="app-content">
|
|
||||||
<RouterView v-slot="{ Component }">
|
|
||||||
<Transition name="slide" mode="out-in">
|
|
||||||
<component :is="Component" :key="$route.path" />
|
|
||||||
</Transition>
|
|
||||||
</RouterView>
|
|
||||||
</main>
|
|
||||||
<Footer class="no-print sticky bottom-0 z-50" />
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.app-layout {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-content {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
17
vue/src/layouts/CVLayout.vue
Normal file
17
vue/src/layouts/CVLayout.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<script setup>
|
||||||
|
import { RouterView } from "vue-router";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="cv-layout">
|
||||||
|
<RouterView />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cv-layout {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: white;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
32
vue/src/layouts/DefaultLayout.vue
Normal file
32
vue/src/layouts/DefaultLayout.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup>
|
||||||
|
import { RouterView } from "vue-router";
|
||||||
|
import Navbar from "@/components/Navbar.vue";
|
||||||
|
import Footer from "@/components/Footer.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="default-layout halftone">
|
||||||
|
<Navbar class="no-print sticky top-0 z-50" />
|
||||||
|
<main class="default-content">
|
||||||
|
<RouterView v-slot="{ Component }">
|
||||||
|
<Transition name="slide" mode="out-in">
|
||||||
|
<component :is="Component" :key="$route.path" />
|
||||||
|
</Transition>
|
||||||
|
</RouterView>
|
||||||
|
</main>
|
||||||
|
<Footer class="no-print sticky bottom-0 z-50" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.default-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
|
import DefaultLayout from "@/layouts/DefaultLayout.vue";
|
||||||
|
import CVLayout from "@/layouts/CVLayout.vue";
|
||||||
import Landing from "@/views/Landing.vue";
|
import Landing from "@/views/Landing.vue";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
@@ -6,63 +8,80 @@ const router = createRouter({
|
|||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
name: "landing",
|
component: DefaultLayout,
|
||||||
component: Landing,
|
children: [
|
||||||
},
|
{
|
||||||
{
|
path: "",
|
||||||
path: "/stp",
|
name: "landing",
|
||||||
name: "home",
|
component: Landing,
|
||||||
component: () => import("@/views/home/Home.vue"),
|
},
|
||||||
|
{
|
||||||
|
path: "stp",
|
||||||
|
name: "home",
|
||||||
|
component: () => import("@/views/home/Home.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "admin",
|
||||||
|
name: "admin",
|
||||||
|
component: () => import("@/views/admin/Admin.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "bookmarks",
|
||||||
|
name: "bookmarks",
|
||||||
|
component: () => import("@/views/Bookmarks.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "notes/:path(.*)*",
|
||||||
|
name: "notes",
|
||||||
|
component: () => import("@/views/Notes.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "shrines",
|
||||||
|
name: "shrine links",
|
||||||
|
component: () => import("@/views/Shrines.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "shrines/gto",
|
||||||
|
name: "gto shrine",
|
||||||
|
component: () => import("@/views/shrines/GTO.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "shrines/skipskipbenben",
|
||||||
|
name: "skipskipbenben shrine",
|
||||||
|
component: () => import("@/views/shrines/Skipskipbenben.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "shrines/evangelion",
|
||||||
|
name: "evangelion shrine",
|
||||||
|
component: () => import("@/views/shrines/Evangelion.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "shrines/demoman",
|
||||||
|
name: "demoman shrine",
|
||||||
|
component: () => import("@/views/shrines/Demoman.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ":pathMatch(.*)*",
|
||||||
|
name: "404",
|
||||||
|
component: () => import("@/views/404.vue"),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/cv",
|
path: "/cv",
|
||||||
name: "cv",
|
component: CVLayout,
|
||||||
component: () => import("../views/CV/CV.vue"),
|
children: [
|
||||||
},
|
{
|
||||||
{
|
path: "",
|
||||||
path: "/admin",
|
name: "cv",
|
||||||
name: "admin",
|
component: () => import("@/views/CV/CV.vue"),
|
||||||
component: () => import("../views/admin/Admin.vue"),
|
},
|
||||||
},
|
{
|
||||||
{
|
path: "jobs",
|
||||||
path: "/bookmarks",
|
name: "job-applications",
|
||||||
name: "bookmarks",
|
component: () => import("@/views/CV/JobApplications.vue"),
|
||||||
component: () => import("../views/Bookmarks.vue"),
|
},
|
||||||
},
|
],
|
||||||
{
|
|
||||||
path: "/notes/:path(.*)*",
|
|
||||||
name: "notes",
|
|
||||||
component: () => import("../views/Notes.vue"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/shrines",
|
|
||||||
name: "shrine links",
|
|
||||||
component: () => import("../views/Shrines.vue"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/shrines/gto",
|
|
||||||
name: "gto shrine",
|
|
||||||
component: () => import("../views/shrines/GTO.vue"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/shrines/skipskipbenben",
|
|
||||||
name: "skipskipbenben shrine",
|
|
||||||
component: () => import("../views/shrines/Skipskipbenben.vue"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/shrines/evangelion",
|
|
||||||
name: "evangelion shrine",
|
|
||||||
component: () => import("../views/shrines/Evangelion.vue"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/shrines/demoman",
|
|
||||||
name: "demoman shrine",
|
|
||||||
component: () => import("../views/shrines/Demoman.vue"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/:pathMatch(.*)*",
|
|
||||||
name: "404",
|
|
||||||
component: () => import("../views/404.vue"),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import CVGeneral from "./CVGeneral.vue";
|
|||||||
import CVBackend from "./CVBackend.vue";
|
import CVBackend from "./CVBackend.vue";
|
||||||
import CVFrontend from "./CVFrontend.vue";
|
import CVFrontend from "./CVFrontend.vue";
|
||||||
import CVTemp from "./CVTemp.vue";
|
import CVTemp from "./CVTemp.vue";
|
||||||
import JobApplications from "./JobApplications.vue";
|
|
||||||
|
|
||||||
const CVHospitality = defineAsyncComponent(() => import("./CVHospitality.vue"));
|
const CVHospitality = defineAsyncComponent(() => import("./CVHospitality.vue"));
|
||||||
|
|
||||||
@@ -39,7 +38,6 @@ function print() {
|
|||||||
<Transition name="cv-fade" mode="out-in">
|
<Transition name="cv-fade" mode="out-in">
|
||||||
<component :is="currentComponent" :key="selected" />
|
<component :is="currentComponent" :key="selected" />
|
||||||
</Transition>
|
</Transition>
|
||||||
<JobApplications />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter, RouterLink } from "vue-router";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
import { gql } from "@/graphql";
|
import { gql } from "@/graphql";
|
||||||
|
|
||||||
@@ -158,9 +158,12 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="no-print ja-root">
|
<div class="ja-root">
|
||||||
<div class="ja-header">
|
<div class="ja-header">
|
||||||
<h2 class="ja-heading">Job Applications</h2>
|
<div class="ja-header-left">
|
||||||
|
<RouterLink to="/cv" class="ja-back">← CV</RouterLink>
|
||||||
|
<h2 class="ja-heading">Job Applications</h2>
|
||||||
|
</div>
|
||||||
<button class="ja-btn" @click="exportCsv" :disabled="!applications.length">Export CSV</button>
|
<button class="ja-btn" @click="exportCsv" :disabled="!applications.length">Export CSV</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -259,6 +262,22 @@ onMounted(() => {
|
|||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ja-header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ja-back {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ja-back:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
.ja-heading {
|
.ja-heading {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|||||||
Reference in New Issue
Block a user