a lot of stuff
This commit is contained in:
@@ -17,8 +17,6 @@
|
|||||||
"next": "15.0.1",
|
"next": "15.0.1",
|
||||||
"next-sanity": "^9.8.7",
|
"next-sanity": "^9.8.7",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "19.0.0-rc-69d4b800-20241021",
|
|
||||||
"react-dom": "19.0.0-rc-69d4b800-20241021",
|
|
||||||
"react-error-boundary": "^4.1.2",
|
"react-error-boundary": "^4.1.2",
|
||||||
"sanity": "^3.62.2",
|
"sanity": "^3.62.2",
|
||||||
"sass": "^1.80.4",
|
"sass": "^1.80.4",
|
||||||
|
BIN
public/apple-touch-icon.png
Normal file
BIN
public/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
public/favicon-192.png
Normal file
BIN
public/favicon-192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
public/favicon-512.png
Normal file
BIN
public/favicon-512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 4.1 KiB |
24
public/favicon.svg
Normal file
24
public/favicon.svg
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(2.67266,0,0,1.58732,-514.854,-263.167)">
|
||||||
|
<g id="V_Bottom">
|
||||||
|
<path d="M283.682,421.257C286.503,417.769 290.342,417.769 293.163,421.257C297.047,426.059 302.823,433.2 308.573,440.309C311.364,443.76 312.522,449.839 311.443,455.378C310.365,460.918 307.295,464.664 303.833,464.664L273.013,464.664C269.55,464.664 266.48,460.918 265.402,455.378C264.324,449.839 265.482,443.76 268.272,440.309C274.023,433.2 279.798,426.059 283.682,421.257Z" style="fill:rgb(126,202,156);"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(-0.494722,0.814887,2.12457,1.6035,264.087,-12.6695)">
|
||||||
|
<g id="V_Left">
|
||||||
|
<path d="M317.216,77.117C328.725,77.207 337.292,80.426 337.044,84.566C336.754,89.405 336.371,95.79 336.062,100.946C335.924,103.239 333.06,105.502 328.186,107.169C323.311,108.836 316.886,109.749 310.517,109.68C246.197,108.985 74.77,107.131 -0.973,106.313C-8.802,106.228 -15.527,104.676 -18.717,102.217C-21.906,99.758 -21.099,96.749 -16.586,94.277C-6.859,88.949 4.068,82.964 11.218,79.048C16.012,76.422 24.221,74.82 32.546,74.885C82.595,75.277 257.388,76.648 317.216,77.117Z" style="fill:rgb(126,202,156);"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(0.494722,0.814887,-2.12457,1.6035,247.913,-12.6695)">
|
||||||
|
<g id="V_Left1" serif:id="V_Left">
|
||||||
|
<path d="M317.216,77.117C328.725,77.207 337.292,80.426 337.044,84.566C336.754,89.405 336.371,95.79 336.062,100.946C335.924,103.239 333.06,105.502 328.186,107.169C323.311,108.836 316.886,109.749 310.517,109.68C246.197,108.985 74.77,107.131 -0.973,106.313C-8.802,106.228 -15.527,104.676 -18.717,102.217C-21.906,99.758 -21.099,96.749 -16.586,94.277C-6.859,88.949 4.068,82.964 11.218,79.048C16.012,76.422 24.221,74.82 32.546,74.885C82.595,75.277 257.388,76.648 317.216,77.117Z" style="fill:rgb(126,202,156);"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(1.58976,-1.1515e-16,1.08287e-15,2.15833,-28.9816,-126.079)">
|
||||||
|
<g id="V_Top">
|
||||||
|
<path d="M321.069,75.834C328.515,75.834 334.551,80.28 334.551,85.764L334.551,100.196C334.551,102.83 333.13,105.357 330.601,107.219C328.073,109.082 324.643,110.128 321.067,110.128L37.466,110.128C33.887,110.128 30.454,109.081 27.923,107.217C25.392,105.352 23.97,102.824 23.97,100.187L23.97,85.773C23.97,80.284 30.011,75.834 37.464,75.834L321.069,75.834Z" style="fill:rgb(126,202,156);"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
14
public/manifest.webmanifest
Normal file
14
public/manifest.webmanifest
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/favicon-192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/favicon-512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
import { defineQuery, PortableText } from "next-sanity";
|
import { defineQuery, PortableText } from "next-sanity";
|
||||||
import imageUrlBuilder from "@sanity/image-url";
|
import imageUrlBuilder from "@sanity/image-url";
|
||||||
import type { SanityImageSource } from "@sanity/image-url/lib/types/types";
|
import type { SanityImageSource } from "@sanity/image-url/lib/types/types";
|
||||||
import { client, sanityFetch } from "../../sanity/client";
|
import { client, sanityFetch } from "../../../sanity/client";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Post, SanityImageAsset } from "@/sanity/sanity.types";
|
import { Post, SanityImageAsset } from "@/sanity/sanity.types";
|
||||||
@@ -66,8 +66,8 @@ export default async function PostPage(props: { params: PageParams }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="container mx-auto min-h-screen max-w-3xl p-8 flex flex-col gap-4">
|
<main className="container mx-auto min-h-screen max-w-3xl p-8 flex flex-col gap-4">
|
||||||
<Link href="/" className="hover:underline">
|
<Link href="/blog" className="hover:underline">
|
||||||
← Back to posts
|
← Blog
|
||||||
</Link>
|
</Link>
|
||||||
{postImageUrl && (
|
{postImageUrl && (
|
||||||
<Image
|
<Image
|
32
src/app/blog/page.tsx
Normal file
32
src/app/blog/page.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { type SanityDocument } from "next-sanity";
|
||||||
|
|
||||||
|
import { client } from "@/sanity/client";
|
||||||
|
|
||||||
|
const POSTS_QUERY = `*[
|
||||||
|
_type == "post"
|
||||||
|
&& defined(slug.current)
|
||||||
|
]|order(publishedAt desc)[0...12]{_id, title, slug, publishedAt}`;
|
||||||
|
|
||||||
|
const options = { next: { revalidate: 30 } };
|
||||||
|
|
||||||
|
export default async function IndexPage() {
|
||||||
|
const posts = await client.fetch<SanityDocument[]>(POSTS_QUERY, {}, options);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="container mx-auto min-h-screen max-w-3xl p-8">
|
||||||
|
<Link href="/">Home</Link>
|
||||||
|
<h1 className="text-4xl font-bold mb-8">Blog</h1>
|
||||||
|
<ul className="flex flex-col gap-y-4">
|
||||||
|
{posts.map((post) => (
|
||||||
|
<li className="hover:underline" key={post._id}>
|
||||||
|
<Link href={`blog/${post.slug.current}`}>
|
||||||
|
<h2 className="text-xl font-semibold">{post.title}</h2>
|
||||||
|
<p>{new Date(post.publishedAt).toLocaleDateString()}</p>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
@@ -5,7 +5,6 @@ import { draftMode } from "next/headers";
|
|||||||
import { VisualEditing } from 'next-sanity'
|
import { VisualEditing } from 'next-sanity'
|
||||||
import { SanityLive } from '@/sanity/client'
|
import { SanityLive } from '@/sanity/client'
|
||||||
import { LiveErrorBoundary } from "./live-error-boundary";
|
import { LiveErrorBoundary } from "./live-error-boundary";
|
||||||
import { Toaster } from "@/components/ui/sonner";
|
|
||||||
|
|
||||||
const geistSans = localFont({
|
const geistSans = localFont({
|
||||||
src: "../fonts/GeistVF.woff",
|
src: "../fonts/GeistVF.woff",
|
||||||
@@ -27,6 +26,13 @@ export default async function RootLayout({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest" />
|
||||||
|
<title>vaporvee's Website</title>
|
||||||
|
</head>
|
||||||
<body
|
<body
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||||
>
|
>
|
||||||
@@ -35,7 +41,6 @@ export default async function RootLayout({
|
|||||||
<SanityLive />
|
<SanityLive />
|
||||||
</LiveErrorBoundary>
|
</LiveErrorBoundary>
|
||||||
{isEnabled && <VisualEditing />}
|
{isEnabled && <VisualEditing />}
|
||||||
<Toaster />
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
@@ -1,31 +1,26 @@
|
|||||||
|
import type { Home } from "@/sanity/sanity.types";
|
||||||
|
|
||||||
|
import { sanityFetch } from "@/sanity/client";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { type SanityDocument } from "next-sanity";
|
|
||||||
|
|
||||||
import { client } from "@/sanity/client";
|
const HOME_QUERY = `*[_type == "home"]`;
|
||||||
|
|
||||||
const POSTS_QUERY = `*[
|
|
||||||
_type == "post"
|
|
||||||
&& defined(slug.current)
|
|
||||||
]|order(publishedAt desc)[0...12]{_id, title, slug, publishedAt}`;
|
|
||||||
|
|
||||||
const options = { next: { revalidate: 30 } };
|
|
||||||
|
|
||||||
export default async function IndexPage() {
|
export default async function IndexPage() {
|
||||||
const posts = await client.fetch<SanityDocument[]>(POSTS_QUERY, {}, options);
|
const result = await sanityFetch({ query: HOME_QUERY, stega: false });
|
||||||
|
const home: Home | null = result.data.length > 0 ? result.data[0] : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="container mx-auto min-h-screen max-w-3xl p-8">
|
<main className="container mx-auto min-h-screen max-w-3xl p-8">
|
||||||
<h1 className="text-4xl font-bold mb-8">Posts</h1>
|
<Link href="/blog">Blog</Link><br/><br/>
|
||||||
<ul className="flex flex-col gap-y-4">
|
{home ? (
|
||||||
{posts.map((post) => (
|
<>
|
||||||
<li className="hover:underline" key={post._id}>
|
<h1 className="text-4xl font-bold mb-8">{home.title}</h1>
|
||||||
<Link href={`/${post.slug.current}`}>
|
<h2 className="text-2xl font-semibold mb-4">{home.subtitle}</h2>
|
||||||
<h2 className="text-xl font-semibold">{post.title}</h2>
|
</>
|
||||||
<p>{new Date(post.publishedAt).toLocaleDateString()}</p>
|
) : (
|
||||||
</Link>
|
<p></p>
|
||||||
</li>
|
)}
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
@@ -1,31 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useTheme } from "next-themes"
|
|
||||||
import { Toaster as Sonner } from "sonner"
|
|
||||||
|
|
||||||
type ToasterProps = React.ComponentProps<typeof Sonner>
|
|
||||||
|
|
||||||
const Toaster = ({ ...props }: ToasterProps) => {
|
|
||||||
const { theme = "system" } = useTheme()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Sonner
|
|
||||||
theme={theme as ToasterProps["theme"]}
|
|
||||||
className="toaster group"
|
|
||||||
toastOptions={{
|
|
||||||
classNames: {
|
|
||||||
toast:
|
|
||||||
"group toast group-[.toaster]:bg-white group-[.toaster]:text-neutral-950 group-[.toaster]:border-neutral-200 group-[.toaster]:shadow-lg dark:group-[.toaster]:bg-neutral-950 dark:group-[.toaster]:text-neutral-50 dark:group-[.toaster]:border-neutral-800",
|
|
||||||
description: "group-[.toast]:text-neutral-500 dark:group-[.toast]:text-neutral-400",
|
|
||||||
actionButton:
|
|
||||||
"group-[.toast]:bg-neutral-900 group-[.toast]:text-neutral-50 dark:group-[.toast]:bg-neutral-50 dark:group-[.toast]:text-neutral-900",
|
|
||||||
cancelButton:
|
|
||||||
"group-[.toast]:bg-neutral-100 group-[.toast]:text-neutral-500 dark:group-[.toast]:bg-neutral-800 dark:group-[.toast]:text-neutral-400",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Toaster }
|
|
@@ -1,6 +0,0 @@
|
|||||||
import { clsx, type ClassValue } from "clsx"
|
|
||||||
import { twMerge } from "tailwind-merge"
|
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
|
||||||
return twMerge(clsx(inputs))
|
|
||||||
}
|
|
@@ -68,6 +68,96 @@ export type Geopoint = {
|
|||||||
alt?: number
|
alt?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Project = {
|
||||||
|
_id: string
|
||||||
|
_type: 'project'
|
||||||
|
_createdAt: string
|
||||||
|
_updatedAt: string
|
||||||
|
_rev: string
|
||||||
|
title?: string
|
||||||
|
url?: string
|
||||||
|
tools?: Array<{
|
||||||
|
_ref: string
|
||||||
|
_type: 'reference'
|
||||||
|
_weak?: boolean
|
||||||
|
_key: string
|
||||||
|
[internalGroqTypeReferenceTo]?: 'tool'
|
||||||
|
}>
|
||||||
|
description?: Array<
|
||||||
|
| {
|
||||||
|
children?: Array<{
|
||||||
|
marks?: Array<string>
|
||||||
|
text?: string
|
||||||
|
_type: 'span'
|
||||||
|
_key: string
|
||||||
|
}>
|
||||||
|
style?: 'normal' | 'h1' | 'h2' | 'h3' | 'h4' | 'blockquote'
|
||||||
|
listItem?: 'bullet'
|
||||||
|
markDefs?: Array<{
|
||||||
|
href?: string
|
||||||
|
_type: 'link'
|
||||||
|
_key: string
|
||||||
|
}>
|
||||||
|
level?: number
|
||||||
|
_type: 'block'
|
||||||
|
_key: string
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
asset?: {
|
||||||
|
_ref: string
|
||||||
|
_type: 'reference'
|
||||||
|
_weak?: boolean
|
||||||
|
[internalGroqTypeReferenceTo]?: 'sanity.imageAsset'
|
||||||
|
}
|
||||||
|
hotspot?: SanityImageHotspot
|
||||||
|
crop?: SanityImageCrop
|
||||||
|
_type: 'image'
|
||||||
|
_key: string
|
||||||
|
}
|
||||||
|
>
|
||||||
|
images?: Array<{
|
||||||
|
asset?: {
|
||||||
|
_ref: string
|
||||||
|
_type: 'reference'
|
||||||
|
_weak?: boolean
|
||||||
|
[internalGroqTypeReferenceTo]?: 'sanity.imageAsset'
|
||||||
|
}
|
||||||
|
hotspot?: SanityImageHotspot
|
||||||
|
crop?: SanityImageCrop
|
||||||
|
_type: 'image'
|
||||||
|
_key: string
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Tool = {
|
||||||
|
_id: string
|
||||||
|
_type: 'tool'
|
||||||
|
_createdAt: string
|
||||||
|
_updatedAt: string
|
||||||
|
_rev: string
|
||||||
|
name?: string
|
||||||
|
icon?: Icon
|
||||||
|
url?: string
|
||||||
|
color?: SimplerColor
|
||||||
|
description?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Home = {
|
||||||
|
_id: string
|
||||||
|
_type: 'home'
|
||||||
|
_createdAt: string
|
||||||
|
_updatedAt: string
|
||||||
|
_rev: string
|
||||||
|
title?: string
|
||||||
|
subtitle?: string
|
||||||
|
owner?: {
|
||||||
|
_ref: string
|
||||||
|
_type: 'reference'
|
||||||
|
_weak?: boolean
|
||||||
|
[internalGroqTypeReferenceTo]?: 'author'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type BlockContent = Array<
|
export type BlockContent = Array<
|
||||||
| {
|
| {
|
||||||
children?: Array<{
|
children?: Array<{
|
||||||
@@ -144,7 +234,6 @@ export type Post = {
|
|||||||
[internalGroqTypeReferenceTo]?: 'category'
|
[internalGroqTypeReferenceTo]?: 'category'
|
||||||
}>
|
}>
|
||||||
publishedAt?: string
|
publishedAt?: string
|
||||||
myCodeField?: Code
|
|
||||||
body?: BlockContent
|
body?: BlockContent
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,12 +347,38 @@ export type Code = {
|
|||||||
highlightedLines?: Array<number>
|
highlightedLines?: Array<number>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Icon = {
|
||||||
|
_type: 'icon'
|
||||||
|
name?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HighlightColor = {
|
||||||
|
_type: 'highlightColor'
|
||||||
|
label?: string
|
||||||
|
value?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TextColor = {
|
||||||
|
_type: 'textColor'
|
||||||
|
label?: string
|
||||||
|
value?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SimplerColor = {
|
||||||
|
_type: 'simplerColor'
|
||||||
|
label?: string
|
||||||
|
value?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type AllSanitySchemaTypes =
|
export type AllSanitySchemaTypes =
|
||||||
| SanityImagePaletteSwatch
|
| SanityImagePaletteSwatch
|
||||||
| SanityImagePalette
|
| SanityImagePalette
|
||||||
| SanityImageDimensions
|
| SanityImageDimensions
|
||||||
| SanityFileAsset
|
| SanityFileAsset
|
||||||
| Geopoint
|
| Geopoint
|
||||||
|
| Project
|
||||||
|
| Tool
|
||||||
|
| Home
|
||||||
| BlockContent
|
| BlockContent
|
||||||
| Category
|
| Category
|
||||||
| Post
|
| Post
|
||||||
@@ -275,4 +390,8 @@ export type AllSanitySchemaTypes =
|
|||||||
| SanityImageMetadata
|
| SanityImageMetadata
|
||||||
| Slug
|
| Slug
|
||||||
| Code
|
| Code
|
||||||
|
| Icon
|
||||||
|
| HighlightColor
|
||||||
|
| TextColor
|
||||||
|
| SimplerColor
|
||||||
export declare const internalGroqTypeReferenceTo: unique symbol
|
export declare const internalGroqTypeReferenceTo: unique symbol
|
||||||
|
Reference in New Issue
Block a user