From 3b14c3453cf61afab1100cbcd4c7865b7e1645bc Mon Sep 17 00:00:00 2001
From: Adam French
Date: Wed, 13 May 2026 09:45:50 +0100
Subject: [PATCH] Include grades
---
vue/src/router/index.js | 183 +++++++++++++++++----------------
vue/src/views/CV/CVAnalyst.vue | 29 ++++++
vue/src/views/CV/cv-shared.css | 22 ++++
3 files changed, 146 insertions(+), 88 deletions(-)
diff --git a/vue/src/router/index.js b/vue/src/router/index.js
index e6097dd..7d38854 100644
--- a/vue/src/router/index.js
+++ b/vue/src/router/index.js
@@ -7,103 +7,110 @@ import { useHomeDataStore } from "@/stores/homeData";
import { useAuthStore } from "@/stores/auth";
const router = createRouter({
- history: createWebHistory(import.meta.env.BASE_URL),
- routes: [
- {
- path: "/",
- component: DefaultLayout,
- children: [
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
{
- path: "",
- name: "landing",
- component: Landing,
+ path: "/",
+ component: DefaultLayout,
+ children: [
+ {
+ path: "",
+ name: "landing",
+ component: Landing,
+ },
+ {
+ path: "stp",
+ name: "home",
+ component: () => import("@/views/home/Home.vue"),
+ },
+ {
+ path: "admin/login",
+ name: "admin-login",
+ component: () => import("@/views/admin/Login.vue"),
+ },
+ {
+ path: "admin",
+ name: "admin",
+ component: () => import("@/views/admin/Admin.vue"),
+ meta: { requiresAdmin: true },
+ },
+ {
+ path: "shrines",
+ name: "shrine links",
+ component: () => import("@/views/home/shrines/Shrines.vue"),
+ },
+ {
+ path: "shrines/gto",
+ name: "gto shrine",
+ component: () => import("@/views/home/shrines/GTO.vue"),
+ },
+ {
+ path: "shrines/skipskipbenben",
+ name: "skipskipbenben shrine",
+ component: () =>
+ import("@/views/home/shrines/Skipskipbenben.vue"),
+ },
+ {
+ path: "shrines/evangelion",
+ name: "evangelion shrine",
+ component: () =>
+ import("@/views/home/shrines/Evangelion.vue"),
+ },
+ {
+ path: "shrines/demoman",
+ name: "demoman shrine",
+ component: () => import("@/views/home/shrines/Demoman.vue"),
+ },
+ {
+ path: ":pathMatch(.*)*",
+ name: "404",
+ component: () => import("@/views/404/404.vue"),
+ },
+ ],
},
{
- path: "stp",
- name: "home",
- component: () => import("@/views/home/Home.vue"),
+ path: "/stp2",
+ name: "home2",
+ component: () => import("@/views/home2/Home2.vue"),
},
{
- path: "admin/login",
- name: "admin-login",
- component: () => import("@/views/admin/Login.vue"),
+ path: "/cv",
+ component: CVLayout,
+ children: [
+ {
+ path: "",
+ name: "cv",
+ component: () => import("@/views/CV/CV.vue"),
+ },
+ {
+ path: "jobs",
+ name: "job-applications",
+ component: () => import("@/views/CV/JobApplications.vue"),
+ meta: { requiresAdmin: true },
+ },
+ ],
},
- {
- path: "admin",
- name: "admin",
- component: () => import("@/views/admin/Admin.vue"),
- meta: { requiresAdmin: true },
- },
- {
- path: "shrines",
- name: "shrine links",
- component: () => import("@/views/home/shrines/Shrines.vue"),
- },
- {
- path: "shrines/gto",
- name: "gto shrine",
- component: () => import("@/views/home/shrines/GTO.vue"),
- },
- {
- path: "shrines/skipskipbenben",
- name: "skipskipbenben shrine",
- component: () => import("@/views/home/shrines/Skipskipbenben.vue"),
- },
- {
- path: "shrines/evangelion",
- name: "evangelion shrine",
- component: () => import("@/views/home/shrines/Evangelion.vue"),
- },
- {
- path: "shrines/demoman",
- name: "demoman shrine",
- component: () => import("@/views/home/shrines/Demoman.vue"),
- },
- {
- path: ":pathMatch(.*)*",
- name: "404",
- component: () => import("@/views/404/404.vue"),
- },
- ],
- },
- {
- path: "/cv",
- component: CVLayout,
- children: [
- {
- path: "",
- name: "cv",
- component: () => import("@/views/CV/CV.vue"),
- },
- {
- path: "jobs",
- name: "job-applications",
- component: () => import("@/views/CV/JobApplications.vue"),
- meta: { requiresAdmin: true },
- },
- ],
- },
- ],
+ ],
});
router.beforeEach(async (to) => {
- if (!to.meta.requiresAdmin) return;
- const homeData = useHomeDataStore();
- if (!homeData.loaded) {
- await new Promise((resolve) => {
- const stop = watch(
- () => homeData.loaded,
- (val) => {
- if (val) {
- stop();
- resolve();
- }
- },
- );
- });
- }
- if (!useAuthStore().user.admin)
- return { path: "/admin/login", query: { redirect: to.fullPath } };
+ if (!to.meta.requiresAdmin) return;
+ const homeData = useHomeDataStore();
+ if (!homeData.loaded) {
+ await new Promise((resolve) => {
+ const stop = watch(
+ () => homeData.loaded,
+ (val) => {
+ if (val) {
+ stop();
+ resolve();
+ }
+ },
+ );
+ });
+ }
+ if (!useAuthStore().user.admin)
+ return { path: "/admin/login", query: { redirect: to.fullPath } };
});
export default router;
diff --git a/vue/src/views/CV/CVAnalyst.vue b/vue/src/views/CV/CVAnalyst.vue
index 562672f..81511af 100644
--- a/vue/src/views/CV/CVAnalyst.vue
+++ b/vue/src/views/CV/CVAnalyst.vue
@@ -204,6 +204,35 @@ import Project from "./Project.vue";
+
+ University Academy of Engineering Southbank
+
+ A Levels
+ Sep 2019 – Jun 2021
+
+
+ MathematicsA*
+ Further MathematicsA*
+ PhysicsA*
+
+
+ GCSEs
+ 2019
+
+
+ English Literature9
+ Mathematics9
+ Physics9
+ English Language8
+ Biology8
+ Chemistry8
+ Computer Science7
+
+
Soft Skills
diff --git a/vue/src/views/CV/cv-shared.css b/vue/src/views/CV/cv-shared.css
index 5929ea4..7d5fe8c 100644
--- a/vue/src/views/CV/cv-shared.css
+++ b/vue/src/views/CV/cv-shared.css
@@ -131,6 +131,28 @@
margin-bottom: 0.2em;
}
+.cv-template .grades-grid {
+ display: grid;
+ grid-template-columns: repeat(2, auto 1fr);
+ column-gap: 0.5em;
+ row-gap: 0.1em;
+ font-size: var(--cv-text-size);
+ color: var(--primary);
+ margin: 0.15em 0;
+}
+
+.cv-template .grades-grid > span:nth-child(4n + 2),
+.cv-template .grades-grid > span:nth-child(4n) {
+ font-weight: 600;
+ padding-right: 1.5em;
+}
+
+@media (max-width: 640px) {
+ .cv-template .grades-grid {
+ grid-template-columns: auto 1fr;
+ }
+}
+
.cv-template table {
color: var(--secondary);
border-collapse: collapse;