move to svelte kit

This commit is contained in:
2021-08-02 09:53:08 +02:00
parent d8e58997e4
commit b1540a7600
64 changed files with 1485 additions and 2895 deletions

View File

@@ -1,22 +1,25 @@
<script>
<script lang="ts">
import { onMount } from 'svelte'
import { stores } from '@sapper/app'
import { page } from '$app/stores'
import { scroll } from '../lib/scroll'
import Nav from '../components/Nav.svelte'
import Progress from '../components/Progress.svelte'
import '../app.css'
export let segment
let wrapper
let main
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat.js'
dayjs.extend(customParseFormat)
import { scroll } from '$lib/stores'
import Nav from '$lib/components/Nav.svelte'
import Progress from '$lib/components/Progress.svelte'
let wrapper: HTMLDivElement
let main: HTMLDivElement
function resize() {
wrapper.style.height = `${window.innerHeight}px`
}
const { page } = stores()
let last = ''
$: {
const { host, path } = $page
const full = host + path
@@ -26,25 +29,25 @@
}
}
function updateScroll(e) {
function updateScroll(e: any) {
const el = e.target
const percentage = el.scrollTop / (el.scrollHeight - el.offsetHeight)
scroll.set(isNaN(percentage) ? 0 : percentage)
}
onMount(() => {
const resizeFN = window.addEventListener('resize', resize, false)
const scrollFN = main.addEventListener('scroll', updateScroll, false)
window.addEventListener('resize', resize, false)
main.addEventListener('scroll', updateScroll, false)
resize()
return () => {
window.removeEventListener(resizeFN)
main.removeEventListener(scrollFN)
window.removeEventListener('resize', resize)
main.removeEventListener('scroll', updateScroll)
}
})
</script>
<div bind:this={wrapper}>
<Nav {segment} />
<Nav />
<main bind:this={main}>
<slot />
</main>

View File

@@ -1,28 +0,0 @@
<script>
export let status
export let error
const dev = process.env.NODE_ENV === 'development'
</script>
<style>
h1 {
font-size: 8vw;
}
p {
margin: 1em auto;
}
</style>
<svelte:head>
<title>{status}</title>
</svelte:head>
<h1>{status}</h1>
<p>{error.message}</p>
{#if dev && error.stack}
<pre>{error.stack}</pre>
{/if}

View File

@@ -1,16 +1,37 @@
<script context="module">
export async function preload() {
return this.fetch('/api/pages/about.json').then((res) => res.json())
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const prerender = true
export const load: Load = async ({ fetch }) => {
return {
props: {
data: await fetch('/api/pages/about.json').then((r) => r.json()),
image: await fetch('/api/media/about-2.json').then((r) => r.json()),
},
}
}
</script>
<script>
import WPAdapter from '../components/WPAdapter.svelte'
import SimplePage from '../components/SimplePage.svelte'
<script lang="ts">
import WPAdapter from '$lib/components/WPAdapter.svelte'
import SimplePage from '$lib/components/SimplePage.svelte'
import type { Page, MediaItem } from '$lib/api'
export let data
export let data: Page
export let image: MediaItem
</script>
<svelte:head>
<title>{data.title}</title>
</svelte:head>
<SimplePage title={data.title} expanded={false}>
{#if data.content}
<WPAdapter content={data.content} />
<img srcset={image.srcSet} alt="decoration" />
{/if}
</SimplePage>
<style>
img {
position: absolute;
@@ -34,13 +55,3 @@
}
}
</style>
<svelte:head>
<title>About</title>
</svelte:head>
<SimplePage title="About" expanded={false}>
<WPAdapter content={data.content} />
<!-- {@html data.content} -->
<img src="/images/about.jpg" alt="decoration" />
</SimplePage>

View File

@@ -1,13 +0,0 @@
import { respond, getAll, getOne, sortByDate } from '../../lib/wp'
export async function get(req, res) {
const [type, slug] = req.params.slug
if (slug) {
const data = await getOne(type, { slug })
respond(res, { data })
} else {
const data = await getAll(type)
respond(res, { data: sortByDate(data) })
}
}

View File

@@ -0,0 +1,116 @@
import type { RequestHandler } from '@sveltejs/kit'
import { Call, gql, MediaItem, Page, Project } from '$lib/api'
export const get: RequestHandler = async (args) => {
const { type, slug } = args.params
const allChar = '*'
const all = slug === allChar
switch (type) {
case 'pages': {
if (all) {
const data = await Call<{ pages: { nodes: Page[] } }>(gql`
query {
pages {
nodes {
title
content
slug
status
id
}
}
}
`)
return { body: data.pages.nodes }
} else {
const data = await Call<{ page: Page }>(
gql`
query ($slug: ID!) {
page(id: $slug, idType: URI) {
title
content
slug
status
id
}
}
`,
{ slug: '/' + slug }
)
return { body: data.page }
}
}
case 'works': {
if (all) {
const data = await Call<{ works: { nodes: MediaItem[] } }>(gql`
query {
works {
nodes {
id
title
content
slug
status
work {
date
image {
sourceUrl
srcSet
altText
}
link
role
}
}
}
}
`)
return { body: data.works.nodes }
} else {
}
}
case 'projects': {
if (all) {
const data = await Call<{ projects: { nodes: Project[] } }>(gql`
query {
projects {
nodes {
id
title
content
slug
status
project {
date
description
link
}
}
}
}
`)
return { body: data.projects.nodes }
}
}
case 'media': {
const data = await Call<{ mediaItem: MediaItem }>(
gql`
query ($slug: ID!) {
mediaItem(id: $slug, idType: SLUG) {
srcSet
altText
sourceUrl
}
}
`,
{ slug }
)
return { body: data.mediaItem }
}
default:
return { status: 404 }
}
}

View File

@@ -1,20 +0,0 @@
<script context="module">
export async function preload({ params }) {
return this.fetch(`/api/posts/${params.slug}.json`).then((res) =>
res.json()
)
}
</script>
<script>
import SimplePage from '../../components/SimplePage.svelte'
import WPAdapter from '../../components/WPAdapter.svelte'
import PostAttributes from '../../components/PostAttributes.svelte'
export let data
</script>
<SimplePage title={data.title} expanded={false} readable>
<PostAttributes post={data} full />
<WPAdapter content={data.content} />
</SimplePage>

View File

@@ -1,45 +0,0 @@
<script context="module">
export async function preload(page) {
return this.fetch('/api/posts.json').then((res) => res.json())
}
</script>
<script>
import { onMount } from 'svelte'
import SimplePage from '../../components/SimplePage.svelte'
import PostPreview from '../../components/PostPreview.svelte'
export let data
export let redirected = false
onMount(() => {
redirected = new URL(location.href).searchParams.has('old')
})
</script>
<style>
div {
margin-bottom: 6em;
background-color: var(--clr-error);
padding: 1em;
}
</style>
<svelte:head>
<title>Blog</title>
</svelte:head>
<SimplePage title="Blog">
{#if redirected}
<div>
<h2>You have been redirected 🔄</h2>
<p>
Probably you are coming form my old blog (blog.nicco.io)
<br />
The article you were looking for is down here 👇
</p>
</div>
{/if}
{#each data as post}
<PostPreview {post} />
{/each}
</SimplePage>

View File

@@ -1,7 +1,6 @@
<script>
import IconList from '../components/IconList.svelte'
import SimplePage from '../components/SimplePage.svelte'
<script lang="ts">
import IconList from '$lib/components/IconList.svelte'
import SimplePage from '$lib/components/SimplePage.svelte'
const links = [
{

View File

@@ -1,72 +1,111 @@
<script>
import SpacedLetters from '../components/SpacedLetters.svelte'
<script lang="ts" context="module">
import { Call, gql } from '$lib/api'
export const prerender = true
type Data = Record<'signature' | 'home', { srcSet: string }>
export const load: Load = async () => {
const data = await Call<Data>(gql`
query {
signature: mediaItem(id: "signature", idType: SLUG) {
srcSet
}
home: mediaItem(id: "home", idType: SLUG) {
srcSet
}
}
`)
return { props: { data } }
}
</script>
<script lang="ts">
import SpacedLetters from '$lib/components/SpacedLetters.svelte'
import type { Load } from '@sveltejs/kit'
export let data: Data
</script>
<svelte:head>
<title>Niccolo Borgioli</title>
</svelte:head>
<section class="left" style="z-index: 3;">
<h1>
<SpacedLetters letters="Niccolò" even />
<SpacedLetters letters="Borgioli" even />
</h1>
<div class="wrapper">
<div class="left" style="z-index: 3;">
<h1>
<SpacedLetters letters="Niccolò" even />
<SpacedLetters letters="Borgioli" even />
</h1>
<p>Design & Development</p>
</section>
<p>Design & Development</p>
</div>
<section class="right" style="z-index: 2;">
<picture>
<source media="(min-width: 60em)" srcset="/images/home@1500.webp" />
<source media="(min-width: 45em)" srcset="/images/home@1000.webp" />
<source srcset="/images/home@500.webp" />
<img src="/images/decoration.jpg" alt="decoration" />
</picture>
</section>
<div class="right" style="z-index: 2;">
<img srcset={data.home.srcSet} alt="decoration" class="home" />
<img srcset={data.signature.srcSet} alt="signature" class="signature" />
</div>
</div>
<style>
p {
font-size: 4vw;
margin-top: 0;
}
section {
.wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 1rem;
}
section.left {
align-items: flex-start;
padding-left: 1em;
width: initial;
.left {
flex: 1 0 auto;
max-width: 64vw;
}
section.right {
align-items: flex-end;
.right {
position: relative;
top: 5vh;
}
img {
p {
font-size: 4vw;
margin: 0;
}
img.home {
width: min(100%, 33vw);
object-fit: contain;
height: 65vh;
width: 33vw;
transform: translateY(5vh);
object-position: left;
max-height: 65vh;
}
img.signature {
position: absolute;
width: 50%;
top: -6%;
left: -10%;
transform: rotate(-8deg);
}
@media (max-width: 50em) {
img {
transform: translateY(15vh);
height: 60vh;
width: 69vw;
.wrapper {
flex-direction: column;
}
section.left {
transform: translateY(-25vh);
.left {
flex: initial;
}
.right {
left: 1rem;
}
img.home {
width: auto;
height: 100%;
max-height: calc(90vh - 35vw - 5vh);
max-width: 90%;
}
}
</style>

View File

@@ -1,16 +1,30 @@
<script context="module">
export async function preload() {
return this.fetch('/api/pages/privacy.json').then((res) => res.json())
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const prerender = true
export const load: Load = async ({ fetch }) => {
return {
props: {
data: await fetch('/api/pages/privacy.json').then((r) => r.json()),
},
}
}
</script>
<script>
import WPAdapter from '../components/WPAdapter.svelte'
import SimplePage from '../components/SimplePage.svelte'
<script lang="ts">
import WPAdapter from '$lib/components/WPAdapter.svelte'
import SimplePage from '$lib/components/SimplePage.svelte'
import type { Page } from '$lib/api'
export let data
export let data: Page
</script>
<SimplePage title="Privacy Policy">
<WPAdapter content={data.content} />
<svelte:head>
<title>{data.title}</title>
</svelte:head>
<SimplePage title={data.title} expanded={false}>
{#if data.content}
<WPAdapter content={data.content} />
{/if}
</SimplePage>

View File

@@ -1,14 +1,21 @@
<script context="module">
export async function preload() {
return this.fetch('/api/projects.json').then((res) => res.json())
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const load: Load = async ({ fetch }) => {
return {
props: {
data: await fetch('/api/projects/*.json').then((r) => r.json()),
},
}
}
</script>
<script lang="ts">
import SimplePage from '../components/SimplePage.svelte'
import Project from '../components/Project.svelte'
import type { Project as TProject } from '$lib/api'
import SimplePage from '$lib/components/SimplePage.svelte'
import Project from '$lib/components/Project.svelte'
export let data
export let data: TProject[]
</script>
<svelte:head>

View File

@@ -1,34 +0,0 @@
import lunr from 'lunr'
import { getAll } from '../lib/wp'
function removeHTML(s) {
return s.replace(/<.*?>|\s+|&#\d+;/g, ' ').trim()
}
async function convertForIdx(type, fields = []) {
const items = await getAll(type)
const keys = ['title', 'content', 'slug', ...fields]
return items.map((item) => ({
url: `${item.type}/${item.slug}`,
data: keys.map((field) => removeHTML(item[field])).join(' '),
}))
}
export async function get(req, res) {
const all = await Promise.all([
convertForIdx('projects', ['description']),
convertForIdx('pages'),
convertForIdx('posts'),
convertForIdx('works', ['role']),
])
const idx = lunr(function () {
this.ref('url')
this.field('data')
all.flat().forEach((doc) => this.add(doc))
})
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(idx))
}

View File

@@ -1,70 +0,0 @@
<script context="module">
export async function preload({ query }) {
const prebuilt = await this.fetch(`/search.json`).then((res) => res.json())
return { prebuilt }
}
</script>
<script>
import lunr from 'lunr'
import { onMount } from 'svelte'
import SearchResult from '../components/SearchResult.svelte'
import SimplePage from '../components/SimplePage.svelte'
export let prebuilt
let needle
let results = []
const idx = lunr.Index.load(prebuilt)
async function search(needle) {
if (!needle || !idx) {
results = []
} else {
let found = idx.search(needle + '~1')
if (!found.length) found = idx.search(needle + '*')
results = found.slice(0, 20)
}
}
$: if (needle) {
if (typeof window !== 'undefined') {
window.history.replaceState(null, null, `/search?q=${needle || ''}`)
}
search(needle)
}
onMount(() => {
needle = new URLSearchParams(window.location.search).get('q')
})
</script>
<SimplePage title="Search" expanded={false}>
<input bind:value={needle} placeholder="needle" />
<ul>
{#each results as result (result.ref)}
<SearchResult {result} />
{/each}
</ul>
</SimplePage>
<style>
input {
appearance: none;
-webkit-appearance: none;
margin: 0;
padding: 0.5rem;
font-size: 1em;
width: 100%;
outline: none;
border: 2px solid var(--clr-primary);
border-radius: 0;
}
ul {
margin-top: 2em;
list-style: none;
padding: 0;
}
</style>

View File

@@ -1,7 +1,6 @@
<script>
import IconList from '../components/IconList.svelte'
import SimplePage from '../components/SimplePage.svelte'
<script lang="ts">
import IconList from '$lib/components/IconList.svelte'
import SimplePage from '$lib/components/SimplePage.svelte'
const links = [
{

View File

@@ -1,14 +1,21 @@
<script context="module">
export async function preload() {
return this.fetch('/api/works.json').then((res) => res.json())
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const load: Load = async ({ fetch }) => {
return {
props: {
data: await fetch('/api/works/*.json').then((r) => r.json()),
},
}
}
</script>
<script>
import SimplePage from '../components/SimplePage.svelte'
import Work from '../components/Work.svelte'
<script lang="ts">
import type { Work as TWork } from '$lib/api'
import SimplePage from '$lib/components/SimplePage.svelte'
import Work from '$lib/components/Work.svelte'
export let data
export let data: TWork[]
</script>
<svelte:head>