mirror of
https://github.com/cupcakearmy/nicco.io.git
synced 2024-12-22 08:06:29 +00:00
progress
This commit is contained in:
parent
0f8c58d182
commit
170d61dd96
@ -36,7 +36,7 @@ export type Page = {
|
|||||||
status: string
|
status: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BaseAttributes = gql`
|
export const BaseAttributes = `
|
||||||
id
|
id
|
||||||
slug
|
slug
|
||||||
status
|
status
|
||||||
@ -44,6 +44,27 @@ export const BaseAttributes = gql`
|
|||||||
content
|
content
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export interface Post extends Page {
|
||||||
|
date: string
|
||||||
|
modified: string
|
||||||
|
post: {
|
||||||
|
featured: MediaItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PostFragment = gql`
|
||||||
|
fragment PostFragment on Post {
|
||||||
|
${BaseAttributes}
|
||||||
|
date
|
||||||
|
modified
|
||||||
|
post {
|
||||||
|
featured {
|
||||||
|
...MediaItemFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export interface Work extends Page {
|
export interface Work extends Page {
|
||||||
work: {
|
work: {
|
||||||
date: string
|
date: string
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<script>
|
<script lang="ts">
|
||||||
import dj from 'dayjs'
|
import dj from 'dayjs'
|
||||||
import { readingTimeInMinutes } from '../lib/readingTime'
|
import type { Post } from '$lib/api'
|
||||||
|
import { readingTimeInMinutes } from '$lib/utils'
|
||||||
|
|
||||||
export let post
|
export let post: Post
|
||||||
export let full = false
|
export let full = false
|
||||||
|
|
||||||
function format(date) {
|
function format(date: string) {
|
||||||
return dj(date).format('MMM D, YYYY')
|
return dj(date).format('MMM D, YYYY')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,6 +14,16 @@
|
|||||||
$: modified = format(post.modified)
|
$: modified = format(post.modified)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="attributes">
|
||||||
|
<div>
|
||||||
|
{created}
|
||||||
|
{#if full && created !== modified}<br /> <small>Last update: {modified}</small>{/if}
|
||||||
|
</div>
|
||||||
|
{#if post.content}
|
||||||
|
<div>~ {readingTimeInMinutes(post.content)} min</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.attributes {
|
.attributes {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -21,11 +32,3 @@
|
|||||||
margin-top: -0.125em;
|
margin-top: -0.125em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="attributes">
|
|
||||||
<div>
|
|
||||||
{created}
|
|
||||||
{#if full && created !== modified}<br /> <small>Last update: {modified}</small>{/if}
|
|
||||||
</div>
|
|
||||||
<div>~ {readingTimeInMinutes(post.content)} min</div>
|
|
||||||
</div>
|
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
<script>
|
<script lang="ts">
|
||||||
|
import type { Post } from '$lib/api'
|
||||||
|
|
||||||
import ImageFrame from '../components/ImageFrame.svelte'
|
import ImageFrame from '../components/ImageFrame.svelte'
|
||||||
import PostAttributes from '../components/PostAttributes.svelte'
|
import PostAttributes from '../components/PostAttributes.svelte'
|
||||||
|
|
||||||
export let post
|
export let post: Post
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<a href={`blog/${post.slug}`} class:without={!post.post.featured}>
|
||||||
|
{#if post.post.featured}
|
||||||
|
<ImageFrame src={post.post.featured.sourceUrl} alt={post.post.featured.altText} />
|
||||||
|
{/if}
|
||||||
|
<PostAttributes {post} />
|
||||||
|
<h2>
|
||||||
|
{@html post.title}
|
||||||
|
</h2>
|
||||||
|
</a>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
display: block;
|
display: block;
|
||||||
@ -41,13 +53,3 @@
|
|||||||
transform: translateX(-5%);
|
transform: translateX(-5%);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<a href={`blog/${post.slug}`} class:without={!post.featured}>
|
|
||||||
{#if post.featured}
|
|
||||||
<ImageFrame src={post.featured.url} alt={post.featured.description} />
|
|
||||||
{/if}
|
|
||||||
<PostAttributes {post} />
|
|
||||||
<h2>
|
|
||||||
{@html post.title}
|
|
||||||
</h2>
|
|
||||||
</a>
|
|
||||||
|
5
src/lib/utils.ts
Normal file
5
src/lib/utils.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function readingTimeInMinutes(text: string, options: { wpm?: number } = {}): number {
|
||||||
|
const cleaned = text.replace(/(<.*?>)|(\\n)|(&#\d*?;)/g, '')
|
||||||
|
const words = cleaned.split(' ').length
|
||||||
|
return Math.round(words / (options.wpm ?? 200))
|
||||||
|
}
|
@ -7,6 +7,8 @@ import {
|
|||||||
MediaItem,
|
MediaItem,
|
||||||
MediaItemFragment,
|
MediaItemFragment,
|
||||||
Page,
|
Page,
|
||||||
|
Post,
|
||||||
|
PostFragment,
|
||||||
Project,
|
Project,
|
||||||
ProjectFragment,
|
ProjectFragment,
|
||||||
WorkFragment,
|
WorkFragment,
|
||||||
@ -22,7 +24,7 @@ export const get: RequestHandler = async (args) => {
|
|||||||
if (all) {
|
if (all) {
|
||||||
const data = await Call<{ pages: { nodes: Page[] } }>(gql`
|
const data = await Call<{ pages: { nodes: Page[] } }>(gql`
|
||||||
query {
|
query {
|
||||||
pages {
|
pages(where: {status: PUBLISH}) {
|
||||||
nodes {
|
nodes {
|
||||||
${BaseAttributes}
|
${BaseAttributes}
|
||||||
}
|
}
|
||||||
@ -50,7 +52,7 @@ export const get: RequestHandler = async (args) => {
|
|||||||
${MediaItemFragment}
|
${MediaItemFragment}
|
||||||
${WorkFragment}
|
${WorkFragment}
|
||||||
query {
|
query {
|
||||||
works {
|
works(where: { status: PUBLISH }) {
|
||||||
nodes {
|
nodes {
|
||||||
...WorkFragment
|
...WorkFragment
|
||||||
}
|
}
|
||||||
@ -81,7 +83,7 @@ export const get: RequestHandler = async (args) => {
|
|||||||
gql`
|
gql`
|
||||||
${ProjectFragment}
|
${ProjectFragment}
|
||||||
query {
|
query {
|
||||||
projects {
|
projects(where: { status: PUBLISH }) {
|
||||||
nodes {
|
nodes {
|
||||||
...ProjectFragment
|
...ProjectFragment
|
||||||
}
|
}
|
||||||
@ -120,6 +122,38 @@ export const get: RequestHandler = async (args) => {
|
|||||||
)
|
)
|
||||||
return { body: data.mediaItem }
|
return { body: data.mediaItem }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'posts': {
|
||||||
|
if (all) {
|
||||||
|
const data = await Call<{ posts: { nodes: Post[] } }>(gql`
|
||||||
|
${PostFragment}
|
||||||
|
${MediaItemFragment}
|
||||||
|
{
|
||||||
|
posts(where: { status: PUBLISH }, first: 1000000000) {
|
||||||
|
nodes {
|
||||||
|
...PostFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
return { body: data.posts.nodes }
|
||||||
|
} else {
|
||||||
|
const data = await Call<{ post: Post }>(
|
||||||
|
gql`
|
||||||
|
${PostFragment}
|
||||||
|
${MediaItemFragment}
|
||||||
|
query ($slug: ID!) {
|
||||||
|
post(id: $slug, idType: SLUG) {
|
||||||
|
...PostFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ slug }
|
||||||
|
)
|
||||||
|
return { body: data.post }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return { status: 404 }
|
return { status: 404 }
|
||||||
}
|
}
|
||||||
|
32
src/routes/blog/[slug].svelte
Normal file
32
src/routes/blog/[slug].svelte
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
import type { Load } from '@sveltejs/kit'
|
||||||
|
|
||||||
|
export const prerender = true
|
||||||
|
export const load: Load = async ({ fetch, page }) => {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
data: await fetch(`/api/posts/${page.params.slug}.json`).then((r) => r.json()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Post } from '$lib/api'
|
||||||
|
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||||
|
import PostAttributes from '$lib/components/PostAttributes.svelte'
|
||||||
|
import WpAdapter from '$lib/components/WPAdapter.svelte'
|
||||||
|
|
||||||
|
export let data: Post
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Works</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<SimplePage title={data.title}>
|
||||||
|
<PostAttributes post={data} full />
|
||||||
|
{#if data.content}
|
||||||
|
<WpAdapter content={data.content} />
|
||||||
|
{/if}
|
||||||
|
</SimplePage>
|
30
src/routes/blog/index.svelte
Normal file
30
src/routes/blog/index.svelte
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<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/posts/*.json').then((r) => r.json()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Post } from '$lib/api'
|
||||||
|
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||||
|
import PostPreview from '$lib/components/PostPreview.svelte'
|
||||||
|
|
||||||
|
export let data: Post[]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Blog</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<SimplePage title="Works">
|
||||||
|
{#each data as post}
|
||||||
|
<PostPreview {post} />
|
||||||
|
{/each}
|
||||||
|
</SimplePage>
|
@ -1,3 +1,7 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
export const prerender = true
|
||||||
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import IconList from '$lib/components/IconList.svelte'
|
import IconList from '$lib/components/IconList.svelte'
|
||||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import { Call, gql } from '$lib/api'
|
import type { MediaItem } from '$lib/api'
|
||||||
|
|
||||||
export const prerender = true
|
export const prerender = true
|
||||||
|
|
||||||
type Data = Record<'signature' | 'home', { srcSet: string }>
|
type Data = Record<'signature' | 'home', MediaItem>
|
||||||
export const load: Load = async () => {
|
export const load: Load = async ({ fetch }) => {
|
||||||
const data = await Call<Data>(gql`
|
const signature: MediaItem = await fetch('/api/media/signature.json').then((r) => r.json())
|
||||||
query {
|
const home: MediaItem = await fetch('/api/media/home.json').then((r) => r.json())
|
||||||
signature: mediaItem(id: "signature", idType: SLUG) {
|
return { props: { data: { signature, home } } }
|
||||||
srcSet
|
|
||||||
}
|
|
||||||
|
|
||||||
home: mediaItem(id: "home", idType: SLUG) {
|
|
||||||
srcSet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
return { props: { data } }
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -28,7 +19,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Niccolo Borgioli</title>
|
<title>Niccolò Borgioli</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import type { Load } from '@sveltejs/kit'
|
import type { Load } from '@sveltejs/kit'
|
||||||
|
|
||||||
|
export const prerender = true
|
||||||
export const load: Load = async ({ fetch }) => {
|
export const load: Load = async ({ fetch }) => {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
1
src/routes/search.svelte
Normal file
1
src/routes/search.svelte
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hello
|
@ -1,3 +1,7 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
export const prerender = true
|
||||||
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import IconList from '$lib/components/IconList.svelte'
|
import IconList from '$lib/components/IconList.svelte'
|
||||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||||
|
Loading…
Reference in New Issue
Block a user