Adds functionality to load server-side checklist, then update locally later

This commit is contained in:
Alicia Sykes 2024-02-10 13:13:52 +00:00
parent f4bb43ab40
commit 9439d7f490
10 changed files with 74 additions and 22 deletions

View File

@ -17,6 +17,7 @@
},
"devDependencies": {
"@builder.io/qwik-city": "^1.1.4",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.11.16",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",

View File

@ -1,9 +1,9 @@
{
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
"name": "qwik-project-name",
"short_name": "Welcome to Qwik",
"name": "digital-defense",
"short_name": "Digital Defense",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"description": "A Qwik project app."
"background_color": "#5616c6",
"description": "The ultimate personal security checklist"
}

12
web/src/routes/_404.tsx Normal file
View File

@ -0,0 +1,12 @@
// src/routes/_404.tsx
import { component$ } from '@builder.io/qwik';
export default component$(() => {
return (
<div>
<h1>404 Not Found</h1>
<p>The page you're looking for doesn't exist.</p>
<a href="/">Go back to the homepage</a>
</div>
);
});

View File

@ -212,11 +212,11 @@ export default component$(() => {
});
export const head: DocumentHead = {
title: "Welcome to Qwik",
title: "About | Digital Defense",
meta: [
{
name: "description",
content: "Qwik site description",
content: "This project aims to give you practical guidance on how to improve your digital security, and protect your privacy online",
},
],
};

View File

@ -4,17 +4,20 @@ import { marked } from 'marked';
import Icon from '~/components/core/icon';
import { ChecklistContext } from '~/store/checklist-context';
import { useChecklist } from '~/store/local-checklist-store';
import type { Section } from "~/types/PSC";
import Table from '~/components/psc/checklist-table';
export default component$(() => {
const checklists = useContext(ChecklistContext);
const localChecklist = useChecklist();
const loc = useLocation();
const slug = loc.params.title;
const section: Section | undefined = checklists.value.find((item: Section) => item.slug === slug);
const section: Section | undefined = (localChecklist.checklist.checklist || checklists.value)
.find((item: Section) => item.slug === slug);
const parseMarkdown = (text: string | undefined): string => {
return marked.parse(text || '', { async: false }) as string || '';

View File

@ -2,17 +2,19 @@ import { component$, useContext } from "@builder.io/qwik";
import { ChecklistContext } from '~/store/checklist-context';
import { useLocalStorage } from "~/hooks/useLocalStorage";
import { useChecklist } from '~/store/local-checklist-store';
import type { Section } from "~/types/PSC";
export default component$(() => {
const checklists = useContext(ChecklistContext);
const localChecklist = useChecklist();
const [completed, setCompleted] = useLocalStorage('PSC_PROGRESS', {});
return (
<main class="p-8">
<div class="join join-vertical w-full">
{checklists.value.map((section: Section, index: number) => (
{(localChecklist.checklist.checklist || checklists.value).map((section: Section, index: number) => (
<div key={index} class={['collapse collapse-plus bg-base-200 my-4', `border-double border-2 border-${section.color}-400`]}>
<input type="radio" name="my-accordion-3" />
<div class={['collapse-title text-xl font-medium']}>

View File

@ -7,14 +7,18 @@ import Progress from "~/components/psc/progress";
import { ChecklistContext } from '~/store/checklist-context';
import { useChecklist } from '~/store/local-checklist-store';
export default component$(() => {
const checklists = useContext(ChecklistContext);
const localChecklist = useChecklist();
return (
<>
<Hero />
<Progress />
<SectionLinkGrid sections={checklists.value} />
<SectionLinkGrid sections={localChecklist.checklist.checklist || checklists.value} />
</>
);
});

View File

@ -1,18 +1,16 @@
import { component$, useContextProvider, Slot } from "@builder.io/qwik";
import { routeLoader$, type RequestHandler } from "@builder.io/qwik-city";
import Navbar from "../components/furniture/nav";
import Footer from "../components/furniture/footer";
import { ChecklistContext } from "../store/checklist-context";
import { type Sections } from "~/types/PSC";
import jsyaml from "js-yaml";
import Navbar from "~/components/furniture/nav";
import Footer from "~/components/furniture/footer";
import { ChecklistContext } from "~/store/checklist-context";
import type { Sections } from "~/types/PSC";
export const useChecklists = routeLoader$(async () => {
const url = import.meta.env.DEV ? `http://localhost:5173/personal-security-checklist.yml` : '/personal-security-checklist.yml';
return await fetch(url)
const remoteUrl = 'https://gist.githubusercontent.com/Lissy93/0c26e4255b6fabc2c027ac72a4428aeb/raw/4ccdbc71e0fffdef53472cf98acbe40b0acf982b/personal-security-checklist.yml';
// TODO: Update this URL to point to the Git repository
return fetch(remoteUrl)
.then((res) => res.text())
.then((res) => jsyaml.load(res) as Sections)
.catch(() => []);
@ -26,13 +24,11 @@ export const onGet: RequestHandler = async ({ cacheControl }) => {
};
export default component$(() => {
const checklists = useChecklists();
useContextProvider(ChecklistContext, checklists)
useContextProvider(ChecklistContext, checklists);
return (
<>
{/* <Header /> */}
<Navbar />
<main class="bg-base-100 min-h-full">
<Slot />

View File

@ -0,0 +1,29 @@
import { $, useStore, useOnWindow } from '@builder.io/qwik';
import jsyaml from 'js-yaml';
import type { Sections } from '~/types/PSC';
export const useChecklist = () => {
const state = useStore<{ checklist: Sections | null }>({ checklist: null });
const fetchChecklist = $(async () => {
const localUrl = '/personal-security-checklist.yml';
return fetch(localUrl)
.then((res) => res.text())
.then((yamlText) => {
return jsyaml.load(yamlText);
});
});
useOnWindow('load', $(() => {
fetchChecklist().then((checklist) => {
state.checklist = checklist as Sections;
});
}));
const setChecklist = $((newChecklist: Sections) => {
state.checklist = newChecklist;
});
return { checklist: state, setChecklist };
};

View File

@ -656,6 +656,11 @@
dependencies:
"@types/unist" "^2"
"@types/js-yaml@^4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2"
integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==
"@types/json-schema@^7.0.12":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"