├── .gitignore
├── README.md
├── astro
├── .gitignore
├── .prettierrc
├── .vscode
│ ├── extensions.json
│ └── launch.json
├── README.md
├── astro.config.mjs
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── public
│ ├── favicon.svg
│ └── fonts
│ │ ├── Sohne-Buch-webh.woff
│ │ └── Sohne-Buch-webh.woff2
├── src
│ ├── components
│ │ ├── Canvas.astro
│ │ ├── Fonts.astro
│ │ ├── Meta.astro
│ │ ├── Section.astro
│ │ ├── content.js
│ │ └── svg
│ │ │ └── Svg.astro
│ ├── env.d.ts
│ ├── js
│ │ └── app.js
│ ├── layouts
│ │ └── PageLayout.astro
│ ├── pages
│ │ ├── 404.astro
│ │ └── index.astro
│ └── style
│ │ └── main.css
├── tailwind.config.cjs
└── tsconfig.json
├── changelog.md
├── gists
├── cookies.md
├── css.md
├── glsl.md
├── pbr.glsl.md
├── promiseWrap.md
├── threejs.md
└── viewport.md
├── package.json
├── pnpm-lock.yaml
├── sanity
├── .eslintrc
├── .gitignore
├── .prettierrc
├── README.md
├── _
│ ├── astro
│ │ ├── Image.astro
│ │ └── Text.astro
│ ├── deref.js
│ ├── index.js
│ └── sanity-util.js
├── components
│ ├── LinkTypeSelect.jsx
│ ├── LockedArray.tsx
│ ├── index.js
│ └── lockedArray.module.sass
├── desk
│ └── structure.ts
├── package.json
├── plop
│ └── sanitySlice.hbs
├── plopfile.js
├── pnpm-lock.yaml
├── sanity.cli.ts
├── sanity.config.ts
├── schemas
│ ├── blocks
│ │ ├── blockContent.js
│ │ ├── emphasizedHeading.js
│ │ ├── externalLink.js
│ │ ├── form
│ │ │ ├── input.js
│ │ │ └── textarea.js
│ │ ├── imageAlt.js
│ │ ├── imageCaption.js
│ │ ├── index.js
│ │ ├── internalLink.js
│ │ └── normalText.js
│ ├── index.ts
│ ├── pages
│ │ ├── _pageDefaults.js
│ │ ├── createPage.ts
│ │ ├── error.ts
│ │ ├── home.ts
│ │ ├── index.ts
│ │ ├── legal.ts
│ │ └── project.ts
│ ├── settings
│ │ ├── cookies.ts
│ │ ├── footer.ts
│ │ ├── form.ts
│ │ ├── header.ts
│ │ ├── index.ts
│ │ ├── lists.ts
│ │ └── seo.ts
│ ├── slices
│ │ ├── _
│ │ │ ├── hero.ts
│ │ │ └── media.ts
│ │ └── index.ts
│ └── types
│ │ └── index.ts
├── static
│ └── .gitkeep
├── theme
│ └── Logo.tsx
├── tsconfig.json
└── utils
│ ├── client.js
│ ├── create.ts
│ └── preview.ts
├── todo.md
├── tooling
└── watch-asset
│ ├── .gitignore
│ ├── README.md
│ ├── bun.lockb
│ ├── index.ts
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── public
│ └── 001.webp
│ └── tsconfig.json
├── turbo
├── .eslintrc.js
├── .gitignore
├── .vscode
│ └── settings.json
├── README.md
├── gitignore
├── package.json
├── packages
│ ├── eslint-config
│ │ ├── README.md
│ │ ├── library.js
│ │ ├── next.js
│ │ ├── package.json
│ │ └── react-internal.js
│ ├── typescript-config
│ │ ├── base.json
│ │ ├── nextjs.json
│ │ ├── package.json
│ │ └── react-library.json
│ └── ui
│ │ ├── .eslintrc.js
│ │ ├── package.json
│ │ ├── src
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ └── code.tsx
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lint.json
│ │ └── turbo
│ │ └── generators
│ │ ├── config.ts
│ │ └── templates
│ │ └── component.hbs
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── tsconfig.json
└── turbo.json
├── utils
├── .gitignore
├── .parcelrc
├── agents.js
├── easings.js
├── esbuild.config.js
└── math.js
├── vite
├── .gitignore
├── README.md
├── index.html
├── package.json
├── pnpm-lock.yaml
├── src
│ ├── app.js
│ ├── assets
│ │ └── index.js
│ ├── gsap.js
│ ├── hey.js
│ ├── modules
│ │ ├── animation
│ │ │ ├── alpha.js
│ │ │ └── text.js
│ │ ├── ctrl.js
│ │ ├── dom.js
│ │ ├── pages.js
│ │ ├── scroll.js
│ │ └── viewport.js
│ ├── style
│ │ ├── anim.css
│ │ └── main.css
│ └── util
│ │ ├── clientRect.js
│ │ ├── easings.js
│ │ ├── gui.js
│ │ ├── index.js
│ │ ├── math.js
│ │ ├── observe.js
│ │ ├── track.js
│ │ └── tween.js
├── tsconfig.json.bak
└── vite.config.js
├── webflow
├── full
│ ├── .gitignore
│ ├── README.md
│ ├── bin
│ │ ├── build.js
│ │ └── live-reload.js
│ ├── package.json
│ └── src
│ │ └── index.ts
└── tiny
│ ├── README.md
│ ├── dist
│ ├── app.js
│ ├── app.js.map
│ └── styles
│ │ ├── main.css
│ │ ├── main.css.map
│ │ ├── out.css
│ │ └── out.css.map
│ ├── esbuild.config.js
│ ├── package.json
│ ├── pnpm-lock.yaml
│ └── src
│ ├── app.js
│ └── styles
│ ├── lenis.css
│ ├── main.css
│ ├── out.css
│ └── variables.css
└── webgl
├── chunk
├── imageuv.glsl
├── perlin3d.glsl
├── rand.glsl
└── rotate3d.glsl
├── ogl
├── .gitignore
├── README.md
├── index.html
├── package.json
├── pnpm-lock.yaml
├── src
│ ├── app.js
│ ├── assets
│ │ ├── index.js
│ │ ├── uvH.jpg
│ │ └── uvV.jpg
│ ├── gl
│ │ ├── _dquad.js
│ │ ├── _group.js
│ │ ├── _instance.js
│ │ ├── _model.js
│ │ ├── _quad.js
│ │ ├── _scene.js
│ │ ├── _screen.js
│ │ ├── camera.js
│ │ ├── gl.js
│ │ ├── mat
│ │ │ ├── _insta
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── _model
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── _quad
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ └── _screen
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ ├── post
│ │ │ ├── mat
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── post.js
│ │ │ └── quad.js
│ │ └── util
│ │ │ ├── domitem.js
│ │ │ ├── loader.js
│ │ │ ├── model-loader.js
│ │ │ └── texture-loader.js
│ ├── modules
│ │ ├── dom.js
│ │ ├── gui.js
│ │ ├── lenis.js
│ │ ├── pages.js
│ │ └── viewport.js
│ ├── style
│ │ └── main.css
│ └── util
│ │ ├── math.js
│ │ ├── observe.js
│ │ └── track.js
└── vite.config.js
├── three-new
├── index.html
├── package.json
├── pnpm-lock.yaml
├── src
│ ├── app.js
│ ├── assets
│ │ ├── index.js
│ │ ├── uvH.jpg
│ │ └── uvV.jpg
│ ├── gl
│ │ ├── gl.js
│ │ ├── glsl
│ │ │ ├── _
│ │ │ │ └── basic
│ │ │ │ │ ├── fragment.frag
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── vertex.vert
│ │ │ ├── constants.glsl
│ │ │ ├── imageuv.glsl
│ │ │ ├── perlin3d.glsl
│ │ │ ├── rand.glsl
│ │ │ └── rotate3d.glsl
│ │ ├── instance
│ │ │ ├── fragment.frag
│ │ │ ├── index.js
│ │ │ ├── utils.js
│ │ │ └── vertex.vert
│ │ ├── post
│ │ │ ├── base
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ └── index.js
│ │ ├── quad
│ │ │ ├── fragment.frag
│ │ │ ├── index.js
│ │ │ └── vertex.vert
│ │ ├── ray.js
│ │ ├── scenes
│ │ │ └── scene.js
│ │ └── utils
│ │ │ ├── cube-loader.js
│ │ │ ├── draco-loader.js
│ │ │ ├── index.js
│ │ │ ├── loader.js
│ │ │ ├── model-loader.js
│ │ │ └── texture-loader.js
│ ├── gsap.js
│ ├── gui.js
│ └── utils
│ │ └── math.js
├── style.css
└── vite.config.js
├── three-v2
├── .gitignore
├── README.md
├── index.html
├── package.json
├── pnpm-lock.yaml
├── src
│ ├── app.js
│ ├── assets
│ │ ├── index.js
│ │ ├── uvH.jpg
│ │ └── uvV.jpg
│ ├── gl
│ │ ├── _instance.js
│ │ ├── _quad.js
│ │ ├── gl.js
│ │ ├── mat
│ │ │ ├── basic
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── chunk
│ │ │ │ ├── imageuv.glsl
│ │ │ │ ├── perlin3d.glsl
│ │ │ │ ├── rand.glsl
│ │ │ │ └── rotate3d.glsl
│ │ │ ├── instance-raw
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── post
│ │ │ │ └── base
│ │ │ │ │ ├── fragment.frag
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── vertex.vert
│ │ │ └── raw
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ ├── post.js
│ │ ├── scene.js
│ │ └── util
│ │ │ ├── cube-loader.js
│ │ │ ├── draco-loader.js
│ │ │ ├── loader.js
│ │ │ ├── model-loader.js
│ │ │ └── texture-loader.js
│ ├── modules
│ │ ├── dom.js
│ │ ├── gui.js
│ │ ├── lenis.js
│ │ ├── pages.js
│ │ └── viewport.js
│ ├── style
│ │ └── main.css
│ └── util
│ │ └── math.js
└── vite.config.js
├── three
├── .gitignore
├── README.md
├── index.html
├── package.json
├── pnpm-lock.yaml
├── src
│ ├── app.js
│ ├── assets
│ │ ├── index.js
│ │ ├── uvH.jpg
│ │ └── uvV.jpg
│ ├── gl
│ │ ├── _instance.js
│ │ ├── _quad.js
│ │ ├── gl.js
│ │ ├── mat
│ │ │ ├── basic
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── chunk
│ │ │ │ ├── imageuv.glsl
│ │ │ │ ├── perlin3d.glsl
│ │ │ │ ├── rand.glsl
│ │ │ │ └── rotate3d.glsl
│ │ │ ├── instance-raw
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── post
│ │ │ │ └── base
│ │ │ │ │ ├── fragment.frag
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── vertex.vert
│ │ │ └── raw
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ ├── post.js
│ │ ├── scene.js
│ │ └── util
│ │ │ ├── cube-loader.js
│ │ │ ├── draco-loader.js
│ │ │ ├── loader.js
│ │ │ ├── model-loader.js
│ │ │ └── texture-loader.js
│ ├── modules
│ │ ├── dom.js
│ │ ├── gui.js
│ │ ├── lenis.js
│ │ ├── pages.js
│ │ └── viewport.js
│ ├── style
│ │ └── main.css
│ └── util
│ │ └── math.js
└── vite.config.js
├── twgl
├── index.html
├── package.json
├── package.json.bak
├── pnpm-lock.yaml
├── src
│ ├── app.js
│ ├── assets
│ │ └── index.js
│ ├── gl
│ │ ├── _
│ │ │ ├── _fs-quad.js
│ │ │ ├── _instance.js
│ │ │ └── _model.js
│ │ ├── _camera.js
│ │ ├── _quad.js
│ │ ├── gl.js
│ │ ├── mat
│ │ │ ├── _
│ │ │ │ ├── fsq
│ │ │ │ │ ├── fragment.frag
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── vertex.vert
│ │ │ │ ├── instanced
│ │ │ │ │ ├── fragment.frag
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── vertex.vert
│ │ │ │ └── model
│ │ │ │ │ ├── fragment.frag
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── vertex.vert
│ │ │ ├── chunk
│ │ │ │ ├── imageuv.glsl
│ │ │ │ ├── perlin3d.glsl
│ │ │ │ ├── rand.glsl
│ │ │ │ └── rotate3d.glsl
│ │ │ └── quad
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ ├── post
│ │ │ ├── mat
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── index.js
│ │ │ │ └── vertex.vert
│ │ │ ├── post.js
│ │ │ └── quad.js
│ │ ├── scene.js
│ │ └── util
│ │ │ ├── gltf-loader.js
│ │ │ └── spinner.js
│ ├── gui.js
│ ├── styles
│ │ ├── main.css
│ │ └── project.css
│ └── utils
│ │ ├── math.js
│ │ ├── media.js
│ │ └── texture-loader.js
└── vite.config.js
├── util
├── slider.js
└── spinner.js
└── vanilla
├── esbuild.config.js
├── index.html
├── package-lock.json
├── package.json
├── src
├── app.js
├── assets
│ ├── 3d
│ │ ├── par.glb
│ │ └── par1.glb
│ ├── imgs
│ │ ├── uvH.jpg
│ │ └── uvV.jpg
│ ├── index.js
│ └── notes.md
├── flightsheet.md
├── modules
│ ├── gl.js
│ ├── gl
│ │ ├── mat
│ │ │ ├── cam
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── m.js
│ │ │ │ └── vertex.vert
│ │ │ ├── fsq
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── m.js
│ │ │ │ └── vertex.vert
│ │ │ ├── instanced
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── m.js
│ │ │ │ └── vertex.vert
│ │ │ └── model
│ │ │ │ ├── fragment.frag
│ │ │ │ ├── m.js
│ │ │ │ └── vertex.vert
│ │ ├── mod
│ │ │ ├── fs-quad.js
│ │ │ ├── instance.js
│ │ │ ├── model.js
│ │ │ └── plane.js
│ │ └── utils
│ │ │ ├── camera.js
│ │ │ ├── gltf-loader.js
│ │ │ └── spinner.js
│ └── utils
│ │ ├── math.js
│ │ └── media.js
└── styles
│ ├── main.css
│ └── project.css
└── todo.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 | .npmrc
4 | .DS_Store
--------------------------------------------------------------------------------
/astro/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | .output/
4 |
5 | # dependencies
6 | node_modules/
7 |
8 | # logs
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | pnpm-debug.log*
13 |
14 |
15 | # environment variables
16 | .env
17 | .env.production
18 |
19 | # macOS-specific files
20 | .DS_Store
21 |
--------------------------------------------------------------------------------
/astro/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "tabWidth": 2,
4 | "singleQuote": false,
5 | "jsxSingleQuote": false,
6 | "bracketSpacing": true,
7 | "endOfLine": "lf",
8 | "trailingComma": "es5",
9 | "arrowParens": "avoid",
10 | "plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"]
11 | }
12 |
--------------------------------------------------------------------------------
/astro/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["astro-build.astro-vscode"],
3 | "unwantedRecommendations": []
4 | }
5 |
--------------------------------------------------------------------------------
/astro/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "command": "./node_modules/.bin/astro dev",
6 | "name": "Development server",
7 | "request": "launch",
8 | "type": "node-terminal"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/astro/README.md:
--------------------------------------------------------------------------------
1 | # Astro BP
2 |
3 | Astro <3 boilerplate for creative thigy
4 |
5 | #### Updates
6 |
7 | - [ ] To Add
8 |
9 |
10 | ### Use w/ Sanity
11 |
12 | scripts
13 | ```json
14 | "cms": "cd cms && pnpm dev",
15 | "all": "concurrently \"pnpm cms\" \"pnpm dev\"",
16 | "sd": "cd cms && pnpm sanity deploy"
17 | ```
18 |
19 | devdependencies
20 | ```json
21 | "astro-portabletext": "^0.9.1",
22 | "astro-sanity": "^1.1.7",
23 | "concurrently": "^8.2.0",
24 | "@sanity/client": "^6.1.7",
25 | ```
--------------------------------------------------------------------------------
/astro/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "astro/config";
2 | import tailwind from "@astrojs/tailwind";
3 | // import glsl from "vite-plugin-glsl";
4 |
5 | const plugins = [
6 | // glsl({
7 | // include: [
8 | // // Glob pattern, or array of glob patterns to import
9 | // "**/*.glsl",
10 | // // "**/*.wgsl",
11 | // "**/*.vert",
12 | // "**/*.frag",
13 | // // "**/*.vs",
14 | // // "**/*.fs",
15 | // ],
16 | // exclude: undefined, // Glob pattern, or array of glob patterns to ignore
17 | // warnDuplicatedImports: true, // Warn if the same chunk was imported multiple times
18 | // defaultExtension: "glsl", // Shader suffix when no extension is specified
19 | // compress: false, // Compress output shader code
20 | // watch: false, // Recompile shader on change
21 | // root: "/", // Directory for root imports
22 | // }),
23 | ];
24 |
25 | export default defineConfig({
26 | integrations: [tailwind()],
27 | vite: {
28 | // plugins,
29 | assetsInclude: ["**/*.webp", "**/*.glb"],
30 | },
31 | });
32 |
33 | // https://astro.build/config
34 |
--------------------------------------------------------------------------------
/astro/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@example/basics",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "dev": "astro dev",
7 | "start": "astro dev",
8 | "build": "astro build",
9 | "preview": "astro preview",
10 | "astro": "astro"
11 | },
12 | "devDependencies": {
13 | "@astrojs/tailwind": "3.1.2",
14 | "astro": "2.4.3",
15 | "prettier": "^3.0.0",
16 | "prettier-plugin-astro": "^0.11.0",
17 | "prettier-plugin-tailwindcss": "^0.4.1"
18 | }
19 | }
20 |
21 |
22 |
--------------------------------------------------------------------------------
/astro/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/astro/public/fonts/Sohne-Buch-webh.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/astro/public/fonts/Sohne-Buch-webh.woff
--------------------------------------------------------------------------------
/astro/public/fonts/Sohne-Buch-webh.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/astro/public/fonts/Sohne-Buch-webh.woff2
--------------------------------------------------------------------------------
/astro/src/components/Canvas.astro:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/astro/src/components/Fonts.astro:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | ---
4 |
5 |
--------------------------------------------------------------------------------
/astro/src/components/Meta.astro:
--------------------------------------------------------------------------------
1 | ---
2 | const { title, imageUrl, description, keyworks } = Astro.props;
3 | const def = {
4 | description: "... Description",
5 | keywords: "... Keywords",
6 | imageUrl: "/util/...",
7 | };
8 | ---
9 |
10 |
11 | {title}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/astro/src/components/Section.astro:
--------------------------------------------------------------------------------
1 | ---
2 | const { cn } = Astro.props;
3 | const classes = cn ? "py-gy" + " " + cn : "py-gy";
4 | ---
5 |
6 |
9 |
--------------------------------------------------------------------------------
/astro/src/components/content.js:
--------------------------------------------------------------------------------
1 | /* --- Data */
2 | export const content = {
3 | links: [],
4 | };
5 |
6 | /* --- Dynamic Pages */
7 | export async function getPages() {
8 | const pages = import.meta.glob("../pages/work/*.md");
9 | const pageArray = [];
10 |
11 | for (const path in pages) {
12 | pageArray.push(await pages[path]());
13 | }
14 |
15 | // pageArray.sort((a, b ) => Date.parse(b.frontmatter.date) - Date.parse(a.frontmatter.date))
16 |
17 | return pageArray;
18 | }
19 |
--------------------------------------------------------------------------------
/astro/src/components/svg/Svg.astro:
--------------------------------------------------------------------------------
1 | ---
2 | let { size } = Astro.props.props;
3 | if (size === undefined) size = "w-[5rem]";
4 |
5 | const style = `
6 | aspect-square
7 | ${size}
8 | `;
9 | ---
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/astro/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/astro/src/js/app.js:
--------------------------------------------------------------------------------
1 | console.log("App script");
2 |
--------------------------------------------------------------------------------
/astro/src/layouts/PageLayout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import "../style/main.css";
3 |
4 | const { title } = Astro.props;
5 |
6 | import Canvas from "../components/Canvas.astro";
7 | import Meta from "src/components/Meta.astro";
8 | import Fonts from "src/components/Fonts.astro";
9 | ---
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/astro/src/pages/404.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Layout from "../layouts/PageLayout.astro";
3 | import Section from "../components/Section.astro";
4 | ---
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/astro/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Layout from "../layouts/PageLayout.astro";
3 | import Section from "../components/Section.astro";
4 | ---
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/astro/src/style/main.css:
--------------------------------------------------------------------------------
1 | /* ------------------------------ Utils */
2 |
3 | html,
4 | body {
5 | overscroll-behavior: none;
6 | /* touch-action: none; */
7 | }
8 |
9 | html,
10 | body,
11 | p,
12 | h1,
13 | h2,
14 | h3,
15 | h4 {
16 | user-select: none; /* supported by Chrome and Opera */
17 | -webkit-user-select: none; /* Safari */
18 | -khtml-user-select: none; /* Konqueror HTML */
19 | -moz-user-select: none; /* Firefox */
20 | -ms-user-select: none; /* Internet Explorer/Edge */
21 | }
22 |
23 | [data-selectable] {
24 | user-select: text;
25 | -webkit-user-select: text;
26 | -khtml-user-select: text;
27 | -moz-user-select: text;
28 | -ms-user-select: text;
29 | }
30 |
31 | /* ------------------------------ Webgl */
32 | [data-gl="c"] {
33 | position: fixed;
34 | box-sizing: border-box;
35 |
36 | top: 0px;
37 | left: 0px;
38 | width: 100vw;
39 | height: 100vh;
40 |
41 | z-index: -10;
42 | pointer-events: none;
43 | /* background: blue; */
44 | }
45 |
46 | canvas {
47 | width: 100%;
48 | height: 100%;
49 | border: 1px solid blue;
50 | }
51 |
52 | /* ------------------------------ Layout */
53 |
54 | main {
55 | min-height: 100vh;
56 | }
57 | /* ------------------------------ ... */
58 |
--------------------------------------------------------------------------------
/astro/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/base",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@c/*": ["src/components/*"],
7 | "@js/*": ["src/js/*"]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/gists/cookies.md:
--------------------------------------------------------------------------------
1 | # Cookie Ops
2 |
3 | #### 100vh Viewport Height variable set
4 |
5 | ```js
6 | export function getCookie(cname) {
7 | let name = cname + "=";
8 | let decodedCookie = decodeURIComponent(document.cookie);
9 | let ca = decodedCookie.split(";");
10 | for (let i = 0; i < ca.length; i++) {
11 | let c = ca[i];
12 | while (c.charAt(0) == " ") {
13 | c = c.substring(1);
14 | }
15 | if (c.indexOf(name) == 0) {
16 | return c.substring(name.length, c.length);
17 | }
18 | }
19 | return "";
20 | }
21 |
22 | export function handleCookie(name = "NAME", value = "VALUE") {
23 | // const cname = "COOKIE NAME";
24 | // const cval = "COOKIE VALUE";
25 |
26 | const vcookie = getCookie(cname);
27 |
28 | if (vcookie) {
29 | return false;
30 | } else {
31 | const exdays = 1;
32 |
33 | const d = new Date();
34 | d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
35 | let expires = "expires=" + d.toUTCString();
36 |
37 | document.cookie = cname + "=" + cval + ";" + expires;
38 |
39 | return true;
40 | }
41 | }
42 | ```
43 |
--------------------------------------------------------------------------------
/gists/css.md:
--------------------------------------------------------------------------------
1 | # CSS Snippets
2 |
3 | ## Body/Root/\*
4 |
5 | #### HTML & Body Fill
6 |
7 | ```css
8 | :where(:root) {
9 | display: grid;
10 | min-height: 100%;
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/gists/promiseWrap.md:
--------------------------------------------------------------------------------
1 | # Wrap Promise.all w/ callbacks
2 |
3 | ```js
4 | export function allProgress(proms, progress_cb) {
5 | let d = 0;
6 | progress_cb(0);
7 | for (const p of proms) {
8 | p.then(() => {
9 | d++;
10 | progress_cb((d * 100) / proms.length);
11 | });
12 | }
13 | return Promise.all(proms);
14 | }
15 |
16 | function test(ms) {
17 | return new Promise((resolve) => {
18 | setTimeout(() => {
19 | console.log(`Waited ${ms}`);
20 | resolve("somedata");
21 | }, ms);
22 | });
23 | }
24 |
25 | function progressCallback(p) {
26 | console.log(`${p.toFixed(0)} %`);
27 | }
28 |
29 | async function init() {
30 | const [data1, data2, data3, data4] = await allProgress(
31 | [test(1000), test(3000), test(2000), test(3500)],
32 | progressCallback
33 | );
34 |
35 | console.log(data1, data2, data3, data4);
36 | }
37 |
38 | init();
39 | ```
40 |
--------------------------------------------------------------------------------
/gists/threejs.md:
--------------------------------------------------------------------------------
1 | # THREEjs
2 |
3 | ## Shaders
4 |
5 | #### Skinned Shader
6 |
7 | ```csharp
8 | // (VERTEX)
9 |
10 | // #include
11 | #include
12 |
13 | void main() {
14 | // #include
15 | #include
16 |
17 |
18 | vec4 tr = modelViewMatrix * vec4(position, 1.0);
19 | // gl_Position = projectionMatrix * tr;
20 | vUv = uv;
21 |
22 | #include
23 | // #include
24 | #include
25 | #include
26 | #include
27 |
28 | }
29 |
30 | // might want to add (up top)
31 | // #include
32 | // #include
33 | // #include
34 |
35 | ```
36 |
--------------------------------------------------------------------------------
/gists/viewport.md:
--------------------------------------------------------------------------------
1 | # Viewport Utils
2 |
3 | ## CSS
4 |
5 | #### 100vh Viewport Height variable set
6 |
7 | ```js
8 | document.documentElement.style.setProperty(
9 | "--100vh",
10 | `${window.innerHeight}px`
11 | );
12 | ```
13 |
14 | #### Set VH unit (constantly)
15 |
16 | ```js
17 | ["DOMContentLoaded", "resize"].forEach((event) => {
18 | window.addEventListener(event, (_) => {
19 | const vh = window.innerHeight * 0.01;
20 | document.documentElement.style.setProperty("--vh", `${vh}px`);
21 | });
22 | });
23 | ```
24 |
25 | #### Detect Browser window / tab state
26 |
27 | ```js
28 | document.addEventListener("visibilitychange", () => {
29 | if (document.hidden) {
30 | console.log("hidden");
31 | } else {
32 | console.log("visible");
33 | }
34 | });
35 |
36 | window.addEventListener("focus", () => {
37 | console.log("focus");
38 | });
39 |
40 | window.addEventListener("blur", () => {
41 | console.log("blur");
42 | });
43 | ```
44 |
45 | ```js
46 | export function viewportUnits() {
47 | document.documentElement.style.setProperty(
48 | "--vw",
49 | document.documentElement.clientWidth * 0.01 + "px"
50 | );
51 |
52 | document.documentElement.style.setProperty(
53 | "--dvh",
54 | window.innerHeight * 0.01 + "px"
55 | );
56 |
57 | document.documentElement.style.setProperty(
58 | "--svh",
59 | document.documentElement.clientHeight * 0.01 + "px"
60 | );
61 |
62 | document.documentElement.style.setProperty("--lvh", "1vh");
63 | }
64 | ```
65 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "starters",
3 | "version": "1.0.0",
4 | "description": "mixed scaffolds and boilerplate code",
5 | "main": "index.js",
6 | "author": "vallafederico",
7 | "license": "MIT",
8 | "scripts": {
9 | "vite": "cd vite && pnpm dev"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .: {}
10 |
--------------------------------------------------------------------------------
/sanity/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@sanity/eslint-config-studio"
3 | }
4 |
--------------------------------------------------------------------------------
/sanity/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # Compiled Sanity Studio
9 | /dist
10 |
11 | # Temporary Sanity runtime, generated by the CLI on every dev server start
12 | /.sanity
13 |
14 | # Logs
15 | /logs
16 | *.log
17 |
18 | # Coverage directory used by testing tools
19 | /coverage
20 |
21 | # Misc
22 | .DS_Store
23 | *.pem
24 |
25 | # Typescript
26 | *.tsbuildinfo
27 |
28 | # Dotenv and similar local-only files
29 | *.local
30 |
--------------------------------------------------------------------------------
/sanity/.prettierrc:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/sanity/README.md:
--------------------------------------------------------------------------------
1 | # Sanity Clean Content Studio
2 |
3 | ## Secrets
4 |
5 | ```js
6 | export default defineCliConfig({
7 | api: {
8 | projectId: process.env.SANITY_STUDIO_ID,
9 | dataset: 'production',
10 | },
11 | })
12 | ```
13 |
14 | ### .env
15 | ```md
16 | SANITY_STUDIO_ID="..."
17 | ```
18 |
--------------------------------------------------------------------------------
/sanity/_/astro/Text.astro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vallafederico/starters/b8e01d7a426bdb78898de95e385a2a99b553f9cc/sanity/_/astro/Text.astro
--------------------------------------------------------------------------------
/sanity/_/index.js:
--------------------------------------------------------------------------------
1 | import {urlFor} from './sanity-util.js'
2 | import {sanityClient} from 'sanity:client'
3 | // import { resolveLinks } from "./deref.js"
4 |
5 | export {urlFor}
6 |
7 | // export async function getRef(ref) {
8 | // const query = groq`*[_id == '${ref}']`
9 | // const data = await useSanityClient().fetch(query)
10 | // return data
11 | // }
12 |
13 | export async function getType(type) {
14 | const query = `*[_type == "${type}"]`
15 | const data = await sanityClient.fetch(query)
16 |
17 | // .then(async data => {
18 | // await resolveLinks(data)
19 | // return data
20 | // })
21 |
22 | return data
23 | }
24 |
25 | /** -- -- Astro */
26 | export async function getPages(name) {
27 | const data = await getType(name)
28 |
29 | return data.map((d) => {
30 | return {
31 | params: {card: d.slug.current},
32 | props: d,
33 | }
34 | })
35 | }
36 |
37 | /**
38 | * /[...smth].astro
39 | */
40 |
41 | export async function getStaticPaths(name) {
42 | const data = await getPages(name)
43 | // data.forEach((item, i) => {
44 | // // console.log(item)
45 | // if (i === 9) {
46 | // item.props.next = data[0].props;
47 | // } else {
48 | // item.props.next = data[i + 1].props;
49 | // }
50 | // });
51 |
52 | return data
53 | }
54 |
55 | // const { smth } = Astro.params;
56 | // const { ... } = Astro.props;
57 |
--------------------------------------------------------------------------------
/sanity/_/sanity-util.js:
--------------------------------------------------------------------------------
1 | import imageUrlBuilder from '@sanity/image-url'
2 | import {sanityClient} from 'sanity:client'
3 |
4 | // imageBuilder
5 | export const imageBuilder = imageUrlBuilder(sanityClient)
6 |
7 | /* ---- Sanity Image Builder ----
8 | .size(w | 0, (h / aspectRatio) | 0)
9 | .fit('crop')
10 | .auto('format') // -> converts to webp
11 | .quality(77)
12 | .url()
13 | */
14 |
15 | export function urlFor(source, {url = false, quality = 50, width = 720} = {}) {
16 | const img = imageBuilder.image(source).auto('format').quality(quality).width(width)
17 |
18 | if (url) return img.url()
19 | return img
20 | }
21 |
--------------------------------------------------------------------------------
/sanity/components/index.js:
--------------------------------------------------------------------------------
1 | const components = []
2 |
3 | export default components
4 |
--------------------------------------------------------------------------------
/sanity/components/lockedArray.module.sass:
--------------------------------------------------------------------------------
1 | .locked
2 | :global
3 | .sc-kcuKUB
4 | button[aria-haspopup=true]
5 | display: none
--------------------------------------------------------------------------------
/sanity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sofia-papadopoulou",
3 | "private": true,
4 | "version": "1.0.0",
5 | "type": "module",
6 | "main": "package.json",
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "dev": "sanity dev",
10 | "start": "sanity start",
11 | "build": "sanity build",
12 | "deploy": "sanity deploy",
13 | "deploy-graphql": "sanity graphql deploy"
14 | },
15 | "keywords": [
16 | "sanity"
17 | ],
18 | "dependencies": {
19 | "@sanity/vision": "^3.24.1",
20 | "react": "^18.2.0",
21 | "react-dom": "^18.2.0",
22 | "react-icons": "^5.0.1",
23 | "react-is": "^18.2.0",
24 | "sanity": "^3.24.1",
25 | "sanity-plugin-prefixed-slug": "^2.0.0",
26 | "sanity-plugin-vercel-deploy": "^3.3.4",
27 | "sass": "^1.69.7",
28 | "styled-components": "^6.1.8"
29 | },
30 | "devDependencies": {
31 | "@sanity/eslint-config-studio": "^3.0.1",
32 | "@types/react": "^18.2.48",
33 | "@types/styled-components": "^5.1.34",
34 | "eslint": "^8.56.0",
35 | "plop": "^4.0.1",
36 | "prettier": "^3.2.2",
37 | "typescript": "^5.3.3"
38 | },
39 | "prettier": {
40 | "semi": false,
41 | "printWidth": 100,
42 | "bracketSpacing": false,
43 | "singleQuote": true
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/sanity/plop/sanitySlice.hbs:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '{{camelCase name}}',
3 | icon: null,
4 | type: 'object',
5 | fields:[],
6 | preview: {
7 | prepare() {
8 | return {
9 | title: '{{titleCase name}}',
10 | icon: null,
11 | }
12 | },
13 | },
14 | }
--------------------------------------------------------------------------------
/sanity/sanity.cli.ts:
--------------------------------------------------------------------------------
1 | import {defineCliConfig} from 'sanity/cli'
2 |
3 | export default defineCliConfig({
4 | api: {
5 | projectId: process.env.SANITY_STUDIO_ID,
6 | dataset: 'production',
7 | },
8 | })
9 |
--------------------------------------------------------------------------------
/sanity/sanity.config.ts:
--------------------------------------------------------------------------------
1 | import {defineConfig} from 'sanity'
2 | import {deskTool} from 'sanity/desk'
3 | import {visionTool} from '@sanity/vision'
4 | import {structure} from './desk/structure'
5 | import {schemaTypes} from './schemas'
6 | import {vercelDeployTool} from 'sanity-plugin-vercel-deploy'
7 |
8 | export default defineConfig({
9 | name: 'default',
10 | title: '👀',
11 | projectId: process.env.SANITY_STUDIO_ID,
12 | dataset: 'production',
13 |
14 | plugins: [deskTool({structure}), visionTool(), vercelDeployTool()],
15 |
16 | schema: {
17 | types: schemaTypes,
18 | },
19 | })
20 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/blockContent.js:
--------------------------------------------------------------------------------
1 | // Rich Text field with code tags and H1 removed
2 |
3 | export default {
4 | name: 'blockContent',
5 | title: 'Content',
6 | type: 'array',
7 | of: [
8 | {
9 | type: 'block',
10 | styles: [
11 | {title: 'Normal', value: 'normal'},
12 | // {title: 'H1', value: 'h1'},
13 | {title: 'Heading', value: 'h2'},
14 | {title: 'Subhead', value: 'h3'},
15 | {title: 'Microhead', value: 'h4'},
16 | ],
17 | lists: [
18 | {title: '', value: 'bullet'},
19 | {title: '', value: 'number'},
20 | ],
21 | marks: {
22 | decorators: [
23 | {
24 | title: 'Italics',
25 | value: 'em',
26 | },
27 | {
28 | title: 'Bold',
29 | value: 'strong',
30 | },
31 | ],
32 | },
33 | },
34 | ],
35 | }
36 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/emphasizedHeading.js:
--------------------------------------------------------------------------------
1 | // Only supports normal text and emphasis for b
2 |
3 | export default {
4 | name: 'emphasizedHeading',
5 | title: 'Content',
6 | type: 'array',
7 | of: [
8 | {
9 | type: 'block',
10 | styles: [
11 | {title: 'Normal', value: 'normal'},
12 | // {title: 'Heading 2', value: 'h2'},
13 | // {title: 'Heading 3', value: 'h3'},
14 | // {title: 'Heading 4', value: 'h4'},
15 | // {title: 'Heading 5', value: 'h5'},
16 | // {title: 'Heading 6', value: 'h6'},
17 | ],
18 | lists: [],
19 | marks: {
20 | decorators: [
21 | {
22 | title: 'Italics',
23 | value: 'em',
24 | },
25 | // {
26 | // title: 'Bold',
27 | // value: 'strong',
28 | // },
29 | ],
30 | },
31 | },
32 | ],
33 | }
34 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/externalLink.js:
--------------------------------------------------------------------------------
1 | import {BiLinkExternal} from 'react-icons/bi'
2 |
3 | export default {
4 | name: 'externalLink',
5 | type: 'object',
6 | icon: BiLinkExternal,
7 | preview: {
8 | select: {
9 | title: 'label',
10 | subtitle: 'url',
11 | },
12 | prepare(selection) {
13 | const {title, subtitle} = selection
14 | return {
15 | title,
16 | subtitle,
17 | }
18 | },
19 | },
20 | fields: [
21 | {
22 | name: 'label',
23 | type: 'string',
24 | },
25 | {
26 | name: 'url',
27 | type: 'url',
28 | title: 'URL',
29 | validation: (Rule) => Rule.required(),
30 | description: 'Must begin with https://',
31 | },
32 | ],
33 | }
34 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/form/input.js:
--------------------------------------------------------------------------------
1 | import {BsInputCursorText} from 'react-icons/bs'
2 |
3 | export default {
4 | name: 'input',
5 | title: 'Short Text Field',
6 | icon: BsInputCursorText,
7 | type: 'object',
8 | fieldsets: [
9 | {
10 | name: 'form',
11 | options: {columns: 2},
12 | },
13 | ],
14 | fields: [
15 | {
16 | name: 'label',
17 | fieldset: 'form',
18 | type: 'string',
19 | title: 'Field Label',
20 | },
21 | {
22 | name: 'placeholder',
23 | type: 'string',
24 | fieldset: 'form',
25 | title: 'Field Placeholder',
26 | description:
27 | 'Placed inside the field before a user has typed anything, a helpful hint for the format or expected value. Defaults to the field label above.',
28 | },
29 | {
30 | name: 'validation',
31 | type: 'string',
32 | descripton: 'Optional. What is the user expected to type?',
33 | options: {
34 | list: [
35 | {
36 | title: 'Email',
37 | value: 'email',
38 | },
39 | {
40 | title: 'Location',
41 | value: 'location',
42 | },
43 | {
44 | title: 'phone',
45 | value: 'Phone Number',
46 | },
47 | ],
48 | },
49 | },
50 | ],
51 | }
52 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/form/textarea.js:
--------------------------------------------------------------------------------
1 | import {BsTextLeft} from 'react-icons/bs'
2 |
3 | export default {
4 | name: 'textarea',
5 | icon: BsTextLeft,
6 | title: 'Long Text Field',
7 | type: 'object',
8 | fieldsets: [
9 | {
10 | name: 'form',
11 | options: {columns: 2},
12 | },
13 | ],
14 | fields: [
15 | {
16 | name: 'label',
17 | fieldset: 'form',
18 | type: 'string',
19 | title: 'Field Label',
20 | },
21 | {
22 | name: 'placeholder',
23 | type: 'string',
24 | fieldset: 'form',
25 | title: 'Field Placeholder',
26 | description:
27 | 'Placed inside the field before a user has typed anything, a helpful hint for the format or expected value. Defaults to the field label above.',
28 | },
29 | ],
30 | }
31 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/imageAlt.js:
--------------------------------------------------------------------------------
1 | import {MdImage} from 'react-icons/md'
2 |
3 | export default {
4 | name: 'imageAlt',
5 | title: 'Image',
6 | icon: MdImage,
7 | type: 'object',
8 | fields: [
9 | {
10 | name: 'image',
11 | type: 'image',
12 | options: {
13 | metadata: ['lqip'],
14 | hotspot: true,
15 | },
16 | },
17 | {
18 | name: 'alt',
19 | title: 'Alternative Text',
20 | type: 'string',
21 | description: 'Users with visual impairments will read this description instead of the image.',
22 | validation: (Rule) => Rule.required().error('Alternative text is required'),
23 | },
24 | ],
25 | }
26 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/imageCaption.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: 'object',
3 | name: 'imageCaption',
4 | title: 'Image with Caption',
5 | fields: [
6 | {
7 | name: 'image',
8 | type: 'imageAlt',
9 | },
10 | {
11 | name: 'caption',
12 | type: 'string',
13 | description: 'Captions are only visible inside galleries',
14 | },
15 | ],
16 | preview: {
17 | select: {
18 | alt: 'image.alt',
19 | caption: 'caption',
20 | media: 'image.image',
21 | },
22 | prepare(selection) {
23 | const {media, alt, caption} = selection
24 | return {
25 | media: media,
26 | title: caption ? caption : 'No caption provided',
27 | }
28 | },
29 | },
30 | }
31 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/index.js:
--------------------------------------------------------------------------------
1 | import normalText from './normalText'
2 | import blockContent from './blockContent'
3 | import imageAlt from './imageAlt'
4 | // import mediaSelect from './mediaSelect'
5 | import input from './form/input'
6 | import textArea from './form/textArea'
7 |
8 | import emphasizedHeading from './emphasizedHeading'
9 | import imageCaption from './imageCaption'
10 | import internalLink from './internalLink'
11 |
12 | const blocks = [
13 | imageAlt,
14 | emphasizedHeading,
15 | internalLink,
16 | blockContent,
17 | imageCaption,
18 | // mediaSelect,
19 | normalText,
20 | input,
21 | textArea,
22 | ]
23 |
24 | export default blocks
25 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/internalLink.js:
--------------------------------------------------------------------------------
1 | import {BiLink} from 'react-icons/bi'
2 | import pages from '../pages'
3 |
4 | const allPages = []
5 |
6 | pages.forEach((page) => {
7 | if (page && page.name) {
8 | allPages.push({type: page.name})
9 | }
10 | })
11 |
12 | export default {
13 | name: 'internalLink',
14 | type: 'object',
15 | icon: BiLink,
16 | fields: [
17 | {
18 | name: 'label',
19 | type: 'string',
20 | validation: (Rule) => Rule.required(),
21 | },
22 | {
23 | name: 'link',
24 | validation: (Rule) => Rule.required(),
25 | type: 'reference',
26 | options: {
27 | disableNew: true,
28 | },
29 | to: [...allPages],
30 | },
31 | ],
32 | preivew: {
33 | select: {
34 | link: 'link',
35 | title: 'label',
36 | },
37 | prepare(selection) {
38 | const {link, title} = selection
39 | return {
40 | subtitle: link.slug.current,
41 | title,
42 | }
43 | },
44 | },
45 | }
46 |
--------------------------------------------------------------------------------
/sanity/schemas/blocks/normalText.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'normalText',
3 | title: 'Text Block',
4 | type: 'array',
5 | of: [
6 | {
7 | type: 'block',
8 | styles: [
9 | {title: 'Normal', value: 'normal'},
10 | // {title: 'H1', value: 'h1'},
11 | // {title: 'H2', value: 'h2'},
12 | ],
13 | },
14 | ],
15 | }
16 |
--------------------------------------------------------------------------------
/sanity/schemas/index.ts:
--------------------------------------------------------------------------------
1 | import pages from './pages'
2 | import slices from './slices'
3 | import settings from './settings'
4 | import blocks from './blocks'
5 |
6 | export const schemaTypes = [...blocks, ...slices, ...pages, ...settings]
7 |
--------------------------------------------------------------------------------
/sanity/schemas/pages/error.ts:
--------------------------------------------------------------------------------
1 | import {MdError} from 'react-icons/md'
2 | import createPage from './createPage'
3 |
4 | const options = {
5 | slug: false,
6 | seo: false,
7 | slices: false,
8 | icon: MdError,
9 | body: false,
10 | fields: [
11 | {
12 | name: 'text',
13 | type: 'string',
14 | group: 'content',
15 | },
16 | ],
17 | }
18 |
19 | export default createPage('Error Page (404)', 'error', options)
20 |
--------------------------------------------------------------------------------
/sanity/schemas/pages/home.ts:
--------------------------------------------------------------------------------
1 | import {MdHome} from 'react-icons/md'
2 | import createPage from './createPage'
3 |
4 | const options = {
5 | slices: 'homeSlices',
6 | icon: MdHome,
7 | slug: false,
8 | prefix: false,
9 | }
10 |
11 | export default createPage('Home', 'home', options)
12 |
--------------------------------------------------------------------------------
/sanity/schemas/pages/index.ts:
--------------------------------------------------------------------------------
1 | import error from './error'
2 | import home from './home'
3 | import legal from './legal'
4 | import project from './project'
5 |
6 | const pages = [home, error, legal, project]
7 |
8 | export default pages
9 |
--------------------------------------------------------------------------------
/sanity/schemas/pages/legal.ts:
--------------------------------------------------------------------------------
1 | import {MdGavel} from 'react-icons/md'
2 | import createPage from './createPage'
3 |
4 | const options = {
5 | // prefix: 'legal',
6 | seo: false,
7 | slug: true,
8 | fields: [
9 | {
10 | name: 'blurb',
11 | type: 'text',
12 | rows: 3,
13 | group: 'content',
14 | description: 'Short paragraph at the top of this page, underneath the title.',
15 | },
16 | ],
17 | icon: MdGavel,
18 | slices: false,
19 | body: true,
20 | }
21 |
22 | export default createPage('Legal Page', 'legal', options)
23 |
--------------------------------------------------------------------------------
/sanity/schemas/pages/project.ts:
--------------------------------------------------------------------------------
1 | import {createPreview} from '../../utils/preview'
2 | import createPage from './createPage'
3 | import {MdPages, MdPerson} from 'react-icons/md'
4 |
5 | const options = {
6 | slices: 'pageSlices',
7 | prefix: false,
8 | slug: true,
9 | seo: true,
10 | groups: [{title: 'Project Brief', name: 'brief'}],
11 | icon: MdPages,
12 | fields: [
13 | // {
14 | // name: 'mainImage',
15 | // type: 'imageAlt',
16 | // group: 'content',
17 | // },
18 | ],
19 | body: false,
20 | }
21 |
22 | export default createPage('Project', 'project', options)
23 |
--------------------------------------------------------------------------------
/sanity/schemas/settings/cookies.ts:
--------------------------------------------------------------------------------
1 | import {MdCookie} from 'react-icons/md'
2 |
3 | export default {
4 | name: 'settings.cookies',
5 | title: 'Cookie & Privacy Settings',
6 | icon: MdCookie,
7 | type: 'document',
8 | fields: [
9 | {
10 | name: 'blurb',
11 | validation: (Rule) => Rule.required(),
12 | type: 'text',
13 | rows: 2,
14 | description:
15 | 'Small description of what cookies are used for on the site. Appears in the popup when a user loads the page.',
16 | },
17 | {
18 | name: 'description',
19 | validation: (Rule) => Rule.required(),
20 | type: 'text',
21 | rows: 2,
22 | title: 'Marketing Cookies Description',
23 | description:
24 | "GDPR-Compliant description of how cookies are used when the site gathers them. Visible when a user opens 'Cookie Preferences'",
25 | },
26 | ],
27 | }
28 |
--------------------------------------------------------------------------------
/sanity/schemas/settings/footer.ts:
--------------------------------------------------------------------------------
1 | import {createPreview} from '../../utils/preview'
2 | import {IoShareSocial} from 'react-icons/io5'
3 |
4 | export default {
5 | name: 'settings.footer',
6 | title: 'Footer',
7 | type: 'object',
8 | fields: [
9 | {
10 | name: 'socialLinks',
11 | title: 'Social Media Links',
12 | type: 'array',
13 | of: [
14 | {
15 | type: 'object',
16 | icon: IoShareSocial,
17 | preview: createPreview('networkName', 'url'),
18 | fields: [
19 | {name: 'networkName', type: 'string'},
20 | {name: 'url', type: 'url', title: 'URL'},
21 | ],
22 | },
23 | ],
24 | },
25 | {
26 | name: 'legalLinks',
27 | title: 'Legal Page Links',
28 | type: 'array',
29 | of: [{type: 'reference', to: [{type: 'legal'}]}],
30 | },
31 | {
32 | name: 'cta',
33 | title: 'CTA button label',
34 | type: 'string',
35 | },
36 | {
37 | name: 'email',
38 | type: 'string',
39 | },
40 | ],
41 | preview: {
42 | prepare() {
43 | return {
44 | title: 'Footer',
45 | }
46 | },
47 | },
48 | }
49 |
--------------------------------------------------------------------------------
/sanity/schemas/settings/header.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | name: 'settings.header',
3 | title: 'Header',
4 | type: 'object',
5 | fields: [
6 | {
7 | name: 'links',
8 | title: 'Navigation Links',
9 | type: 'array',
10 | of: [
11 | {
12 | type: 'internalLink',
13 | name: 'link',
14 | },
15 | ],
16 | },
17 | {
18 | name: 'cta',
19 | title: 'Call to Action Label',
20 | description: 'Label for a call to action button in the navigation.',
21 | type: 'string',
22 | },
23 | ],
24 | preview: {
25 | prepare() {
26 | return {
27 | title: 'Header',
28 | }
29 | },
30 | },
31 | }
32 |
--------------------------------------------------------------------------------
/sanity/schemas/settings/index.ts:
--------------------------------------------------------------------------------
1 | import header from './header'
2 | import footer from './footer'
3 | import seo from './seo'
4 | import form from './form'
5 | import cookies from './cookies'
6 |
7 | const settings = [header, footer, seo, form, cookies]
8 |
9 | export default settings
10 |
--------------------------------------------------------------------------------
/sanity/schemas/slices/_/hero.ts:
--------------------------------------------------------------------------------
1 | import {TbLayoutBottombar} from 'react-icons/tb'
2 |
3 | export default {
4 | name: 'hero',
5 | type: 'object',
6 | icon: TbLayoutBottombar,
7 | fields: [
8 | {
9 | name: 'swappyWords',
10 | type: 'array',
11 | of: [{type: 'string'}],
12 | },
13 | ],
14 | preview: {
15 | prepare() {
16 | return {
17 | title: 'Hero',
18 | icon: null,
19 | }
20 | },
21 | },
22 | }
23 |
--------------------------------------------------------------------------------
/sanity/schemas/slices/_/media.ts:
--------------------------------------------------------------------------------
1 | import {MdPermMedia} from 'react-icons/md'
2 |
3 | export default {
4 | name: 'media',
5 | icon: MdPermMedia,
6 | type: 'object',
7 | fields: [
8 | {
9 | name: 'media',
10 | validation: (Rule) => Rule.max(3),
11 | type: 'array',
12 | of: [
13 | {
14 | type: 'object',
15 | fields: [
16 | {
17 | name: 'image',
18 | type: 'imageAlt',
19 | // hidden: ({parent, value}) => parent.mediaType === 'video',
20 | options: {
21 | collapsed: false,
22 | },
23 | },
24 | {
25 | name: 'video',
26 | title: 'Video (optional)',
27 | type: 'url',
28 | options: {
29 | collapsed: false,
30 | },
31 | // hidden: ({parent, value}) => parent.mediaType === 'image',
32 | },
33 | ],
34 | },
35 | ],
36 | },
37 | ],
38 | preview: {
39 | prepare() {
40 | return {
41 | title: 'Media',
42 | icon: MdPermMedia,
43 | }
44 | },
45 | },
46 | }
47 |
--------------------------------------------------------------------------------
/sanity/schemas/slices/index.ts:
--------------------------------------------------------------------------------
1 | // import hero from './hero'
2 |
3 | const sortAlpha = (a, b) => {
4 | return a.name.localeCompare(b.name)
5 | }
6 |
7 | const globalPageSlices = [
8 | // hero,
9 | ]
10 | const contentPageSlices = [
11 | // hero,
12 | ]
13 | const homeSlices = [
14 | // hero,
15 | ]
16 |
17 | // Create page slices type that acts as a base for all types of slices to be dropped into
18 | const pageSlices = {
19 | name: 'pageSlices',
20 | title: 'Page slices',
21 | description: 'Each section of the page can be edited here',
22 | type: 'array',
23 | of: [...contentPageSlices.sort((a, b) => sortAlpha(a, b)).map((slice) => ({type: slice.name}))],
24 | }
25 |
26 | const homePageSlices = {
27 | name: 'homeSlices',
28 | title: 'Page Slices',
29 | description: 'Each section of the page can be edited here',
30 | type: 'array',
31 | of: [...homeSlices.sort((a, b) => sortAlpha(a, b)).map((slice) => ({type: slice.name}))],
32 | }
33 |
34 | // Create an array from all of the slice types so that sanity can iterate on them
35 | const allSlices = Array.from(new Set([...globalPageSlices]))
36 |
37 | export default [pageSlices, ...allSlices, homePageSlices]
38 |
--------------------------------------------------------------------------------
/sanity/schemas/types/index.ts:
--------------------------------------------------------------------------------
1 | import {IconType} from 'react-icons'
2 | import {ObjectField} from 'sanity'
3 |
4 | export interface PageAttributes {
5 | title: string
6 | name: string
7 | options: {
8 | slug?: string
9 | icon: IconType
10 | slices?: false | 'homeSlices' | 'pageSlices' // Adds slice array to add sections in visually-based pages
11 | }
12 | prefix?: string // Add prefix to slug, i.e "/blog/..."
13 | seo?: boolean // Add SEO attributes to page
14 |
15 | body?: boolean // Adds a rich text field for text-based pages
16 | fields?: Array // Add extra fields on top of defaults
17 | }
18 |
--------------------------------------------------------------------------------
/sanity/static/.gitkeep:
--------------------------------------------------------------------------------
1 | Files placed here will be served by the Sanity server under the `/static`-prefix
2 |
--------------------------------------------------------------------------------
/sanity/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true
17 | },
18 | "include": ["**/*.ts", "**/*.tsx"],
19 | "exclude": ["node_modules"]
20 | }
21 |
--------------------------------------------------------------------------------
/sanity/utils/client.js:
--------------------------------------------------------------------------------
1 | import client from '@sanity/client'
2 |
3 | export default client({
4 | projectId: 'r19ry25y',
5 | dataset: 'production',
6 | apiVersion: 'v2023-04-20',
7 | })
8 |
--------------------------------------------------------------------------------
/sanity/utils/create.ts:
--------------------------------------------------------------------------------
1 | // import f
2 |
3 | export const createField = (name: string, type?: string, title?: string, extra?: any) => {
4 | return {
5 | name,
6 | type,
7 | title,
8 | ...extra,
9 | }
10 | }
11 |
12 | export const createTaxo = (name: string, title: string, fields: Array