mirror of
https://github.com/cupcakearmy/nicco.io.git
synced 2025-09-06 02:30:45 +00:00
move to svelte kit
This commit is contained in:
@@ -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>
|
@@ -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}
|
@@ -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>
|
||||
|
@@ -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) })
|
||||
}
|
||||
}
|
116
src/routes/api/[type]/[slug].json.ts
Normal file
116
src/routes/api/[type]/[slug].json.ts
Normal 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 }
|
||||
}
|
||||
}
|
@@ -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>
|
@@ -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>
|
@@ -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 = [
|
||||
{
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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))
|
||||
}
|
@@ -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>
|
@@ -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 = [
|
||||
{
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user