mirror of
https://github.com/Lissy93/personal-security-checklist.git
synced 2024-10-01 01:35:37 -04:00
Adds functionality to load server-side checklist, then update locally later
This commit is contained in:
parent
f4bb43ab40
commit
9439d7f490
@ -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",
|
||||
|
@ -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
12
web/src/routes/_404.tsx
Normal 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>
|
||||
);
|
||||
});
|
@ -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",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -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 || '';
|
||||
|
@ -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']}>
|
||||
|
@ -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} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
@ -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 />
|
||||
|
29
web/src/store/local-checklist-store.ts
Normal file
29
web/src/store/local-checklist-store.ts
Normal 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 };
|
||||
};
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user