Add typescript/og-website
This commit is contained in:
commit
73b742dd80
|
@ -7,3 +7,4 @@
|
||||||
| [wave38](./wave38/) | Remake of [wave37](https://github.com/Mateiadrielrafael/wave37) I dropped super early into development. |
|
| [wave38](./wave38/) | Remake of [wave37](https://github.com/Mateiadrielrafael/wave37) I dropped super early into development. |
|
||||||
| [pleix-frontend](./pleix-frontend/) | No idea what `pleix` was supposed to be, but this was essentially just a bunch of experiments with [lit-html](https://lit.dev/) |
|
| [pleix-frontend](./pleix-frontend/) | No idea what `pleix` was supposed to be, but this was essentially just a bunch of experiments with [lit-html](https://lit.dev/) |
|
||||||
| [monadic](./monadic) | Custom web framework inspired by [halogen](https://github.com/purescript-halogen/purescript-halogen) |
|
| [monadic](./monadic) | Custom web framework inspired by [halogen](https://github.com/purescript-halogen/purescript-halogen) |
|
||||||
|
| [og-website](./og-website) | My first ever personal website |
|
||||||
|
|
3
typescript/og-website/.gitignore
vendored
Normal file
3
typescript/og-website/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.env
|
5
typescript/og-website/.prettierrc
Normal file
5
typescript/og-website/.prettierrc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
3
typescript/og-website/.vscode/settings.json
vendored
Normal file
3
typescript/og-website/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
}
|
21
typescript/og-website/LICENSE
Normal file
21
typescript/og-website/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Matei Adriel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
5
typescript/og-website/README.md
Normal file
5
typescript/og-website/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Website
|
||||||
|
|
||||||
|
My own personal website.
|
||||||
|
|
||||||
|
Check it out [here](https://matei-adriel.herokuapp.com/projects)
|
6
typescript/og-website/nodemon.json
Normal file
6
typescript/og-website/nodemon.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/nodemon.json",
|
||||||
|
"exec": "npm start",
|
||||||
|
"ext": "js,json,ts,css",
|
||||||
|
"ignore": ["node_modules", ".gitignore", ".vscode"]
|
||||||
|
}
|
3051
typescript/og-website/package-lock.json
generated
Normal file
3051
typescript/og-website/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
22
typescript/og-website/package.json
Normal file
22
typescript/og-website/package.json
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "website",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"start": "ts-node src/index.ts",
|
||||||
|
"dev": "nodemon"
|
||||||
|
},
|
||||||
|
"author": "Matei Adriel",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^1.19.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@popeindustries/lit-html-server": "^1.6.0",
|
||||||
|
"@types/express": "^4.17.1",
|
||||||
|
"dotenv": "^8.2.0",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"ts-node": "^8.4.1",
|
||||||
|
"typescript": "^3.6.4"
|
||||||
|
}
|
||||||
|
}
|
11
typescript/og-website/src/components/Blog.ts
Normal file
11
typescript/og-website/src/components/Blog.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { html } from '@popeindustries/lit-html-server'
|
||||||
|
import { withCss } from '../helpers/withCss'
|
||||||
|
|
||||||
|
export const Blog = () => html`
|
||||||
|
${withCss('blog')}
|
||||||
|
<div class="full center">
|
||||||
|
<div class="title">
|
||||||
|
This page is still in construction!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
21
typescript/og-website/src/components/Home.ts
Normal file
21
typescript/og-website/src/components/Home.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { html } from '@popeindustries/lit-html-server'
|
||||||
|
import { withCss } from '../helpers/withCss'
|
||||||
|
import { buttons } from '../constants/navButtons'
|
||||||
|
import { UrlConfig } from '../types/UrlConfig'
|
||||||
|
|
||||||
|
export const HomeButton = (config: UrlConfig) => html`
|
||||||
|
<a class="home-button" href=${config.url}>${config.name}</a>
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Home = () => html`
|
||||||
|
${withCss('home')}
|
||||||
|
<div id="home" class="full center">
|
||||||
|
<div id="home-title" class="title">
|
||||||
|
Hello! I'm Matei Adriel!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="home-buttons">
|
||||||
|
${buttons.filter(button => button.name !== 'Home').map(HomeButton)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
24
typescript/og-website/src/components/Layout.ts
Normal file
24
typescript/og-website/src/components/Layout.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { html } from '@popeindustries/lit-html-server'
|
||||||
|
import { withCss } from '../helpers/withCss'
|
||||||
|
import { Nav } from './Nav'
|
||||||
|
import { buttons } from '../constants/navButtons'
|
||||||
|
import { LayoutOptions } from '../types/LayoutOptions'
|
||||||
|
import { ServiceWorker } from './ServiceWorker'
|
||||||
|
|
||||||
|
export const Layout = ({ title, body, url }: LayoutOptions) => html`
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>${title}</title>
|
||||||
|
<base href="/" />
|
||||||
|
${withCss('layout', 'config')}
|
||||||
|
</head>
|
||||||
|
<body class="background">
|
||||||
|
${Nav(buttons, url)}
|
||||||
|
<div id="page-content">${body}</div>
|
||||||
|
|
||||||
|
${ServiceWorker('/static/js/service-worker.js')}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
24
typescript/og-website/src/components/Nav.ts
Normal file
24
typescript/og-website/src/components/Nav.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { TemplateResult, html } from '@popeindustries/lit-html-server'
|
||||||
|
import { withCss } from '../helpers/withCss'
|
||||||
|
import { UrlConfig } from '../types/UrlConfig'
|
||||||
|
|
||||||
|
export const NavButtons = (config: UrlConfig, url: string) => {
|
||||||
|
const className = ['nav-button', config.url === url && 'glow']
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(' ')
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<a class=${className} href=${config.url}>${config.name}</a>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Nav = (buttons: UrlConfig[], url: string) =>
|
||||||
|
html`
|
||||||
|
${withCss('nav')}
|
||||||
|
|
||||||
|
<div id="nav">
|
||||||
|
<div id="nav-buttons">
|
||||||
|
${buttons.map(button => NavButtons(button, url))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
37
typescript/og-website/src/components/Projects.ts
Normal file
37
typescript/og-website/src/components/Projects.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { html } from '@popeindustries/lit-html-server'
|
||||||
|
import { ProjectConfig } from '../types/Project'
|
||||||
|
import { withCss } from '../helpers/withCss'
|
||||||
|
import { projects } from '../constants/projects'
|
||||||
|
|
||||||
|
export const Project = (project: ProjectConfig) => {
|
||||||
|
const style = `background-image: url(/static/assets/${project.thumbail})`
|
||||||
|
return html`
|
||||||
|
<div class="project">
|
||||||
|
<a href=${project.demo || project.docs || project.source}>
|
||||||
|
<div class="project-thumbail background" style=${style}></div>
|
||||||
|
</a>
|
||||||
|
<div class="project-name">${project.name}</div>
|
||||||
|
<div class="project-links">
|
||||||
|
<a class="project-source" href=${project.source}>Source</a>
|
||||||
|
|
||||||
|
${project.demo
|
||||||
|
? html`
|
||||||
|
<a class="project-demo" href=${project.demo}>Demo</a>
|
||||||
|
`
|
||||||
|
: ''}
|
||||||
|
${project.docs
|
||||||
|
? html`
|
||||||
|
<a class="project-demo" href=${project.docs}>Docs</a>
|
||||||
|
`
|
||||||
|
: ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Projects = () => html`
|
||||||
|
${withCss('projects')}
|
||||||
|
<div id="projects" class="full center">
|
||||||
|
${projects.map(Project)}
|
||||||
|
</div>
|
||||||
|
`
|
11
typescript/og-website/src/components/ServiceWorker.ts
Normal file
11
typescript/og-website/src/components/ServiceWorker.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { html } from '@popeindustries/lit-html-server'
|
||||||
|
|
||||||
|
export const ServiceWorker = (url: string) => html`
|
||||||
|
<script>
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
navigator.serviceWorker.register('${url}')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`
|
22
typescript/og-website/src/constants/navButtons.ts
Normal file
22
typescript/og-website/src/constants/navButtons.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { UrlConfig } from '../types/UrlConfig'
|
||||||
|
import { Home } from '../components/Home'
|
||||||
|
import { Projects } from '../components/Projects'
|
||||||
|
import { Blog } from '../components/Blog'
|
||||||
|
|
||||||
|
export const buttons: UrlConfig[] = [
|
||||||
|
{
|
||||||
|
url: '/',
|
||||||
|
name: 'Home',
|
||||||
|
component: Home
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/projects',
|
||||||
|
name: 'Projects',
|
||||||
|
component: Projects
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/blog',
|
||||||
|
name: 'Blog',
|
||||||
|
component: Blog
|
||||||
|
}
|
||||||
|
]
|
22
typescript/og-website/src/constants/projects.ts
Normal file
22
typescript/og-website/src/constants/projects.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { ProjectConfig } from '../types/Project'
|
||||||
|
|
||||||
|
export const projects: ProjectConfig[] = [
|
||||||
|
{
|
||||||
|
name: 'Logic gate simulator',
|
||||||
|
demo: 'https://logic-gate-simulator.herokuapp.com/',
|
||||||
|
source: 'https://github.com/Mateiadrielrafael/logicgatesimulator',
|
||||||
|
thumbail: 'logic.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Visual studio paint',
|
||||||
|
demo: 'https://visual-studio-paint.herokuapp.com/',
|
||||||
|
source: 'https://github.com/Mateiadrielrafael/visual-studio-paint',
|
||||||
|
thumbail: 'paint.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Reix',
|
||||||
|
docs: 'https://mateiadrielrafael.github.io/reix/',
|
||||||
|
source: 'https://github.com/Mateiadrielrafael/reix',
|
||||||
|
thumbail: 'gears.jpg'
|
||||||
|
}
|
||||||
|
]
|
16
typescript/og-website/src/helpers/renderComponent.ts
Normal file
16
typescript/og-website/src/helpers/renderComponent.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { TemplateResult, renderToStream } from '@popeindustries/lit-html-server'
|
||||||
|
import { LayoutOptions } from '../types/LayoutOptions'
|
||||||
|
import { Response } from 'express'
|
||||||
|
|
||||||
|
export const createComponentRenderer = (
|
||||||
|
layout: (options: LayoutOptions) => TemplateResult,
|
||||||
|
name: string
|
||||||
|
) => (res: Response, { body, title, url }: LayoutOptions) => {
|
||||||
|
renderToStream(
|
||||||
|
layout({
|
||||||
|
body,
|
||||||
|
url,
|
||||||
|
title: `${name} | ${title}`
|
||||||
|
})
|
||||||
|
).pipe(res)
|
||||||
|
}
|
12
typescript/og-website/src/helpers/withCss.ts
Normal file
12
typescript/og-website/src/helpers/withCss.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { html } from '@popeindustries/lit-html-server'
|
||||||
|
|
||||||
|
export const withCss = (...names: string[]) =>
|
||||||
|
names.map(
|
||||||
|
name => html`
|
||||||
|
<link
|
||||||
|
type="text/css"
|
||||||
|
rel="stylesheet"
|
||||||
|
href=${`static/css/${name}.css`}
|
||||||
|
/>
|
||||||
|
`
|
||||||
|
)
|
30
typescript/og-website/src/index.ts
Normal file
30
typescript/og-website/src/index.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import express from 'express'
|
||||||
|
import { Layout } from './components/Layout'
|
||||||
|
import { resolve } from 'path'
|
||||||
|
import { createPageMiddlewareFactory } from './middleware/servePage'
|
||||||
|
import { buttons } from './constants/navButtons'
|
||||||
|
import { config } from 'dotenv'
|
||||||
|
|
||||||
|
config()
|
||||||
|
|
||||||
|
const port = Number(process.env.PORT) || 8080
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
const renderComponent = createPageMiddlewareFactory(Layout, 'Matei Adriel')
|
||||||
|
|
||||||
|
app.use('/static', express.static(resolve(__dirname, 'static')))
|
||||||
|
|
||||||
|
for (const button of buttons) {
|
||||||
|
app.get(
|
||||||
|
button.url,
|
||||||
|
renderComponent({
|
||||||
|
body: button.component(),
|
||||||
|
title: button.name,
|
||||||
|
url: button.url
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Listening on port ${port}`)
|
||||||
|
})
|
16
typescript/og-website/src/middleware/servePage.ts
Normal file
16
typescript/og-website/src/middleware/servePage.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { Request, Response } from 'express'
|
||||||
|
import { createComponentRenderer } from '../helpers/renderComponent'
|
||||||
|
import { LayoutOptions } from '../types/LayoutOptions'
|
||||||
|
|
||||||
|
export const createPageMiddlewareFactory = (
|
||||||
|
...args: Parameters<typeof createComponentRenderer>
|
||||||
|
) => {
|
||||||
|
const renderComponent = createComponentRenderer(...args)
|
||||||
|
return (config: LayoutOptions) => (
|
||||||
|
request: Request,
|
||||||
|
response: Response
|
||||||
|
) => {
|
||||||
|
console.log(`Serving page ${config.title}`)
|
||||||
|
renderComponent(response, config)
|
||||||
|
}
|
||||||
|
}
|
BIN
typescript/og-website/src/static/assets/gears.jpg
Normal file
BIN
typescript/og-website/src/static/assets/gears.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
typescript/og-website/src/static/assets/logic.jpg
Normal file
BIN
typescript/og-website/src/static/assets/logic.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 439 KiB |
BIN
typescript/og-website/src/static/assets/paint.jpg
Normal file
BIN
typescript/og-website/src/static/assets/paint.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 KiB |
0
typescript/og-website/src/static/css/blog.css
Normal file
0
typescript/og-website/src/static/css/blog.css
Normal file
25
typescript/og-website/src/static/css/config.css
Normal file
25
typescript/og-website/src/static/css/config.css
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
:root {
|
||||||
|
--spacing: 1rem;
|
||||||
|
--on-raised: white;
|
||||||
|
--bg-raised: #444444;
|
||||||
|
--nav-bg: rgba(79, 79, 79, 0.3);
|
||||||
|
--on-bg: white;
|
||||||
|
--title-font: 'Permanent Marker', cursive;
|
||||||
|
--home-bg: url(https://i.pinimg.com/originals/52/28/c1/5228c1ca678bf00fb3996bf9fa1c54b1.jpg);
|
||||||
|
--glow-color-1: white;
|
||||||
|
--glow-color-2: cyan;
|
||||||
|
--glow-color-3: blue;
|
||||||
|
--transition-duration: 1s;
|
||||||
|
--project-var-multiplier: 3;
|
||||||
|
--project-thumbail-scale: 1.1;
|
||||||
|
--project-thumbail-size: 200px;
|
||||||
|
--title-font-size: 7vw;
|
||||||
|
--font-size: 3vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
:root {
|
||||||
|
--title-font-size: 3rem;
|
||||||
|
--font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
}
|
17
typescript/og-website/src/static/css/home.css
Normal file
17
typescript/og-website/src/static/css/home.css
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
div#home-title {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: var(--spacing, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.home-button {
|
||||||
|
background-color: rgba(128, 128, 128, 0.5);
|
||||||
|
padding: var(--spacing, 1rem);
|
||||||
|
border-radius: var(--spacing, 1rem);
|
||||||
|
font-size: var(--font-size, 1em);
|
||||||
|
font-family: var(--title-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
div#home-buttons {
|
||||||
|
padding: var(--spacing, 0.5rem);
|
||||||
|
}
|
32
typescript/og-website/src/static/css/layout.css
Normal file
32
typescript/og-website/src/static/css/layout.css
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Permanent+Marker&display=swap');
|
||||||
|
@import './utility.css';
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
color: var(--on-bg, black);
|
||||||
|
}
|
||||||
|
|
||||||
|
div#page-content {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
color: var(--on-bg, black);
|
||||||
|
padding: var(--spacing, 1rem);
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: calc(2 * var(--font-size, 1em) + 4 * var(--spacing, 1rem));
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-image: var(--home-bg);
|
||||||
|
}
|
30
typescript/og-website/src/static/css/nav.css
Normal file
30
typescript/og-website/src/static/css/nav.css
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
div#nav {
|
||||||
|
width: 100%;
|
||||||
|
padding: var(--spacing, 1rem);
|
||||||
|
position: fixed;
|
||||||
|
font-size: var(--font-size);
|
||||||
|
background-color: var(--nav-bg);
|
||||||
|
filter: hue-rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
div#nav-buttons {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-button {
|
||||||
|
margin: var(--spacing, 1rem);
|
||||||
|
font-family: var(--title-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.nav-button:hover {
|
||||||
|
animation: glow var(--transition-ruration, 1s) ease-in-out infinite
|
||||||
|
alternate;
|
||||||
|
--glow-color-3: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
div#nav {
|
||||||
|
background-color: transparent;
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
}
|
54
typescript/og-website/src/static/css/projects.css
Normal file
54
typescript/og-website/src/static/css/projects.css
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
div.project-thumbail {
|
||||||
|
width: var(--project-thumbail-size, 100px);
|
||||||
|
height: var(--project-thumbail-size, 100px);
|
||||||
|
display: block;
|
||||||
|
transition: transform
|
||||||
|
calc(var(--transition-duration) / var(--project-var-multiplier, 3)),
|
||||||
|
border-radius
|
||||||
|
calc(var(--transition-duration) / var(--project-var-multiplier, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project-thumbail:hover {
|
||||||
|
transform: scale(
|
||||||
|
var(--project-thumbail-scale, 1),
|
||||||
|
var(--project-thumbail-scale, 1)
|
||||||
|
);
|
||||||
|
border-radius: calc(
|
||||||
|
var(--spacing, 1rem) / var(--project-var-multiplier, 3)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project {
|
||||||
|
background-color: var(--bg-raised, black);
|
||||||
|
margin: var(--spacing, 1rem);
|
||||||
|
border-radius: var(--spacing, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project > * {
|
||||||
|
margin: var(--spacing, 1rem);
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project-name {
|
||||||
|
border-bottom: 1px solid #777777;
|
||||||
|
padding-bottom: var(--spacing, 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project-links {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#projects {
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-family: var(--title-font);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project-links *:hover {
|
||||||
|
animation: glow var(--transition-ruration, 1s) ease-in-out infinite
|
||||||
|
alternate;
|
||||||
|
}
|
49
typescript/og-website/src/static/css/utility.css
Normal file
49
typescript/og-website/src/static/css/utility.css
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
.background {
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glow {
|
||||||
|
animation: glow var(--transition-ruration, 1s) ease-in-out infinite
|
||||||
|
alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes glow {
|
||||||
|
from {
|
||||||
|
text-shadow: 0 0 10px var(--glow-color-1, white),
|
||||||
|
0 0 20px var(--glow-color-1, white),
|
||||||
|
0 0 30px var(--glow-color-2, white),
|
||||||
|
0 0 40px var(--glow-color-2, white),
|
||||||
|
0 0 50px var(--glow-color-2, white),
|
||||||
|
0 0 60px var(--glow-color-2, white),
|
||||||
|
0 0 70px var(--glow-color-2, white);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
text-shadow: 0 0 20px var(--glow-color-1, white),
|
||||||
|
0 0 30px var(--glow-color-3, white),
|
||||||
|
0 0 40px var(--glow-color-3, white),
|
||||||
|
0 0 50px var(--glow-color-3, white),
|
||||||
|
0 0 60px var(--glow-color-3, white),
|
||||||
|
0 0 70px var(--glow-color-3, white),
|
||||||
|
0 0 80px var(--glow-color-3, white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: var(--title-font-size, 1em);
|
||||||
|
font-family: var(--title-font);
|
||||||
|
text-align: center;
|
||||||
|
}
|
45
typescript/og-website/src/static/js/service-worker.js
Normal file
45
typescript/og-website/src/static/js/service-worker.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
importScripts(
|
||||||
|
'https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'
|
||||||
|
)
|
||||||
|
|
||||||
|
if (workbox) {
|
||||||
|
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
|
||||||
|
workbox.routing.registerRoute(
|
||||||
|
/^https:\/\/fonts\.googleapis\.com/,
|
||||||
|
new workbox.strategies.StaleWhileRevalidate({
|
||||||
|
cacheName: 'google-fonts-stylesheets'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cache the underlying font files with a cache-first strategy for 1 year.
|
||||||
|
workbox.routing.registerRoute(
|
||||||
|
/^https:\/\/fonts\.gstatic\.com/,
|
||||||
|
new workbox.strategies.CacheFirst({
|
||||||
|
cacheName: 'google-fonts-webfonts',
|
||||||
|
plugins: [
|
||||||
|
new workbox.cacheableResponse.Plugin({
|
||||||
|
statuses: [0, 200]
|
||||||
|
}),
|
||||||
|
new workbox.expiration.Plugin({
|
||||||
|
maxAgeSeconds: 60 * 60 * 24 * 365,
|
||||||
|
maxEntries: 30
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
workbox.routing.registerRoute(
|
||||||
|
/\.(?:png|gif|jpg|jpeg|webp|svg)$/,
|
||||||
|
new workbox.strategies.CacheFirst({
|
||||||
|
cacheName: 'images',
|
||||||
|
plugins: [
|
||||||
|
new workbox.expiration.Plugin({
|
||||||
|
maxEntries: 60,
|
||||||
|
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 Days
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
console.log(`Boo! Workbox didn't load 😬`)
|
||||||
|
}
|
7
typescript/og-website/src/types/LayoutOptions.ts
Normal file
7
typescript/og-website/src/types/LayoutOptions.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { TemplateResult } from '@popeindustries/lit-html-server'
|
||||||
|
|
||||||
|
export interface LayoutOptions {
|
||||||
|
title: string
|
||||||
|
url: string
|
||||||
|
body: TemplateResult | string
|
||||||
|
}
|
7
typescript/og-website/src/types/Project.ts
Normal file
7
typescript/og-website/src/types/Project.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export interface ProjectConfig {
|
||||||
|
name: string
|
||||||
|
source: string
|
||||||
|
demo?: string
|
||||||
|
docs?: string
|
||||||
|
thumbail: string
|
||||||
|
}
|
7
typescript/og-website/src/types/UrlConfig.ts
Normal file
7
typescript/og-website/src/types/UrlConfig.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { TemplateResult } from '@popeindustries/lit-html-server'
|
||||||
|
|
||||||
|
export interface UrlConfig {
|
||||||
|
url: string
|
||||||
|
name: string
|
||||||
|
component: () => TemplateResult
|
||||||
|
}
|
7
typescript/og-website/tsconfig.json
Normal file
7
typescript/og-website/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"target": "esnext",
|
||||||
|
"moduleResolution": "node"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue