This commit is contained in:
Jacob Babich
2021-04-26 02:35:41 -04:00
parent acdbbe6d21
commit 84b5e7ff44
27 changed files with 1866 additions and 1876 deletions

View File

@@ -1,2 +1,20 @@
# My University Website
This is a micro-project for my personal domain at my university's web server.
TODO:
```js
const modules = import.meta.glob('')
const rawModules = {}
for (const path in modules) {
rawModules[path] = () => import(`${path}?raw`)
}
// or
const modules = import.meta.glob('../models/docs/*/*.md')
const docs = modules.map( path => {
return () => import(`${path}?raw`)
})
```
Then you should have an object called rawModules that has all the proper urls to import them as a string

View File

@@ -13,6 +13,7 @@ module.exports = {
}],
],
layout: {
_: "./src/routes/_centered-prose.svelte",
_: "./src/lib/Prose.svelte",
blog: "./src/routes/blog/_layout.svelte",
},
};

View File

@@ -9,19 +9,18 @@
"format": "prettier --write ."
},
"devDependencies": {
"@sveltejs/adapter-static": "^1.0.0-next.4",
"@sveltejs/adapter-static": "next",
"@sveltejs/kit": "next",
"@tailwindcss/jit": "^0.1.18",
"@tailwindcss/typography": "^0.4.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"autoprefixer": "^10.2.5",
"cssnano": "^5.0.1",
"eslint": "^7.24.0",
"eslint-config-prettier": "^8.2.0",
"eslint-plugin-svelte3": "^3.1.2",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^3.2.0",
"mdsvex": "^0.9.0",
"postcss": "^8.2.10",
"postcss": "^8.2.12",
"postcss-load-config": "^3.0.1",
"prettier": "~2.2.1",
"prettier-plugin-svelte": "^2.2.0",
@@ -30,13 +29,13 @@
"remark-abbr": "^1.4.1",
"remark-github": "^10.0.1",
"svelte": "^3.37.0",
"svelte-preprocess": "^4.7.0",
"tailwindcss": "^2.1.1",
"svelte-preprocess": "^4.7.2",
"tailwindcss": "^2.1.2",
"tailwindcss-theme-variants": "^1.11.0-beta.1",
"tslib": "^2.2.0",
"typescript": "^4.2.4",
"vite": "^2.1.5",
"vite-imagetools": "3.4.0-next.1"
"vite": "^2.2.3",
"vite-imagetools": "^3.4.0"
},
"type": "module",
"engines": {

3252
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,6 @@
%svelte.head%
</head>
<body class="bg-primary text-on-primary">
<div id="svelte">%svelte.body%</div>
<div id="svelte" class="flex flex-col min-h-screen">%svelte.body%</div>
</body>
</html>

View File

@@ -1,4 +1,4 @@
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap');
@tailwind base;
::selection {

3
src/lib/Prose.svelte Normal file
View File

@@ -0,0 +1,3 @@
<div class="prose">
<slot />
</div>

View File

@@ -1,10 +1,64 @@
<script>
import { author, shortName as siteTitle } from "./_site.config.js";
import { page } from "$app/stores";
import "../app.postcss";
// TODO: doesn't actually use ico format
import faviconIco from "./_favicon.png?width=32&height=32&format=ico";
import favicon from "./_favicon.png?width=128&height=128&format=png";
import appleTouchIcon from "./_favicon.png?width=180&height=180&format=png";
const links = [
{
name: "Blog",
route: "/blog",
},
{
name: "Projects",
route: "/projects",
},
{
name: "University",
route: "https://umdearborn.edu/",
},
];
// TODO: based on the page
import image from "./_me.png";
const imageAlt = "A photo of me";
const pageTitle = "What is this?";
$: title = `${pageTitle} - ${siteTitle}`;
const description = "My first blog post, explaining this very cool template";
const domain = "localhost:3000";
const route = "/blog/what-is-this";
$: url = `${domain}${route}`;
$: metaTagsProperty = {
"author": author,
"og:url": url,
"og:type": "website",
"og:title": title,
"og:image": image,
"og:image:alt": imageAlt,
...(description ? {
"og:description": description,
} : {}),
"og:site_name": siteTitle,
"og:locale": "en_US",
};
$: metaTagsName = {
"twitter:card": "summary_large_image",
"twitter:url": url,
"twitter:title": title,
...(description ? {
"twitter:description": description,
} : {}),
"twitter:image": image,
"twitter:image:alt": imageAlt,
}
</script>
<svelte:head>
@@ -12,6 +66,37 @@
<link rel="shortcut icon" type="image/png" href={favicon} />
<link rel="apple-touch-icon" href={appleTouchIcon} />
<link rel="manifest" href="/manifest.json" />
<title>{title}</title>
{#each Object.entries(metaTagsProperty) as [property, content]}
<meta {property} {content} />
{/each}
{#each Object.entries(metaTagsName) as [name, content]}
<meta {name} {content} />
{/each}
</svelte:head>
<slot />
<!-- Attribution: https://tailblocks.cc/ -->
<header class="text-on-primary-weak py-8 flex justify-center">
<div class="w-full max-w-prose flex flex-wrap flex-col md:flex-row items-center">
<nav class="flex flex-wrap items-center text-base justify-center">
<a href="/" class="mr-8 font-medium text-xl border-b-2 border-transparent hover:text-accent hover:border-accent">{siteTitle}</a>
{#each links as link}
<a href={link.route} class="ml-8" class:text-accent={$page.path.startsWith(link.route)} class:hover:text-accent={!$page.path.startsWith(link.route)}>{link.name}</a>
{/each}
</nav>
</div>
</header>
<main class="flex-1 py-8 flex flex-col items-center">
<slot />
</main>
<!-- Attribution: https://tailblocks.cc/ -->
<footer class="bg-primary-dark text-on-primary-weak py-8 flex justify-center">
<div class="w-full max-w-prose">
<p class="text-sm text-on-primary-weak">© {new Date().getFullYear()} {author}</p>
</div>
</footer>

View File

@@ -1,7 +0,0 @@
<script>
import Prose from "./_prose.svelte";
</script>
<div class="flex justify-center">
<Prose><slot /></Prose>
</div>

View File

@@ -1,3 +0,0 @@
<article class="prose">
<slot />
</article>

View File

@@ -0,0 +1,14 @@
import babichjacob from "./_me.png";
export const author = "J / Jacob Babich";
export const shortName = "World's Best Blog";
export const name = "J / Jacob Babich's Blog - The World's Best";
export const description = "This is where I go to write some thoughts. I usually write about programming and my time at University.";
export const lang = "en-US";
export const authors = {
"babichjacob": {
name: "J / Jacob Babich",
photo: babichjacob,
}
};

View File

@@ -0,0 +1,23 @@
<script>
import { authors } from "../_site.config.js";
export let author;
export let created;
export let title;
export let subtitle;
</script>
<div class="w-full max-w-prose items-center pt-12">
<img class="h-16 w-16 mr-8 rounded-full inline-block float-left" src={authors[author].photo} alt="A photo of {authors[author].name}" title={authors[author].name} />
<div class="text-on-primary-weak"><span class="text-on-primary">{authors[author].name}</span> on <span class="text-on-primary">{new Date(created).toLocaleString(undefined, { weekday: "long", month: "long", day: "numeric", year: "numeric" })}</span> wrote</div>
<div class="mt-4 text-4xl font-heading font-bold leading-none">{title}</div>
<div class="mt-8 text-2xl font-heading">{subtitle}</div>
</div>
<hr class="border-t-4 mt-4 mb-8 border-on-primary-faint border-solid block w-full max-w-prose" />
<article class="prose w-full max-w-prose py-12">
<slot />
</article>

View File

@@ -0,0 +1,35 @@
---
layout: blog
author: babichjacob
created: 2020-08-23T00:00:00
title: "I hate your theme switch"
subtitle: "Just copy my system theme and be done with it."
---
Prologue.
# How did we get here?
This is where I'd write the introductory knowledge.
## Why you think your theme switch is a good idea
Sure, you're supporting multiple themes on your site, which is really nice for
## The problems with this approach
It's another UI element to design.
Your site will never match my theme without writing custom JavaScript to copy it.
* Your site won't be themed without JavaScript enabled.
* Your users have to download that extra code for a feature that could be supported without it --- if you're willing to believe that manually switching themes on just one site is probably unnecessary *on your site*.
* (Extreme nitpick) your site's theme won't transition smoothly with the rest of the system on macOS. **Imagine I put a video here demonstrating**
# My preferred solutions
Reminder: This is all my opinion, and other users of your site may disagree.
## Option 1: No theme switch
Always use the system theme and be done with it.
## Option 2: Not a theme switch, but a theme option menu
Have 3 mutually exclusive buttons: use system theme, always use light theme, and always use dark theme.
## Implementation
Always do the theming in the CSS. Don't store theme information in JavaScript beyond the button interactivity.

View File

@@ -0,0 +1,30 @@
import { parse } from "path";
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async () => {
const modules = import.meta.glob("./**/index.svelte.md");
const posts = [];
await Promise.all(Object.entries(modules).map(async ([file, module]) => {
const { metadata } = await module();
posts.push({
author: metadata.author,
created: metadata.created,
slug: parse(file).dir,
subtitle: metadata.subtitle,
title: metadata.title,
});
}));
// Newest first
posts.sort((a, b) => (a.created > b.created) ? -1 : 1);
return {
body: {
posts: posts,
},
}
};

View File

@@ -0,0 +1,41 @@
<script context="module">
export const load = async ({ fetch }) => {
const response = await fetch("/blog.json");
const { posts } = await response.json();
return {
props: {
posts,
}
};
};
</script>
<script>
export let posts;
</script>
<div class="max-w-prose py-12">
<h1 class="text-2xl font-medium">All posts from the blog:</h1>
<div class="divide-y-2 divide-primary-weak">
{#each posts as post}
<div class="py-8 flex flex-wrap md:flex-nowrap">
<div class="md:w-64 md:mb-0 mb-6 flex-shrink-0 flex flex-col">
<span class="mt-1 text-on-primary-weak text-sm">{new Date(post.created).toLocaleString(undefined, { weekday: "long", month: "long", day: "numeric", year: "numeric" })}</span>
</div>
<div class="md:flex-grow">
<h2 class="text-2xl font-medium text-on-primary font-heading mb-2">{post.title}</h2>
<p class="leading-relaxed text-on-primary-weak">{post.subtitle}</p>
<a class="text-accent border-b-2 border-transparent hover:border-accent inline-flex items-center mt-4" href="/blog/{post.slug}">Read on
<svg class="w-4 h-4 ml-2" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14"></path>
<path d="M12 5l7 7-7 7"></path>
</svg>
</a>
</div>
</div>
{/each}
</div>
</div>

View File

@@ -0,0 +1,11 @@
---
layout: blog
author: babichjacob
created: 2021-04-17T00:00:00
title: "Showcasing my computer architecture design final project"
subtitle: "... that my partner did the majority of the work on."
---
This is just an example blog post.
*I don't want* to have to make a bunch of example paragraphs for this.

View File

@@ -0,0 +1,15 @@
---
layout: blog
author: babichjacob
created: 2021-04-25T00:00:00
title: "Reflecting on the 20202021 school year"
subtitle: "How online learning has been my uprise and downfall."
---
# Fall semester
Things were really good! This was one of my best semesters in college
I got a false sense of confidence from it.
# Winter semester
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

View File

@@ -0,0 +1,11 @@
---
layout: blog
author: babichjacob
created: 2021-01-13T00:00:00
title: "Starting the Winter 2021 semester"
subtitle: "Ready for a harder semester after a rejuvenating longer-than-usual break"
---
This is just an example blog post.
*I don't want* to have to make a bunch of example paragraphs for this.

View File

@@ -0,0 +1,17 @@
---
layout: blog
author: babichjacob
created: 2020-10-20T00:00:00
title: "Why I don't write (or even like) tutorials"
subtitle: "We as developers already know communication is hard, so let's skip that step."
---
Before I can talk about --- if I ever do talk about it cause I don't know where in this setup --- my issue with tutorials, let's talk about my own experiences making (learning) resources.
# Writing boilerplates
Like this one!
Eventually, the problems with maintaining templates became more apparent as I made more of them.
# Example: the Svelte Adders project
The Svelte Adders project is me taking what I've learned from creating boilerplates.

18
src/routes/index.svelte Normal file
View File

@@ -0,0 +1,18 @@
<script>
import me from "./_me.png";
import { description } from "./_site.config.js";
</script>
<div class="w-full max-w-prose">
<div class="w-full">
<img src={me} alt="A photo of me" class="w-80 h-80 ml-16 rounded-full float-right" />
<span class="text-4xl font-medium text-accent">Welcome!</span>
<p>
{description}
</p>
</div>
</div>

View File

@@ -1,26 +0,0 @@
<script>
import photosOfMe from "./_me.png?width=10;300;1000&format=png;webp&srcset";
import photoOfMe from "./_me.png?width=20&format=webp&metadata";
</script>
# J / Jacob Babich
<picture>
<source srcset={photosOfMe} />
<img src={photoOfMe.src} height={photoOfMe.height} width={photoOfMe.width} class="w-full" />
</picture>
**Student at the University of Michigan-Dearborn**
Cool facts about me:
* I'm seeking a [computer engineering](umdearborn.edu) and **electrical engineering** dual degree.
## Imagine this is another heading
Beware that this site is extremely likely to go out of date! I'd like to keep it updated but that might not be a high priority.
---
*This website's source code is available on [GitHub](https://github.com/babichjacob/university-website)*

View File

@@ -1,22 +1,53 @@
import type { RequestHandler } from "@sveltejs/kit";
import colors from "tailwindcss/colors.js";
import { author, description, lang, name, shortName } from './_site.config.js';
import icon192 from './_favicon.png?width=192&height=192&format=png';
import icon512 from './_favicon.png?width=512&height=512&format=png';
export const get = async () => {
export const get: RequestHandler = async () => {
return {
body: {
// TODO: rest of the manifest
body: {
short_name: shortName,
name,
description,
lang,
icons: [
{
src: icon192,
type: 'image/png',
sizes: '192x192'
sizes: '192x192',
purpose: 'any maskable'
},
{
src: icon512,
type: 'image/png',
sizes: '512x512'
sizes: '512x512',
purpose: 'any maskable'
}
]
}
],
start_url: '/',
display: 'minimal-ui',
background_color: '#FFFFFF',
theme_color: colors.amber[500],
shortcuts: [
{
name: 'Read my Blog',
short_name: 'Blog',
description: `Read all the posts on ${shortName}`,
url: '/blog',
icons: [] // TODO,
},
{
name: 'See my projects',
short_name: 'Projects',
description: `Take a look at all the projects ${author} has to show`,
url: '/blog',
icons: [] // TODO,
},
],
},
};
};

View File

@@ -0,0 +1,3 @@
<div class="max-w-prose w-full">
Exercise for you: implement the projects page
</div>

View File

@@ -1,9 +1,8 @@
const imagetools = require('vite-imagetools');
const { imagetools } = require('vite-imagetools');
const { mdsvex } = require("mdsvex");
const mdsvexConfig = require("./mdsvex.config.cjs");
const sveltePreprocess = require('svelte-preprocess');
const preprocess = require('svelte-preprocess');
const static = require('@sveltejs/adapter-static');
const pkg = require('./package.json');
/** @type {import('@sveltejs/kit').Config} */
module.exports = {
@@ -12,7 +11,7 @@ module.exports = {
// for more information about preprocessors
preprocess: [
mdsvex(mdsvexConfig),
sveltePreprocess({
preprocess({
postcss: true,
}),
],
@@ -28,9 +27,6 @@ module.exports = {
force: true
}),
],
ssr: {
noExternal: Object.keys(pkg.dependencies || {})
},
},
},
};

View File

@@ -3,6 +3,7 @@ module.exports = (_theme) => ({
css: {
color: false,
fontWeight: 300,
maxWidth: false,
"@apply text-on-primary": "",
a: {

View File

@@ -6,13 +6,11 @@ const { themeVariants, prefersDark, prefersLight } = require("tailwindcss-theme-
module.exports = {
mode: "jit",
purge: [
"./src/**/*.{html,js,md,svelte,svx,ts}",
],
purge: ["./src/**/*.{html,js,md,svelte,svx,ts}"],
theme: {
extend: {
colors: {
"true-gray": colors.trueGray,
gray: colors.trueGray,
amber: colors.amber,
},
@@ -21,6 +19,10 @@ module.exports = {
heading: ["'Rubik'", ...defaultTheme.fontFamily.serif],
},
maxWidth: {
prose: "42rem",
},
typography,
},
},
@@ -33,11 +35,17 @@ module.exports = {
semantics: {
colors: {
"primary": "white",
"primary-dark": "gray-100",
"on-primary": "gray-900",
"on-primary-weak": "gray-600",
"on-primary-faint": "gray-400",
"accent": "amber-600",
"accent-vivid": "amber-400",
"accent-strong": "amber-800",
"on-accent": "black",
},
},
@@ -46,12 +54,18 @@ module.exports = {
mediaQuery: prefersDark,
semantics: {
colors: {
"primary": "true-gray-900",
"primary": "gray-900",
"primary-dark": "black",
"on-primary": "white",
"on-primary-weak": "gray-400",
"on-primary-faint": "gray-600",
"accent": "amber-400",
"accent-vivid": "amber-600",
"accent-strong": "amber-200",
"on-accent": "white",
},
},

View File

@@ -1,13 +1,18 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es2018",
"module": "es2020",
"lib": [
"es2020"
],
"target": "es2019",
/**
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
to enforce using \`import type\` instead of \`import\` for Types.
*/
"importsNotUsedAsValues": "error",
"isolatedModules": true,
"resolveJsonModule": true,
/**
To have warnings/errors of the Svelte compiler at the correct position,
enable source maps by default.
@@ -20,10 +25,15 @@
"allowJs": true,
"checkJs": true,
"paths": {
"$app/*": [".svelte/dev/runtime/app/*", ".svelte/build/runtime/app/*"],
"$service-worker": [".svelte/build/runtime/service-worker"],
"$lib/*": ["src/lib/*"]
"$lib/*": [
"src/lib/*"
]
}
},
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"]
}
"include": [
"src/**/*.d.ts",
"src/**/*.js",
"src/**/*.ts",
"src/**/*.svelte"
]
}