From 569e003155d210ddf00b95440642eb34cc47a92a Mon Sep 17 00:00:00 2001 From: Mumtahin Farabi Date: Fri, 2 Aug 2024 22:53:13 -0400 Subject: [PATCH] feat(ui/docs): add devdocs site with content --- .map.ts | 4 + mdx-components.tsx | 29 + next.config.mjs | 14 +- src/app/api/search/route.ts | 11 + src/app/docs/[[...slug]]/page.tsx | 72 ++ src/app/docs/favicon.ico | Bin 0 -> 4286 bytes src/app/docs/fumadocs.global.css | 330 +++++++ src/app/docs/layout.config.tsx | 73 ++ src/app/docs/layout.tsx | 28 + src/app/docs/source.ts | 56 ++ .../docs/contribution-guidelines/index.mdx | 139 +++ .../docs/contribution-guidelines/meta.json | 7 + src/content/docs/index.mdx | 28 + src/content/docs/knowledge-base/index.mdx | 682 ++++++++++++++ src/content/docs/knowledge-base/meta.json | 7 + src/content/docs/meta.json | 10 + src/content/docs/tools-overview/index.mdx | 841 ++++++++++++++++++ src/content/docs/tools-overview/meta.json | 7 + tsconfig.json | 2 +- 19 files changed, 2338 insertions(+), 2 deletions(-) create mode 100644 .map.ts create mode 100644 mdx-components.tsx create mode 100644 src/app/api/search/route.ts create mode 100644 src/app/docs/[[...slug]]/page.tsx create mode 100644 src/app/docs/favicon.ico create mode 100644 src/app/docs/fumadocs.global.css create mode 100644 src/app/docs/layout.config.tsx create mode 100644 src/app/docs/layout.tsx create mode 100644 src/app/docs/source.ts create mode 100644 src/content/docs/contribution-guidelines/index.mdx create mode 100644 src/content/docs/contribution-guidelines/meta.json create mode 100644 src/content/docs/index.mdx create mode 100644 src/content/docs/knowledge-base/index.mdx create mode 100644 src/content/docs/knowledge-base/meta.json create mode 100644 src/content/docs/meta.json create mode 100644 src/content/docs/tools-overview/index.mdx create mode 100644 src/content/docs/tools-overview/meta.json diff --git a/.map.ts b/.map.ts new file mode 100644 index 00000000..681054cf --- /dev/null +++ b/.map.ts @@ -0,0 +1,4 @@ +/** Auto-generated */ +declare const map: Record + +export { map } diff --git a/mdx-components.tsx b/mdx-components.tsx new file mode 100644 index 00000000..9d621d58 --- /dev/null +++ b/mdx-components.tsx @@ -0,0 +1,29 @@ +import type { MDXComponents } from 'mdx/types' +import defaultComponents from 'fumadocs-ui/mdx' +import type { ReactNode } from 'react' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Callout } from 'fumadocs-ui/components/callout' + +export function useMDXComponents(components: MDXComponents): MDXComponents { + return { + ...defaultComponents, + ...components, + Tab, + Tabs, + InstallTabs: ({ + items, + children, + }: { + items: string[] + children: ReactNode + }) => ( + + {children} + + ), + Step, + Steps, + Callout, + } +} diff --git a/next.config.mjs b/next.config.mjs index 4a895d45..f4ab96fc 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,11 +2,23 @@ * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful * for Docker builds. */ +import createMDX from 'fumadocs-mdx/config' +import { fileGenerator, remarkDocGen, remarkInstall } from 'fumadocs-docgen' + await import('./src/env.js') +const withMDX = createMDX({ + rootContentPath: './src/content', + mdxOptions: { + lastModifiedTime: 'git', + remarkPlugins: [[remarkInstall, { Tabs: 'InstallTabs' }], [remarkDocGen, { generators: [fileGenerator()] }]], + }, +}) + /** @type {import("next").NextConfig} */ const config = { + reactStrictMode: true, output: 'standalone', } -export default config +export default withMDX(config) diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts new file mode 100644 index 00000000..bf94aee3 --- /dev/null +++ b/src/app/api/search/route.ts @@ -0,0 +1,11 @@ +import { createSearchAPI } from 'fumadocs-core/search/server' +import { getPages } from '@/app/docs/source' + +export const { GET } = createSearchAPI('advanced', { + indexes: getPages().map(page => ({ + title: page.data.title, + structuredData: page.data.exports.structuredData, + id: page.url, + url: page.url, + })), +}) diff --git a/src/app/docs/[[...slug]]/page.tsx b/src/app/docs/[[...slug]]/page.tsx new file mode 100644 index 00000000..5347a630 --- /dev/null +++ b/src/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,72 @@ +import type { Metadata } from 'next' +import { DocsBody, DocsPage } from 'fumadocs-ui/page' +import { notFound } from 'next/navigation' +import { Edit } from 'lucide-react' +import packageJson from '@root/package.json' +import { getPage, getPages } from '@/app/docs/source' + +export default async function Page({ + params, +}: { + params: { slug?: string[] } +}) { + const page = getPage(params.slug) + + if (page == null) { + notFound() + } + + const MDX = page.data.exports.default + const path = `src/content/docs/${page.file.path}` + const gitHubRepoUrl = packageJson.repository.url.replace(/\.git$/, '') // Remove .git suffix + + const footer = ( + + + Edit on GitHub + + ) + + return ( + + +

{page.data.title}

+

+ {page.data.description} +

+ +
+
+ ) +} + +export async function generateStaticParams() { + return getPages().map(page => ({ + slug: page.slugs, + })) +} + +export function generateMetadata({ params }: { params: { slug?: string[] } }) { + const page = getPage(params.slug) + + if (page == null) + notFound() + + return { + title: page.data.title, + description: page.data.description, + } satisfies Metadata +} diff --git a/src/app/docs/favicon.ico b/src/app/docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..192d6888705b96fdc575d93e337427dac3073dcf GIT binary patch literal 4286 zcmc&%Nhp6?9KXhlA@jyOJVVc{jEMysvxOxxEi8m&D@sy`g(MavFC>LXl7(3oGNfe6 zu)xB?JbmBqbN=t%j_cm*_q>0-qvM`??m6H2`}uxy?W46_zug^F5C?+O`R#sN@l3{Lcj(mN6f2^~b zOg=t7G&?)1DFgJ@m$$L8G5P!ZQ+Rkdxx2fQp`qcoGD8N$lhS~{(9j^M@%Hvcxw*OQKH@bw zIhhc9qO9^KViI@6f!J_#bW}Yb930GY>Hhwny1Tn6Jw2Vhi}&#y92{i(larJ5^z=ld zqod^P?5s!=G9ouIAV*nQnc_LfZE0yq6B85cEdG6be9-grGkZ##|LniKyzpC8QBk2v z7x)0)ySuyO;o+fr&dkh=hKGkg(G_2SPp}DZOYz&))fJ_rq^Qz`KY^1S9UX*Nmivf* z4-5>X_~2>C*T6|&bxux>>N(_;wY4?N zv4evHMjATT*Vhy5!qaqea-xxu5s^Jxo0^(_I>VpG8nr|#-wO%~XnlR1FH@nA8`SHDV@h2_(exYQ)p=D7yBsPLETit zE%2Y3niAPcPt;%~TG#_E7Z(>c^{JJp4Ql*BFF!w@#nsW#krZ2ti;HAuXQwCwFmQ8o zlMW9Lsi>$(@eD6J_^a6;=kOhI78Ddj`}_OM2FUTcy1FmEg-inj1CpKk`}^5_t=s~( z`1$#LD`!YZ2%VmuO0@6p?x?4yhf-5hDIy|*^78VSuXr5j?d@fLfDP4rf%p?~o3{(U zHa9n?@$qqqH@^T5AlBu$hcmDjaI>|wRaHOKu+Gj-P5eQOj*X2;Y=JQk4-a4PS8czg zrA3iHY=T$@{(5?PDxMMT03XfI&of=25A43Tw8tJ7}?m^Fuc9Fxsmw5@1h?gBO~eL4}uM9Yim{cqmF~t_4PHw0o1mQ zjSWJMRaRCK>XV#@7OtSL=5qzQTwGibYMGo4{DfRW@7UDT#Ow?_u(h>Sw5$BS{2e_W z`ZlG3T7#aFzXM!Bo+1zV{hzE+>)>mxfjH-V`4c`$cfcFHy*>kWNJvQdZNES8Tjo2x z<#JtKUb2|f>PwaM9Hp8x;= literal 0 HcmV?d00001 diff --git a/src/app/docs/fumadocs.global.css b/src/app/docs/fumadocs.global.css new file mode 100644 index 00000000..a97a24d4 --- /dev/null +++ b/src/app/docs/fumadocs.global.css @@ -0,0 +1,330 @@ +/*@config '../../../tailwind.fumadocs.config.ts';*/ +@config '../../../tailwind.config.ts'; +@tailwind base; +@tailwind components; +@tailwind utilities; + +/*---------------- HEADER ----------------*/ + +/*Hide on mobile screens, as the sidebar turns into the header on mobile screens*/ +#nd-nav { + @apply max-md:hidden md:sticky; +} + +/*Make header full width, otherwise it's constrained to a container and looks odd at larger screens*/ +#nd-nav nav { + @apply max-w-full; +} + +/*---------------- SIDEBAR ----------------*/ + +/*Sidebar is pushed down when header is visible.*/ +/*When the page is scrolled, the sidebar scrolls as well and is covered by the header.*/ + +/* Fix this by making the sidebar sticky, and setting the height to be viewport height minus the header height.*/ +#nd-sidebar { + @apply md:sticky md:top-16 md:h-[calc(100vh-4rem)]; +} + +/*First container with title, horizontal rule, search bar, and dots button*/ +/*#nd-sidebar > div:first-child {*/ +/* @apply md:hidden;*/ +/*}*/ + +/*Title bar*/ +#nd-sidebar > div:first-child > div:first-child { + @apply md:hidden; +} + +/*Root toggle*/ +#nd-sidebar > div:first-child > button { + @apply border-b; +} + +/*Search bar*/ +#nd-sidebar > div:first-child > button:last-child { + @apply md:hidden; +} + +/*Make the theme toggle button invisible on desktop screens, as the header already has a theme toggle button*/ +#nd-sidebar > div:nth-child(3) > [aria-label='Toggle Theme'] { + @apply md:invisible; +} + +/*The Table of Contents also faces the same issue as the sidebar when desktop header is visible. Apply similar fixes*/ +#nd-docs-layout > div:last-child { + @apply md:sticky md:top-16 md:h-[calc(100vh-4rem)] md:pt-8; +} + +/*---------------- ROLL BUTTON ----------------*/ + +/*The button appears behind the desktop header, move it down*/ +[aria-label='Scroll to Top'] { + @apply md:top-20 !important; +} + +/*---------------- THEME PRESETS ----------------*/ + +/*var defaultPreset = {*/ +/* light: {*/ +/* background: "0 0% 98%",*/ +/* foreground: "0 0% 3.9%",*/ +/* muted: "0 0% 96.1%",*/ +/* "muted-foreground": "0 0% 45.1%",*/ +/* popover: "0 0% 100%",*/ +/* "popover-foreground": "0 0% 15.1%",*/ +/* card: "0 0% 99.7%",*/ +/* "card-foreground": "0 0% 3.9%",*/ +/* border: "0 0% 89.8%",*/ +/* primary: "0 0% 9%",*/ +/* "primary-foreground": "0 0% 98%",*/ +/* secondary: "0 0% 96.1%",*/ +/* "secondary-foreground": "0 0% 9%",*/ +/* accent: "0 0% 94.1%",*/ +/* "accent-foreground": "0 0% 9%",*/ +/* ring: "0 0% 63.9%"*/ +/* },*/ +/* dark: {*/ +/* background: "0 0% 3.9%",*/ +/* foreground: "0 0% 98%",*/ +/* muted: "0 0% 12.9%",*/ +/* "muted-foreground": "0 0% 60.9%",*/ +/* popover: "0 0% 7%",*/ +/* "popover-foreground": "0 0% 88%",*/ +/* card: "0 0% 8%",*/ +/* "card-foreground": "0 0% 98%",*/ +/* border: "0 0% 18%",*/ +/* primary: "0 0% 98%",*/ +/* "primary-foreground": "0 0% 9%",*/ +/* secondary: "0 0% 12.9%",*/ +/* "secondary-foreground": "0 0% 98%",*/ +/* accent: "0 0% 14.9%",*/ +/* "accent-foreground": "0 0% 90%",*/ +/* ring: "0 0% 14.9%"*/ +/* }*/ +/*};*/ +/*var oceanPreset = {*/ +/* light: {*/ +/* background: "0 0% 98%",*/ +/* foreground: "0 0% 3.9%",*/ +/* muted: "220 90% 96.1%",*/ +/* "muted-foreground": "0 0% 45.1%",*/ +/* popover: "0 0% 98%",*/ +/* "popover-foreground": "0 0% 15.1%",*/ +/* card: "220 50% 98%",*/ +/* "card-foreground": "0 0% 3.9%",*/ +/* border: "220 50% 89.8%",*/ +/* primary: "210 80% 20.2%",*/ +/* "primary-foreground": "0 0% 98%",*/ +/* secondary: "220 90% 96.1%",*/ +/* "secondary-foreground": "0 0% 9%",*/ +/* accent: "220 50% 94.1%",*/ +/* "accent-foreground": "0 0% 9%",*/ +/* ring: "220 100% 63.9%"*/ +/* },*/ +/* dark: {*/ +/* "card-foreground": "220 60% 94.5%",*/ +/* "primary-foreground": "0 0% 9%",*/ +/* "secondary-foreground": "220 80% 90%",*/ +/* ring: "205 100% 85%",*/ +/* card: "220 50% 10%",*/ +/* muted: "220 50% 10%",*/ +/* "muted-foreground": "220 30% 65%",*/ +/* "accent-foreground": "220 80% 90%",*/ +/* popover: "220 50% 10%",*/ +/* "popover-foreground": "220 30% 65%",*/ +/* accent: "220 40% 20%",*/ +/* secondary: "220 50% 20%",*/ +/* background: "220 60% 6%",*/ +/* foreground: "220 60% 94.5%",*/ +/* primary: "205 100% 85%",*/ +/* border: "220 50% 20%"*/ +/* },*/ +/* css: {*/ +/* ".dark body": {*/ +/* "background-image": "linear-gradient(rgba(5, 105, 255, 0.15), transparent 20rem, transparent)"*/ +/* }*/ +/* }*/ +/*};*/ +/*var neutral = {*/ +/* light: {*/ +/* background: "0 0% 96%",*/ +/* foreground: "0 0% 3.9%",*/ +/* muted: "0 0% 96.1%",*/ +/* "muted-foreground": "0 0% 45.1%",*/ +/* popover: "0 0% 100%",*/ +/* "popover-foreground": "0 0% 15.1%",*/ +/* card: "0 0% 94.7%",*/ +/* "card-foreground": "0 0% 3.9%",*/ +/* border: "0 0% 89.8%",*/ +/* primary: "0 0% 9%",*/ +/* "primary-foreground": "0 0% 98%",*/ +/* secondary: "0 0% 93.1%",*/ +/* "secondary-foreground": "0 0% 9%",*/ +/* accent: "0 0% 90.1%",*/ +/* "accent-foreground": "0 0% 9%",*/ +/* ring: "0 0% 63.9%"*/ +/* },*/ +/* dark: {*/ +/* background: "0 0% 8.9%",*/ +/* foreground: "0 0% 92%",*/ +/* muted: "0 0% 12.9%",*/ +/* "muted-foreground": "0 0% 60.9%",*/ +/* popover: "0 0% 9.8%",*/ +/* "popover-foreground": "0 0% 88%",*/ +/* card: "0 0% 10%",*/ +/* "card-foreground": "0 0% 98%",*/ +/* border: "0 0% 18%",*/ +/* primary: "0 0% 98%",*/ +/* "primary-foreground": "0 0% 9%",*/ +/* secondary: "0 0% 12.9%",*/ +/* "secondary-foreground": "0 0% 98%",*/ +/* accent: "0 0% 16.9%",*/ +/* "accent-foreground": "0 0% 90%",*/ +/* ring: "0 0% 14.9%"*/ +/* },*/ +/* css: {*/ +/* "#nd-sidebar": {*/ +/* "--muted": "0deg 0% 89%",*/ +/* "--secondary": "0deg 0% 99%",*/ +/* "--muted-foreground": "0 0% 30%"*/ +/* },*/ +/* ".dark #nd-sidebar": {*/ +/* "--muted": "0deg 0% 16%",*/ +/* "--secondary": "0deg 0% 18%",*/ +/* "--muted-foreground": "0 0% 72%"*/ +/* }*/ +/* }*/ +/*};*/ +/*var catppuccin = {*/ +/* light: {*/ +/* popover: "220deg 22% 92%",*/ +/* "popover-foreground": "234deg 16% 35%",*/ +/* "secondary-foreground": "234deg 16% 35%",*/ +/* border: "223deg 16% 83%",*/ +/* primary: "266deg 85% 58%",*/ +/* "primary-foreground": "234deg 16% 35%",*/ +/* muted: "220deg 22% 92%",*/ +/* card: "220deg 22% 92%",*/ +/* accent: "223deg 16% 83%",*/ +/* "accent-foreground": "234deg 16% 35%",*/ +/* "card-foreground": "234deg 16% 35%",*/ +/* "muted-foreground": "233deg 10% 47%",*/ +/* foreground: "234deg 16% 35%",*/ +/* secondary: "220deg 22% 92%",*/ +/* background: "220deg 23% 95%",*/ +/* ring: "267deg 84% 81%"*/ +/* },*/ +/* dark: {*/ +/* ring: "267deg 84% 81%",*/ +/* primary: "267deg 84% 81%",*/ +/* background: "240deg 21% 15%",*/ +/* foreground: "226deg 64% 88%",*/ +/* popover: "240deg 23% 9%",*/ +/* card: "240deg 21% 12%",*/ +/* muted: "240deg 21% 12%",*/ +/* border: "237deg 16% 23%",*/ +/* accent: "237deg 16% 23%",*/ +/* secondary: "240deg 21% 12%",*/ +/* "primary-foreground": "240deg 23% 9%",*/ +/* "card-foreground": "226deg 64% 88%",*/ +/* "secondary-foreground": "226deg 64% 88%",*/ +/* "popover-foreground": "226deg 64% 88%",*/ +/* "accent-foreground": "226deg 64% 88%",*/ +/* "muted-foreground": "228deg 24% 72%"*/ +/* },*/ +/* css: {*/ +/* "#nd-sidebar": {*/ +/* "--secondary": "223deg 16% 83%",*/ +/* "--muted": "223deg 16% 83%"*/ +/* },*/ +/* ".dark #nd-sidebar": {*/ +/* "--secondary": "237deg 16% 23%",*/ +/* "--muted": "237deg 16% 23%"*/ +/* }*/ +/* }*/ +/*};*/ +/*var purple = {*/ +/* light: {*/ +/* background: "256 100% 96%",*/ +/* primary: "270 100% 52%",*/ +/* border: "270 40% 80%",*/ +/* accent: "270 60% 86%",*/ +/* "accent-foreground": "270 100% 20%",*/ +/* muted: "256 60% 94%",*/ +/* "muted-foreground": "256 50% 50%",*/ +/* foreground: "256 60% 26%",*/ +/* secondary: "270 60% 90%",*/ +/* "secondary-foreground": "256 60% 10%",*/ +/* card: "256 60% 92%",*/ +/* "card-foreground": "256 100% 20%",*/ +/* "popover-foreground": "256 100% 20%",*/ +/* popover: "256 60% 96%",*/ +/* "primary-foreground": "270 100% 20%",*/ +/* ring: "270 100% 52%"*/ +/* },*/ +/* dark: {*/ +/* background: "256 60% 6%",*/ +/* primary: "270 100% 86%",*/ +/* border: "270 100% 20%",*/ +/* accent: "256 60% 26%",*/ +/* "accent-foreground": "270 100% 86%",*/ +/* muted: "256 60% 10%",*/ +/* foreground: "256 60% 90%",*/ +/* "muted-foreground": "256 50% 75%",*/ +/* secondary: "270 100% 20%",*/ +/* "secondary-foreground": "256 60% 90%",*/ +/* card: "256 60% 10%",*/ +/* "card-foreground": "256 60% 90%",*/ +/* "popover-foreground": "256 60% 90%",*/ +/* popover: "256 60% 6%",*/ +/* "primary-foreground": "256 60% 6%",*/ +/* ring: "270 100% 86%"*/ +/* }*/ +/*};*/ +/*var dusk = {*/ +/* light: {*/ +/* background: "250 20% 92%",*/ +/* primary: "340 40% 48%",*/ +/* border: "240 40% 90%",*/ +/* accent: "250 30% 90%",*/ +/* "accent-foreground": "250 20% 20%",*/ +/* muted: "240 30% 94%",*/ +/* "muted-foreground": "240 10% 50%",*/ +/* foreground: "220 20% 30%",*/ +/* secondary: "250 40% 94%",*/ +/* "secondary-foreground": "240 40% 10%",*/ +/* card: "250 20% 92%",*/ +/* "card-foreground": "250 20% 20%",*/ +/* "popover-foreground": "250 40% 20%",*/ +/* popover: "250 40% 96%",*/ +/* "primary-foreground": "240 80% 20%",*/ +/* ring: "340 40% 48%"*/ +/* },*/ +/* dark: {*/ +/* ring: "340 100% 90%",*/ +/* "primary-foreground": "240 40% 4%",*/ +/* popover: "240 20% 5%",*/ +/* "popover-foreground": "250 20% 90%",*/ +/* primary: "340 100% 90%",*/ +/* border: "220 15% 15%",*/ +/* background: "220 15% 6%",*/ +/* foreground: "220 15% 87%",*/ +/* muted: "220 20% 15%",*/ +/* "muted-foreground": "220 15% 60%",*/ +/* accent: "250 20% 15%",*/ +/* secondary: "240 20% 15%",*/ +/* "card-foreground": "240 15% 87%",*/ +/* card: "240 20% 5%",*/ +/* "secondary-foreground": "250 20% 90%",*/ +/* "accent-foreground": "340 5% 90%"*/ +/* }*/ +/*};*/ +/*var presets = {*/ +/* default: defaultPreset,*/ +/* neutral,*/ +/* dusk*/ +/* purple,*/ +/* ocean: oceanPreset,*/ +/* catppuccin,*/ +/*};*/ diff --git a/src/app/docs/layout.config.tsx b/src/app/docs/layout.config.tsx new file mode 100644 index 00000000..74a3f270 --- /dev/null +++ b/src/app/docs/layout.config.tsx @@ -0,0 +1,73 @@ +import type { DocsLayoutProps } from 'fumadocs-ui/layout' +import { RootToggle } from 'fumadocs-ui/components/layout/root-toggle' +import { Library as DocumentationPageIcon } from 'lucide-react' +import Image from 'next/image' +import type { HomeLayoutProps } from 'fumadocs-ui/home-layout' +import { pageTree, pages } from '@/app/docs/source' + +// shared configuration +export const baseOptions: HomeLayoutProps = { + nav: { + title: ( + <> + cuHacking logo + cuHacking DevDocs + + ), + url: '/docs', + }, + githubUrl: 'https://github.com/cuhacking/hackathon', + links: [ + { + text: 'Docs Home', + url: '/docs', + icon: , + }, + { + text: 'Landing Page', + url: 'https://www.cuhacking.ca', + icon: , + }, + { + text: 'Hacker Portal', + url: '/', + icon: , + }, + ], +} + +// home layout configuration +export const homeOptions = { + ...baseOptions, +} + +// docs layout configuration +export const docsOptions: DocsLayoutProps = { + ...baseOptions, + sidebar: { + banner: ( + ({ + title: page.title, + description: page.description, + url: `/docs/${page.url}`, + icon: ( + + ), + }))} + /> + ), + }, + tree: pageTree, +} diff --git a/src/app/docs/layout.tsx b/src/app/docs/layout.tsx new file mode 100644 index 00000000..af7f5ffa --- /dev/null +++ b/src/app/docs/layout.tsx @@ -0,0 +1,28 @@ +import './fumadocs.global.css' +import { DocsLayout } from 'fumadocs-ui/layout' +import { HomeLayout } from 'fumadocs-ui/home-layout' +import type { ReactNode } from 'react' +import { RootProvider } from 'fumadocs-ui/provider' +import type { Metadata } from 'next' +import { docsOptions, homeOptions } from './layout.config' + +export const metadata: Metadata = { + title: 'cuHacking DevDocs', + description: + 'Documentation platform for the cuHacking development team, serving as a central hub for all things development-related at cuHacking.', + icons: [{ rel: 'icon', url: '/favicon.ico' }], +} + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + + + + {children} + + + + + ) +} diff --git a/src/app/docs/source.ts b/src/app/docs/source.ts new file mode 100644 index 00000000..c755015f --- /dev/null +++ b/src/app/docs/source.ts @@ -0,0 +1,56 @@ +import { map } from '@root/.map' +import { createMDXSource } from 'fumadocs-mdx' +import { loader } from 'fumadocs-core/source' +import { createElement } from 'react' + +import { + GitPullRequestCreateArrow as ContributionGuidelinesIcon, + Dock as HomeIcon, + Library as KnowledgeBaseIcon, + Layers as ToolsIcon, + icons, +} from 'lucide-react' + +export const pages = [ + { + title: 'Home', + description: 'Read the docs, and suffer less - Wise Person', + url: '', + icon: HomeIcon, + }, + { + title: 'Tools Overview', + description: 'Explore the suite of software we use.', + url: 'tools-overview', + icon: ToolsIcon, + }, + { + title: 'Contribution Guidelines', + description: 'Understand our collaboration process.', + url: 'contribution-guidelines', + icon: ContributionGuidelinesIcon, + }, + { + title: 'Knowledge Base', + description: 'Curated resources to accelerate your learning.', + url: 'knowledge-base', + icon: KnowledgeBaseIcon, + }, +] + +export const { getPage, getPages, pageTree } = loader({ + baseUrl: '/docs', + rootDir: 'docs', + icon(icon) { + if (!icon) { + // You may set a default icon + // return createElement(HomeIcon) + return + } + + if (icon in icons) + return createElement(icons[icon as keyof typeof icons]) + }, + + source: createMDXSource(map), +}) diff --git a/src/content/docs/contribution-guidelines/index.mdx b/src/content/docs/contribution-guidelines/index.mdx new file mode 100644 index 00000000..24257cf8 --- /dev/null +++ b/src/content/docs/contribution-guidelines/index.mdx @@ -0,0 +1,139 @@ +--- +title: Quick Start +description: Understand our collaboration process. +icon: LayoutTemplate +--- + +import { Accordion, Accordions } from "fumadocs-ui/components/accordion"; + +## Using Lazygit and Linux/Unix + +The use of [Lazygit](https://github.com/jesseduffield/lazygit) is highly encouraged, as it provides a visual [terminal user interface (TUI)](https://en.wikipedia.org/wiki/Text-based_user_interface) to manage your commits, branches, staging areas, stashes, and much more. It is also significantly easier to resolve merge conflicts, cherry-pick commits between branches, squash them, amend a few commits back, checkout a specific commit, stage in hunks, etc. You will be able to unlock the full power of Git without having to memorize all the commands. + +For Windows users, the use of [Windows Subsystem Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/install) is highly encouraged in order to avoid those rare, maddening, a-tiny-part-of-this-one-library-breaks issues that can be very hard to debug. + + + +
    +
  • + No you don'tπŸ˜‚ You can simply run WSL in your VS Code terminal, or any + other IDE terminal. Rather than cloning the repo on your windows + machine, you'd be cloning it in a directory of your choice in the Linux + OS. +
  • +
  • + You can still access the windows filesystem from WSL and vice versa, + browsing through the Linux directories with the Windows file explorer + graphically. It's an deadly combo. Well done MicrosoftπŸ‘ +
  • +
+
+
+ +As you go through this document, if there is a technology or process you'd like to dig deeper into, feel free to explore our [knowledge base](/docs/knowledge-base). If you find some great resources and/or have some of your own, we'd very much appreciate your contributions :) + +--- + +
+
+ Step 1: Read our [Tools Overview](/docs/tools-overview) to get an understanding of the technologies + we use and why. +
+
Step 2: Follow along with the rest of this page.
+
+ +--- + +#### Install pnpm + +This project uses [pnpm](https://pnpm.io/). You can follow the instructions on the pnpm website to install it. Then do the following: + +```bash +# Clone this repository +git clone git@github.com:cuhacking/hackathon.git + +# Navigate to repository +cd hackathon + +# Install dependencies listed in package.json +pnpm i + +# Run the app locally +pnpm dev +``` + +--- + +### Conventional Commits + +We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for commit messages. + +When you hit `enter` after doing `git commit`, it will trigger a [Git Hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) managed by [Husky](https://typicode.github.io/husky/), which triggers a [Commitlint](https://commitlint.js.org/) command to verify that your commit message meets the specified guidelines. Any messages that do not follow the specification will be rejected with feedback locally. + +In order to ease the process of learning the specification and writing compliant commit messages, we've configured [Commitizen](https://commitizen-tools.github.io/commitizen/) to guide you through the process of writing a commit message interactively. +You can run `pnpm commit` to use this tool. This will guarantee that your commit messages are formatted correctly. + +With time, writing conventional commit messages will become second nature and you will no longer need to use Commitizen :) + +- Each commit should be a single logical change. Don't make several logical changes in one commit. For example, if a patch fixes a bug and optimizes the performance of a feature, split it into two separate commits. +- Each commit should be able to stand on its own, and each commit should build on the previous one. This way, if a commit introduces a bug, it should be easy to identify and revert. +- Each commit should be deployable and not break the build, tests, or functionality. +- If you're not sure if a commit should be split, it's better to split it if each commit is deployable and doesn't break the build, tests, or functionality. +- If you fixed changes in a past commit, use `git commit --amend` to add changes to the previous commit rather than creating a new one; thus keeping the commit history clean and concise. + - Only exception to this is if the commit already existed on the `main` branch, in which case a fixup commit should be made rather than an amend. If that commit is amended and force pushed, it will diverge the git history for the entire team. +- If you ever amend, reorder, or rebase, your local branch will become divergent from the remote for the amended commit(s), so GitHub won't let you push. Simply force push to overwrite your old branch: `git push --force-with-lease`. + +--- + +### Branching Guidelines + +We currently follow [Trunk-based development](https://tilburgsciencehub.com/topics/automation/version-control/advanced-git/git-branching-strategies/) with a no-merge, no-squash, rebase-only workflow as the project is in its early stages. This essentially means you should always create a branch off `main` in the following format: +`yourname//-`. For example, `johndoe/feat/1-add-login-page`. + +Do not do `git merge`, as this can create a merge commit unless you fast forward; instead always pull the latest from `main`, check back out to your branch, then do `git rebase main`. +This keeps a clean, linear history that is free of merge commits and easy to debug. + +This is subject to change as the project and team scales. Our goal is to always keep branches as short-lived as possible, thus keeping cycle times to a minimum and reducing bugs. + +Sometimes the issue names are long, in which case you can create them directly by clicking on an issue, and it'll autofill the issue number and name for you in kebab-case. + +--- + +### Coding Guidelines + +We're huge on clean code. Code will be read more than it is written. Thankfully you don't have to memorize all of the conventions, as most of them have been automated by [ESLint](https://eslint.org/). If you have the ESLint extension in your IDE, you will immediately see some annoying red and yellow squigglies underneath your code. Thankfully, most of these squigglies can be made to go away using the format command in your IDE, or by running `pnpm lint:fix` in your terminal. + + + +
    +
  • Yes, they're very annoying, we understand😫
  • +
  • We feel tempted to just throw in an `eslint ignore` too. We learned over time that these squigglies are invaluable in ensuring that all code everyone writes follows the same style guide. Following the same conventions also makes migrations and automated codebase re-writes significantly easier using tools such as [codemods](https://github.com/facebook/jscodeshift).
  • +
  • It's either the squigglies or trying to memorize many pages of documentation on style guides which vary from team to team. Having PRs nitpicked at or argued over by different opinions is also very time consuming. It wears the team down and increases the chances of bugs. Whenever possible, we do our best to automate fixes for the squigglies.
  • +
+
+ + +Googling works great; as an alternative ESLint also comes with an interactive solution to find which rules come from which plugins, and hyperlink you to their docs directly. + +Simply do `pnpm lint:inspect` in your terminal, and you'll see a little web app pop up in your browser. It will look [like this](https://eslint-config.antfu.me). Click around and explore :) + +You can also view the `eslint.config.mjs` file to view a list of the presets and plugins we use. + + +
+ +### Pull Requests + +Always simple rebase your branch onto main before creating a pull request. This ensures that your branch is up to date with the latest changes in the main branch. Branch and PR rules are set up for the repo just in case as a guardrail. + +Do your best to close only 1 issue per pull request, and always use the exact same PR title as the issue name. This makes debugging easier later. If the current issue is blocking the next, simply create a new branch off the branch for the pull request and continue working on the next issue on that branch. This technique is called [branch stacking](https://medium.com/@lneves12/git-how-to-stack-multiple-git-branches-and-rebase-them-like-a-pro-91c0cdf67ef). With the power of `git rebase`, you can continually apply PR feedback for the first branch while making progress for the next task on the second branch. Once again, [Lazygit](https://github.com/jesseduffield/lazygit) makes this very quick and easy to do cleanly. + +Ensure that the issue is linked to your PR, and is part of a milestone. However, do not add it to the project board, because it shows up as a card and causes visual pollution. We can easily just see your linked PR from the closed issue if we need to find it. + +If you're getting tired of storing work in progress by stashing changes or amending commits and then switching branches, it's a great sign to look into using [Git Worktrees](https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/Use-this-git-worktree-add-example-and-never-switch-branches-again). + +--- + +### Final Step + +Profit. diff --git a/src/content/docs/contribution-guidelines/meta.json b/src/content/docs/contribution-guidelines/meta.json new file mode 100644 index 00000000..0c0e8fb9 --- /dev/null +++ b/src/content/docs/contribution-guidelines/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Contribution Guidelines", + "icon": "GitPullRequestCreateArrow", + "pages": [ + "index" + ] +} diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx new file mode 100644 index 00000000..cd0640db --- /dev/null +++ b/src/content/docs/index.mdx @@ -0,0 +1,28 @@ +--- +title: Welcome to the Docs +description: Read the docs, and suffer less - Wise Person +--- + +import { pages } from "../../app/docs/source"; + +## Categories + + + {pages + .filter((page) => page.title !== "Home") // Filter out the Home page + .map((page) => ( + + } + /> + ))} + diff --git a/src/content/docs/knowledge-base/index.mdx b/src/content/docs/knowledge-base/index.mdx new file mode 100644 index 00000000..0845f377 --- /dev/null +++ b/src/content/docs/knowledge-base/index.mdx @@ -0,0 +1,682 @@ +--- +title: Quick Start +description: Curated resources to accelerate your learning. +icon: LayoutTemplate +--- + +### πŸ’‘ Hackathon Platforms + + + + + + + + + + + + +### 🌳 Learn Git + + + + + + +### 🧠 General Learning + + + + + + + + + + + +### ✨ Front-End Drill/Practice + + + + + + + + + + + +### βš™οΈ Back-End Drill/Practice + + + + + + + + + + +### πŸ›οΈ Software Architecture + + + + + + + + +### βš› Next.js Ecosystem + + + + + +### πŸ“„ Documentation & References + + + + + + + + + +### πŸ› οΈ Tools + + + + + + + + + +### 🧹 Code Quality + + + + + + + +### πŸ’… UI Libraries & Design Systems + + + + + + + + +### 🧱 Component Libraries + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +### 🎨 CSS + + + + + + + + + +### πŸŽ₯ Animations + + + + + + + + +### ⚑️ Tailwind CSS Components and Layouts + + + + + + + + + + +### 🌠 General UI/UX + + + + + + +### 🏞️ Custom Component Inspiration & Templates + + + + + + +### 🌟 Inspiration + + + + + + + + + + + + +### πŸ‘οΈ Tools (UI/UX) + + + + + + + + + + + + + + + + + + + + + +### πŸ€– GitHub Actions + + + + + +### πŸ†“ Free Stuff + + + + + + +### πŸ’» GitHub Resource Repos + + + + + + + +### πŸ“– Articles & Blogs + + + + + + + + +### πŸ“½οΈ Must-watch YouTube Videos + + + + + +### πŸ‘©β€πŸ’» Join the Dark Side (Be warned, there is no turning back) + + + + + + + + diff --git a/src/content/docs/knowledge-base/meta.json b/src/content/docs/knowledge-base/meta.json new file mode 100644 index 00000000..43a99f9e --- /dev/null +++ b/src/content/docs/knowledge-base/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Knowledge Base", + "icon": "Library", + "pages": [ + "index" + ] +} diff --git a/src/content/docs/meta.json b/src/content/docs/meta.json new file mode 100644 index 00000000..ec11e1d9 --- /dev/null +++ b/src/content/docs/meta.json @@ -0,0 +1,10 @@ +{ + "root": true, + "pages": [ + "index", + "--- Categories ---", + "tools-overview", + "contribution-guidelines", + "knowledge-base" + ] +} diff --git a/src/content/docs/tools-overview/index.mdx b/src/content/docs/tools-overview/index.mdx new file mode 100644 index 00000000..05f5cbe0 --- /dev/null +++ b/src/content/docs/tools-overview/index.mdx @@ -0,0 +1,841 @@ +--- +title: Quick Start +description: Explore the suite of software we use. +icon: LayoutTemplate +--- + +import { Image } from "next/image"; + +Written in a beginner-friendly language in order to provide a smooth onboarding experience for [cuHacking's](https://www.cuhacking.ca) 2024-25 development team, and also act as a general open-source reference for other projects. + +## πŸ”­ Project Management + + + +
  • Tracking issues, tasks, and progress directly within GitHub.
  • +
  • + Allows everyone to see what everyone else is up to, and do work + without blocking each other. +
  • + + } + href={`https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects`} + icon={ + GitHub Logo + } + /> + +
  • Powerful all-in-one workspace used by all teams at cuHacking.
  • +
  • + Mostly to keep an open line of communication with other teams, + technical tasks will be on GitHub Projects. +
  • + + } + href={`https://www.notion.so/`} + icon={ + Notion Logo + } + /> +
    + +## πŸͺ„ UI/UX Design + + + +
  • + An outrageously powerful collaborative design tool for wireframing + ideas and prototyping mockups. +
  • +
  • + Allows you to sort out your UI/UX first, saving you from writing code + and end up building the wrong thing which also may look like potato πŸ₯” +
  • + + } + href={`https://www.figma.com/`} + icon={ + Figma Logo + } + /> +
    + +## 🐞 Development + +### πŸ“¦ Package Manager + + + +
  • + Drop-in replacement for npm that is faster and better in almost every + way. +
  • +
  • + Better for both the disk health of your computer and the speed of our + CI/CD pipelines +
  • + + } + href={`https://pnpm.io/`} + icon={ + pnpm Logo + } + /> +
    + +### ✨ Front-End + + + +
  • Javascript on steroids.
  • +
  • Catches your silly bugs before you can even run the code.
  • + + } + href={`https://www.typescriptlang.org/`} + icon={ + TypeScript Logo + } + /> + +
  • A JavaScript view layer library for building user interfaces.
  • +
  • Emphasis on the library part, it's not a framework.
  • +
  • + Very bueno for saving you from writing all the HTML yourself, and + adding small bits of interactivity. +
  • +
  • + Not so bueno for heavyweight interactivity, need bigger guns and + external libraries for that. +
  • + + } + href={`https://reactjs.org/`} + icon={ + React Logo + } + /> + +
  • + An unopinionated and batteries-not-included React framework with + routing, server-side rendering, image optimizations, and many other + things. +
  • +
  • + In a nutshell, pulls all kinds of strings that allow you to use React + without setting the user's computer on fire. +
  • + + } + href={`https://nextjs.org/`} + icon={ + Next.js Logo + } + /> + +
  • + A framework for developing and testing UI components in isolation. +
  • +
  • + Allows you to make your buttons in peace, without having to launch the + entire main app to see it. +
  • +
  • + Also doubles as documentation for our design system and a playground + for anything and everything the user sees in the main app, in any + state; saving you valuable clickity clicks. +
  • + + } + href={`https://storybook.js.org/`} + icon={ + Storybook Logo + } + /> + +
  • A utility-first CSS framework to style components super fast.
  • +
  • + No more separate stylesheets. Won't necessarily fix your potato UI but + will allow you to make them faster and with less debugging. +
  • +
  • + Does not scale well and makes codebases unreadable by mixing styling + and business logic. This is addressed by good React component + architecture in tandem with other libraries. +
  • + + } + href={`https://tailwindcss.com/`} + icon={ + TailwindCSS Logo + } + /> + +
  • + Unstyled headless components that we can easily lay our design system + on top of. +
  • +
  • + Also handles accessibility, saving us from writing and maintaining a + lot of code + tests. +
  • + + } + href={`https://www.radix-ui.com/primitives`} + icon={ + Radix UI Primitives Logo + } + /> + +
  • + A modern component library built on top of Radix UI Primitives and + styled with Tailwind, combining accessibility, customizability, and + business logic into one. +
  • +
  • + Has an entire ecosystem of other libraries and heavily supported by + the community, making it easy for us to find any component we need. +
  • +
  • + Also has maintained Figma files and Storybooks, allowing us to tightly + integrate design mockups with the frontend. +
  • +
  • + Not an npm package, and therefore easily modifiable because we have + direct access to code. Even comes with tools so that we can track how + much we changed the original look. +
  • + + } + href={`https://ui.shadcn.dev/`} + icon={ + Shadcn/ui Logo + } + /> +
    + +### ⁉️ State Management + + + +
  • Purpose-built and highly opinionated state management library.
  • +
  • + Lots of documentation, large community, and rich ecosystem of plugins. +
  • +
  • + Helps you manage variables that are highly susceptible to change, and + upon which lots of other variables may depend on. +
  • +
  • + Separates state management from the React view layer and other + business logic entirely, and therefore scales well + easy to debug. +
  • + + } + href={`https://redux.js.org/`} + icon={ + Redux Logo + } + /> +
    + +### βš™οΈ Back-End & Middleware + + + +
  • Handling authentication safely and securely.
  • +
  • + Allows people to log in to our app with pre-existing + Google/Microsoft/Apple accounts, saving us from having to deal with + their sensitive data. +
  • + + } + href={`https://next-auth.js.org`} + icon={ + NextAuth.js Logo + } + /> + +
  • End-to-end typesafe API layer for interfacing with databases.
  • + + } + href={`https://trpc.io/`} + icon={ + tRPC Logo + } + /> + +
  • Open-source relational database system where we store data.
  • + + } + href={`https://www.postgresql.org/`} + icon={ + PostgreSQL Logo + } + /> + +
  • + An ORM that saves us from writing raw SQL queries, plays well with the + Node.ts ecosystem. +
  • + + } + href={`https://www.prisma.io/`} + icon={ + Prisma Logo + } + /> + +
  • + Content Management System to hold static data displayed across our + websites and apps. +
  • +
  • + Provides a database that stores static content such as text and images + away from our codebase, so that other teams can change them directly + through a nice admin dashboard without having to contact us. +
  • +
  • + Gives us the power of WordPress without getting in our way for + customizability. +
  • + + } + href={`https://payloadcms.com`} + icon={ + Payload CMS Logo + } + /> +
    + +## 🧹 Code Quality + + + +
  • + Find and fix problems in code, and enforce style guide and best + practices. +
  • +
  • + Saves you from having to memorize and study our style guide by giving + you instant feedback while coding. +
  • +
  • + Saves us from having to make our entire style guide and re-invent best + practices from scratch using plugins. +
  • +
  • + Can catch lightweight surface bugs. Cannot catch deep business logic + bugs, but prevents the likelihood of them happening by catching the + surface bugs. +
  • + + } + href={`https://eslint.org/`} + icon={ + ESLint Logo + } + /> + +
  • An opinionated code formatter to make code look Prettier.
  • +
  • + Cannot catch bugs. Only handles fixing inconsistencies in spacing, + quotes, semicolons, parentheses, brackets, etc. +
  • + + } + href={`https://prettier.io/`} + icon={ + Prettier Logo + } + /> + +
  • + Standardized open-source specification for commit messages. +
  • + + } + href={`https://www.conventionalcommits.org/en/v1.0.0/`} + icon={ + Conventional Commits Logo + } + /> + +
  • + A tool to create standardized commit messages that adhere to the{" "} + + conventional commits specification + {" "} + + our sprinkles on top. +
  • + + } + href={`https://commitizen.github.io/cz-cli/`} + icon={ + Commitizen Logo + } + /> + +
  • Lint commit messages according to our specifications.
  • +
  • + + Commitlint/config-conventional + + - Plugin that enforces conventional commits for commit messages and + allows us to modify them. +
  • +
  • + + Commitlint/cz-commitlint + + - Provides an integration for Commitizen so that the only options + displayed to you are the same ones defined in Commitlint. +
  • +
  • + In a nutshell, blocks commit messages that do not meet our specs, + which in turn saves our CI pipelines from crashing or creating the + wrong versions, which in turn ensures our whole app doesn't blow up. +
  • + + } + href={`https://commitlint.js.org/`} + icon={ + Commitlint Logo + } + /> + +
  • + Runs ESLint and Prettier on Git staged files so that there are no code + style diffs at the PR level. +
  • + + } + href={`https://github.com/okonet/lint-staged`} + icon={ + Lint-staged Logo + } + /> + +
  • + Library that allows us to quickly and easily trigger Git hooks, which + in turn trigger commands to run the tools mentioned above. +
  • + + } + href={`https://typicode.github.io/husky/#/`} + icon={ + Husky Logo + } + /> +
    + +## βš—οΈ Testing + + + +
  • For writing both unit tests and integration tests.
  • +
  • + Code with peace of mind and get instant feedback if you break + something. +
  • + + } + href={`https://vitest.dev/`} + icon={ + Vitest Logo + } + /> + +
  • For End-to-end testing of our entire app.
  • +
  • + Instead of clicking around the entire app yourself to see if it still + works after every single time you make a change, why not let a robot + do it for you? +
  • + + } + href={`https://playwright.dev/`} + icon={ + Playwright Logo + } + /> + +
  • + Executes Vitest and Playwright test suites on design system + components, along with handling accessibility testing, and coverage + testing using plugins. +
  • + + } + href={`https://storybook.js.org/docs/writing-tests/test-runner`} + icon={ + Storybook Test Runner Logo + } + /> + +
  • + Visual test server platform to easily spot differences in UI and + discuss them as a team, integrated with Storybook. +
  • +
  • + Can catch visual bugs by comparing new renders with a specified + baseline, and block the changes from making it to production prior to + being reviewed. +
  • + + } + href={`https://www.chromatic.com/`} + icon={ + Chromatic Logo + } + /> +
    + +## ☁️ Deployment + + + +
  • + Automated versioning and package publishing as per the{" "} + Semantic Versioning specification. +
  • +
  • + Parses the history of commit messages to automatically generate + changelogs. +
  • +
  • + Requires conventional commit specs to be followed in order to work + properly. +
  • + + } + href={`https://semantic-release.gitbook.io/semantic-release/`} + icon={ + Semantic Release Logo + } + /> + +
  • + Automated CI/CD pipelines to run linting, test suites, and handle + versioning. +
  • +
  • + The final boss you need to defeat before human eyes even see your + code. +
  • +
  • + Very fun to configure and watch at work. Not very fun to debug ☁️ +
  • + + } + href={`https://github.com/features/actions`} + icon={ + GitHub Actions Logo + } + /> + +
  • + For safely deploying our app to the web so that people can see and use + it from their browsers. +
  • +
  • + Uses AWS under the hood. +
  • +
  • + Integrates well with Next.js and also allows for demo deployments for + our own purposes which are not indexed on google. +
  • +
  • + If we push a version that makes it past all our tests but somehow + breaks at the build stage, Vercel will provide instant feedback and + not deploy it, leaving up the previous functional version. +
  • +
  • + Also allows quick and easy rollbacks to previously deployed versions. +
  • + + } + href={`https://vercel.com/`} + icon={ + Vercel Logo + } + /> + +
  • + Containerization platform to develop, ship, and run the app anywhere. +
  • +
  • + Your computer is a box. Someone else's computer is a box. Your box is + different from their box. The thing works on their box but not yours. + What if both of you used the same box with the same configs and could + easily pass it around like hot potato? πŸ“¦πŸ€” +
  • +
  • + Docker is that box, more fancily referred to as a 'container'. Both of + you run this box inside your box. It works for both of you by + boxception. +
  • + + } + href={`https://www.docker.com/`} + icon={ + Docker Logo + } + /> +
    diff --git a/src/content/docs/tools-overview/meta.json b/src/content/docs/tools-overview/meta.json new file mode 100644 index 00000000..fd214253 --- /dev/null +++ b/src/content/docs/tools-overview/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Tools Overview", + "icon": "Layers", + "pages": [ + "index" + ] +} diff --git a/tsconfig.json b/tsconfig.json index ef7b8998..4f40fb9f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -41,6 +41,6 @@ ".next/types/**/*.ts", "postcss.config.cjs", "next.config.mjs" - ], +, ".map.ts" ], "exclude": ["node_modules"] }