Fix a shit ton of lint, tsc and build errors. All 100% working now

This commit is contained in:
Alicia Sykes 2024-02-04 16:38:51 +00:00
parent f598e46865
commit 9610d59a3c
12 changed files with 1491 additions and 77 deletions

View File

@ -1,4 +1,6 @@
{ {
"license": "MIT",
"scripts": { "scripts": {
"dev": "vite --mode ssr", "dev": "vite --mode ssr",
"build": "qwik build", "build": "qwik build",
@ -9,25 +11,34 @@
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force", "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
"fmt": "prettier --write .", "fmt": "prettier --write .",
"fmt.check": "prettier --check .", "fmt.check": "prettier --check .",
"lint": "eslint \"src/**/*.ts*\"", "lint": "eslint \"src/**/*.ts*\" -f compact",
"preview": "qwik build preview && vite preview --open", "preview": "qwik build preview && vite preview --open",
"start": "vite --open --mode ssr", "start": "vite --open --mode ssr",
"qwik": "qwik" "qwik": "qwik"
}, },
"devDependencies": { "devDependencies": {
"@builder.io/qwik-city": "^1.1.4", "@builder.io/qwik-city": "^1.1.4",
"@types/node": "^20.11.16",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"daisyui": "^3.0.2", "daisyui": "^3.0.2",
"eslint": "^8.56.0",
"eslint-plugin-qwik": "^1.4.3",
"postcss": "^8.4.21", "postcss": "^8.4.21",
"tailwindcss": "^3.2.4", "tailwindcss": "^3.2.4",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"undici": "^5.16.0", "undici": "^5.16.0",
"vite": "^4.0.4", "vite": "^4.0.4",
"vite-plugin-static-copy": "^1.0.1",
"vite-tsconfig-paths": "^4.3.1" "vite-tsconfig-paths": "^4.3.1"
}, },
"dependencies": { "dependencies": {
"@builder.io/qwik": "^1.1.4", "@builder.io/qwik": "^1.1.4",
"marked": "^12.0.0", "marked": "^12.0.0",
"sharp": "^0.33.2" "sharp": "^0.33.2"
},
"resolutions": {
"sharp": "^0.33.2"
} }
} }

View File

@ -99,16 +99,33 @@ const getSvgPath = (icon: string) => {
} }
}; };
const makeFillColor = (props: IconProps) => {
const isColorKey = (color: any): color is keyof typeof colors => color in colors;
let colorValue = 'currentcolor';
if (props.color && isColorKey(props.color)) {
const colorObject = colors[props.color];
if (colorObject[400]) {
colorValue = colorObject[400];
}
}
return colorValue;
};
interface IconProps { interface IconProps {
icon: string; icon: string;
color?: string; color?: string;
class?: string; class?: string;
width?: number; width?: number;
height?: number; height?: number;
}; }
const IconComponent = component$((props: IconProps) => { const IconComponent = component$((props: IconProps) => {
const fillColor = (colors[props.color] || [])[400] || colors['current'].currentColor || 'currentcolor'; const fillColor = makeFillColor(props);
const svgStyle = { fill: fillColor }; const svgStyle = { fill: fillColor };
const { vb, path } = getSvgPath(props.icon); const { vb, path } = getSvgPath(props.icon);
const svgClass = props.class || ''; const svgClass = props.class || '';

View File

@ -9,7 +9,7 @@ export default component$(() => {
<div class="max-w-2xl flex flex-col place-items-center"> <div class="max-w-2xl flex flex-col place-items-center">
<p>The Ultimate</p> <p>The Ultimate</p>
<h1 class="text-5xl font-bold">Personal Security Checklist</h1> <h1 class="text-5xl font-bold">Personal Security Checklist</h1>
<p class="subtitle pb-6">A guide to securing your digital life, and protecting your privacy online</p> <p class="subtitle pb-6">Your guide to securing your digital life and protecting your privacy</p>
<Icon class="mb-4" icon="shield" width={120} height={120} /> <Icon class="mb-4" icon="shield" width={120} height={120} />
<a href="https://github.com/lissy93/personal-security-checklist"> <a href="https://github.com/lissy93/personal-security-checklist">
<button class="btn btn-primary btn-lg"> <button class="btn btn-primary btn-lg">

View File

@ -9,58 +9,137 @@ import type { Section } from '../../types/PSC';
export default component$(() => { export default component$(() => {
return ( return (
<div class="navbar bg-base-100"> <>
<div class="flex-1"> <input id="my-drawer-3" type="checkbox" class="drawer-toggle" />
<a href="/" class="btn btn-ghost text-xl tooltip tooltip-bottom flex capitalize" data-tip="Go back to Homepage"> <div class="navbar bg-base-100">
<Icon class="mr-2" icon="shield" width={28} height={28} /> <div class="flex-1">
<h1>Personal Security Checklist</h1> <div class="flex-none md:hidden">
</a> <label for="my-drawer-3" aria-label="open sidebar" class="btn btn-square btn-ghost">
</div> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-6 h-6 stroke-current"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
<div class="flex-none"> </label>
<ul class="menu menu-horizontal px-1"> </div>
<li> <a href="/" class="btn btn-ghost text-xl flex capitalize">
<details> <label for="my-drawer-3" aria-label="open sidebar" class="tooltip tooltip-bottom" data-tip="View all Pages"><Icon class="mr-2" icon="shield" width={28} height={28} /></label>
<summary> <h1>Personal Security Checklist</h1>
<Icon icon="checklist" width={16} height={16} /> </a>
Checklists </div>
</summary> <div class="flex-none hidden md:flex">
<ul class="p-2 bg-base-100 rounded-t-none z-10"> <ul class="menu menu-horizontal px-1">
<li> <li>
<a href="/checklist"> <details>
<Icon class="mr-2" icon="all" width={16} height={16} /> <summary>
View All <Icon icon="checklist" width={16} height={16} />
</a> Checklists
</li> </summary>
{data.map((item: Section) => ( <ul class="p-2 bg-base-100 rounded-t-none z-10">
<li class={`hover:bg-${item.color}-600 hover:bg-opacity-15`}> <li>
<a href={`/checklist/${item.slug}`}> <a href="/checklist">
<Icon color={item.color} class="mr-2" icon={item.icon} width={16} height={16} /> <Icon class="mr-2" icon="all" width={16} height={16} />
{item.title} View All
</a> </a>
</li> </li>
))} {data.map((item: Section, index: number) => (
</ul> <li key={`checklist-nav-${index}`} class={`hover:bg-${item.color}-600 hover:bg-opacity-15`}>
</details> <a href={`/checklist/${item.slug}`}>
</li> <Icon color={item.color} class="mr-2" icon={item.icon} width={16} height={16} />
<li> {item.title}
<a class="tooltip flex tooltip-bottom" data-tip="View / Edit Source & Data"> </a>
<Icon icon="github" width={16} height={16} />GitHub </li>
</a> ))}
</li> </ul>
{/* <li> </details>
<a href="https://apps.aliciasykes.com" class="tooltip flex tooltip-bottom" data-tip="Other projects by Alicia Sykes"> </li>
<Icon icon="code" width={24} height={16} />More <li>
</a> <a href="#" class="tooltip flex tooltip-bottom" data-tip="View / Edit Source & Data">
</li> */} <Icon icon="github" width={16} height={16} />GitHub
</ul> </a>
<div class="tooltip tooltip-bottom" data-tip="Theme"> </li>
<label class="cursor-pointer grid place-items-center"> {/* <li>
<input type="checkbox" value="synthwave" class="toggle theme-controller bg-base-content row-start-1 col-start-1 col-span-2"/> <a href="https://apps.aliciasykes.com" class="tooltip flex tooltip-bottom" data-tip="Other projects by Alicia Sykes">
<svg class="col-start-1 row-start-1 stroke-base-100 fill-base-100" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M1 12h2M21 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"/></svg> <Icon icon="code" width={24} height={16} />More
<svg class="col-start-2 row-start-1 stroke-base-100 fill-base-100" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg> </a>
</label> </li> */}
</ul>
<div class="tooltip tooltip-bottom" data-tip="Theme">
<label class="cursor-pointer grid place-items-center">
<input type="checkbox" value="synthwave" class="toggle theme-controller bg-base-content row-start-1 col-start-1 col-span-2"/>
<svg class="col-start-1 row-start-1 stroke-base-100 fill-base-100" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M1 12h2M21 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"/></svg>
<svg class="col-start-2 row-start-1 stroke-base-100 fill-base-100" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
</label>
</div>
</div> </div>
</div> </div>
</div>
<div class="drawer-side z-10">
<label for="my-drawer-3" aria-label="close sidebar" class="drawer-overlay"></label>
<ul class="rounded-box menu p-4 w-80 min-h-full bg-base-200">
<h2 class="flex text-primary">
<Icon class="mr-2" icon="shield" width={16} height={16} />
Personal Security Checklist
</h2>
<li><a href="/">Home</a></li>
<li><a href="/">GitHub</a></li>
<li>
<a href="/checklist">Checklists</a>
<ul>
{data.map((item: Section, index: number) => (
<li key={`checklist-side-${index}`} class={`hover:bg-${item.color}-600 hover:bg-opacity-15`}>
<a href={`/checklist/${item.slug}`}>
<Icon color={item.color} class="mr-2" icon={item.icon} width={16} height={16} />
{item.title}
</a>
</li>
))}
</ul>
</li>
<li>
<a href="/article">Articles</a>
<ul>
<li><a href="/article/1">Article 1</a></li>
<li><a href="/article/2">Article 2</a></li>
</ul>
</li>
<li>
<a href="/about">About</a>
<ul>
<li>
<a href="#">Contributing</a>
</li>
<li>
<a href="#">License</a>
</li>
</ul>
<li>
<a href="#">Author</a>
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
<li>
<a href="#">Socials</a>
<ul>
<li><a href="">GitHub</a></li>
<li><a href="">Twitter</a></li>
<li><a href="">Mastodon</a></li>
</ul>
</li>
<li>
<a href="https://apps.aliciasykes.com">More Apps</a>
<ul>
<li><a href="#">Web-Check</a></li>
<li><a href="#">Dashy</a></li>
<li><a href="#">Portainer-Templates</a></li>
<li><a href="#">AdGuardian</a></li>
<li><a href="#">Bug-Bounties</a></li>
<li><a href="#">Awesome Privacy</a></li>
<li><a href="#">Email Comparison</a></li>
<li><a href="#">Git-In</a></li>
</ul>
</li>
</ul>
</li>
</li>
</ul>
</div>
</>
); );
}); });

View File

@ -0,0 +1,47 @@
import { component$ } from "@builder.io/qwik";
import type { DocumentHead } from "@builder.io/qwik-city";
export default component$(() => {
return (
<article class="bg-base-200 bg-opacity-25 p-8 mx-auto max-w-[1200px] m-8 rounded-lg shadow-lg">
<h3>About the Author</h3>
<p>
This project was originally started by me, Alicia Sykes- with a lot of help from the community.
</p>
<br />
<p>
I write apps which aim to help people escape big tech, secure their data,
and protect their privacy. I have a particular interest in self-hosting,
Linux and OSINT.
</p>
<br />
<p>
If this type of stuff interests you, I maintain several other repositories that you may also like:
</p>
<br />
<ul>
<li>Web-Check - OSINT tool for analysing any website</li>
<li>Dashy - Dashboard app, for organising your self-hosted services</li>
<li>Portainer-Templates - Compiled repository of 1-click Docker apps for self-hosting</li>
<li>AdGuardian - CLI tool for monitoring your networks traffic and AdGuard DNS stats</li>
<li>Bug-Bounties - Database of websites which accept responsible vulnerability discolsure</li>
<li>Awesome Privacy - A list of privacy-respscting software and services</li>
<li>Email Comparison - Objective comparison of private/secure mail providers</li>
<li>Git-In - Tools and resources to help beginners get into open source</li>
</ul>
<p>For a full list of projects I've published, see <a href="https://apps.aliciasykes.com/">apps.aliciasykes.com</a>, or follow me on GitHub (I'm <a href="https://github.com/lissy93">Lissy93</a>).</p>
</article>
);
});
export const head: DocumentHead = {
title: "Welcome to Qwik",
meta: [
{
name: "description",
content: "Qwik site description",
},
],
};

View File

@ -1,7 +1,8 @@
import { component$ } from '@builder.io/qwik'; import { component$ } from '@builder.io/qwik';
import { useLocation } from '@builder.io/qwik-city'; import { useLocation } from '@builder.io/qwik-city';
import marked from 'marked'; import { marked } from 'marked';
import Icon from '../../../components/core/icon';
import { data } from '../../../mock-data'; import { data } from '../../../mock-data';
import type { Section, Priority } from '../../../types/PSC'; import type { Section, Priority } from '../../../types/PSC';
@ -32,10 +33,17 @@ export default component$(() => {
return title.toLowerCase().replace(/ /g, '-'); return title.toLowerCase().replace(/ /g, '-');
}; };
const parseMarkdown = (text: string | undefined): string => {
return marked.parse(text || '', { async: false }) as string || '';
};
return ( return (
<article class="bg-base-200 bg-opacity-25 p-8 mx-auto w-full max-w-[1200px] rounded-lg shadow-lg"> <article class="bg-base-200 bg-opacity-25 p-8 mx-auto w-full max-w-[1200px] rounded-lg shadow-lg">
<h1 class="text-4xl font-bold capitalize">{section?.title}</h1> <h1 class={['gap-2 text-5xl font-bold capitalize flex']}>
<p class="py-2" dangerouslySetInnerHTML={marked.parse(section?.intro || '')}></p> <Icon height={36} width={36} icon={section?.icon || 'star'} />
{section?.title}
</h1>
<p class="py-2" dangerouslySetInnerHTML={parseMarkdown(section?.intro)}></p>
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<table class="table"> <table class="table">
@ -49,7 +57,7 @@ export default component$(() => {
</thead> </thead>
<tbody> <tbody>
{section?.checklist.map((item, index) => ( {section?.checklist.map((item, index) => (
<tr class={`rounded-sm hover:bg-opacity-5 hover:bg-${getBadgeClass(item.priority)}`}> <tr key={index} class={`rounded-sm hover:bg-opacity-5 hover:bg-${getBadgeClass(item.priority)}`}>
<td> <td>
<input type="checkbox" class="checkbox" id={generateId(item.point)} /> <input type="checkbox" class="checkbox" id={generateId(item.point)} />
</td> </td>
@ -63,7 +71,7 @@ export default component$(() => {
{item.priority} {item.priority}
</div> </div>
</td> </td>
<td class="" dangerouslySetInnerHTML={marked.parse(item.details)}></td> <td dangerouslySetInnerHTML={parseMarkdown(item.details)}></td>
</tr> </tr>
))} ))}
</tbody> </tbody>

View File

@ -1,13 +1,23 @@
import { component$ } from "@builder.io/qwik"; import { component$ } from "@builder.io/qwik";
import SectionLinkGrid from "../../components/psc/section-link-grid";
import { data } from '../../mock-data'; import { data } from '../../mock-data';
export default component$(() => { export default component$(() => {
return ( return (
<main class="flex items-center justify-center min-h-[80vh]"> <main class="p-8">
<SectionLinkGrid sections={data} /> <div class="join join-vertical w-full">
{data.map((section, index) => (
<div key={index} class="collapse collapse-plus bg-base-200 join-item">
<input type="radio" name="my-accordion-3" />
<div class={['collapse-title text-xl font-medium', `bg-${section.color}-400`]}>
<h3 class="text-slate-700">{section.title}</h3>
</div>
<div class="collapse-content">
<p>hello</p>
</div>
</div>
))}
</div>
</main> </main>
); );
}); });

View File

@ -1,12 +1,9 @@
import { component$, Slot, useStyles$ } from "@builder.io/qwik"; import { component$, Slot } from "@builder.io/qwik";
import type { RequestHandler } from "@builder.io/qwik-city"; import type { RequestHandler } from "@builder.io/qwik-city";
import Header from "../components/furniture/header";
import Navbar from "../components/furniture/nav"; import Navbar from "../components/furniture/nav";
import Footer from "../components/furniture/footer"; import Footer from "../components/furniture/footer";
// useStyles$(tailwind);
export const onGet: RequestHandler = async ({ cacheControl }) => { export const onGet: RequestHandler = async ({ cacheControl }) => {
cacheControl({ cacheControl({
staleWhileRevalidate: 60 * 60 * 24 * 7, staleWhileRevalidate: 60 * 60 * 24 * 7,

View File

@ -11,6 +11,7 @@ export interface Section {
icon: string, icon: string,
color: string, color: string,
checklist: Checklist[], checklist: Checklist[],
furtherLinks?: FurtherLink[],
} }
export type Priority = 'recommended' | 'optional' | 'advanced'; export type Priority = 'recommended' | 'optional' | 'advanced';
@ -21,3 +22,8 @@ export interface Checklist {
details: string, details: string,
} }
export interface FurtherLink {
title: string,
url: string,
description: string,
}

1
web/src/types/vite-plugin-copy.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare module 'vite-plugin-copy';

View File

@ -2,10 +2,23 @@ import { defineConfig, type UserConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer"; import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite"; import { qwikCity } from "@builder.io/qwik-city/vite";
import tsconfigPaths from "vite-tsconfig-paths"; import tsconfigPaths from "vite-tsconfig-paths";
import { viteStaticCopy } from 'vite-plugin-static-copy'
export default defineConfig((): UserConfig => { export default defineConfig((): UserConfig => {
return { return {
plugins: [qwikCity(), qwikVite(), tsconfigPaths()], plugins: [
qwikCity(),
qwikVite(),
tsconfigPaths(),
viteStaticCopy({
targets: [
{
src: '../personal-security-checklist.yml',
dest: 'public'
}
]
})
],
server: { server: {
headers: { headers: {
"Cache-Control": "public, max-age=0", "Cache-Control": "public, max-age=0",

File diff suppressed because it is too large Load Diff