Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import tailwindcss from "@tailwindcss/vite";

import svelte from "@astrojs/svelte";

import sanity from "@sanity/astro";
import react from "@astrojs/react";

// https://astro.build/config
export default defineConfig({
redirects: {
Expand Down Expand Up @@ -72,5 +75,15 @@ export default defineConfig({
plugins: [tailwindcss()],
},

integrations: [svelte()],
integrations: [
svelte(),
sanity({
projectId: "payz0nck",
dataset: "production",
// Set useCdn to false if you're building statically.
useCdn: false,
studioBasePath: "/sanity",
}),
react(),
],
});
16 changes: 15 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,30 @@
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
"astro": "astro",
"sanity:extract": "sanity schema extract",
"sanity:typegen": "sanity typegen generate"
},
"dependencies": {
"@astrojs/react": "^4.4.2",
"@astrojs/svelte": "^7.2.5",
"@sanity/astro": "^3.2.11",
"@sanity/client": "^7.14.1",
"@sanity/image-url": "^2.0.3",
"@tailwindcss/vite": "^4.1.18",
"@types/react": "^19.2.9",
"@types/react-dom": "^19.2.3",
"astro": "^5.16.11",
"cva": "1.0.0-beta.4",
"dayjs": "^1.11.19",
"embla-carousel": "^8.6.0",
"groq": "^5.6.0",
"motion": "^12.26.2",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-is": "^19.2.3",
"sanity": "^5.6.0",
"styled-components": "^6.3.8",
"svelte": "^5.46.4",
"svelte-portal": "^2.2.1",
"tailwindcss": "^4.1.18",
Expand Down
12,619 changes: 11,079 additions & 1,540 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions sanity.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from "sanity";
import { structureTool } from "sanity/structure";
import { schemaTypes } from "schema";

export default defineConfig({
name: "youthacks",
title: "Youthacks",
projectId: "payz0nck",
dataset: "production",
plugins: [structureTool()],
schema: {
types: schemaTypes,
},
});
208 changes: 208 additions & 0 deletions sanity.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/**
* ---------------------------------------------------------------------------------
* This file has been generated by Sanity TypeGen.
* Command: `sanity typegen generate`
*
* Any modifications made directly to this file will be overwritten the next time
* the TypeScript definitions are generated. Please make changes to the Sanity
* schema definitions and/or GROQ queries if you need to update these types.
*
* For more information on how to use Sanity TypeGen, visit the official documentation:
* https://www.sanity.io/docs/sanity-typegen
* ---------------------------------------------------------------------------------
*/

// Source: schema.json
export type SanityImageAssetReference = {
_ref: string;
_type: "reference";
_weak?: boolean;
[internalGroqTypeReferenceTo]?: "sanity.imageAsset";
};

export type Sponsor = {
_id: string;
_type: "sponsor";
_createdAt: string;
_updatedAt: string;
_rev: string;
title?: string;
url?: string;
image?: {
asset: SanityImageAssetReference;
media?: unknown;
hotspot?: SanityImageHotspot;
crop?: SanityImageCrop;
_type: "image";
};
};

export type SanityImageCrop = {
_type: "sanity.imageCrop";
top?: number;
bottom?: number;
left?: number;
right?: number;
};

export type SanityImageHotspot = {
_type: "sanity.imageHotspot";
x?: number;
y?: number;
height?: number;
width?: number;
};

export type SanityImagePaletteSwatch = {
_type: "sanity.imagePaletteSwatch";
background?: string;
foreground?: string;
population?: number;
title?: string;
};

export type SanityImagePalette = {
_type: "sanity.imagePalette";
darkMuted?: SanityImagePaletteSwatch;
lightVibrant?: SanityImagePaletteSwatch;
darkVibrant?: SanityImagePaletteSwatch;
vibrant?: SanityImagePaletteSwatch;
dominant?: SanityImagePaletteSwatch;
lightMuted?: SanityImagePaletteSwatch;
muted?: SanityImagePaletteSwatch;
};

export type SanityImageDimensions = {
_type: "sanity.imageDimensions";
height?: number;
width?: number;
aspectRatio?: number;
};

export type SanityImageMetadata = {
_type: "sanity.imageMetadata";
location?: Geopoint;
dimensions?: SanityImageDimensions;
palette?: SanityImagePalette;
lqip?: string;
blurHash?: string;
thumbHash?: string;
hasAlpha?: boolean;
isOpaque?: boolean;
};

export type SanityFileAsset = {
_id: string;
_type: "sanity.fileAsset";
_createdAt: string;
_updatedAt: string;
_rev: string;
originalFilename?: string;
label?: string;
title?: string;
description?: string;
altText?: string;
sha1hash?: string;
extension?: string;
mimeType?: string;
size?: number;
assetId?: string;
uploadId?: string;
path?: string;
url?: string;
source?: SanityAssetSourceData;
};

export type SanityAssetSourceData = {
_type: "sanity.assetSourceData";
name?: string;
id?: string;
url?: string;
};

export type SanityImageAsset = {
_id: string;
_type: "sanity.imageAsset";
_createdAt: string;
_updatedAt: string;
_rev: string;
originalFilename?: string;
label?: string;
title?: string;
description?: string;
altText?: string;
sha1hash?: string;
extension?: string;
mimeType?: string;
size?: number;
assetId?: string;
uploadId?: string;
path?: string;
url?: string;
metadata?: SanityImageMetadata;
source?: SanityAssetSourceData;
};

export type Geopoint = {
_type: "geopoint";
lat?: number;
lng?: number;
alt?: number;
};

export type Slug = {
_type: "slug";
current?: string;
source?: string;
};

export type AllSanitySchemaTypes =
| SanityImageAssetReference
| Sponsor
| SanityImageCrop
| SanityImageHotspot
| SanityImagePaletteSwatch
| SanityImagePalette
| SanityImageDimensions
| SanityImageMetadata
| SanityFileAsset
| SanityAssetSourceData
| SanityImageAsset
| Geopoint
| Slug;

export declare const internalGroqTypeReferenceTo: unique symbol;

type ArrayOf<T> = Array<
T & {
_key: string;
}
>;

// Source: src/components/home/Partners.astro
// Variable: sponsorsQuery
// Query: *[_type == "sponsor"]
export type SponsorsQueryResult = Array<{
_id: string;
_type: "sponsor";
_createdAt: string;
_updatedAt: string;
_rev: string;
title?: string;
url?: string;
image?: {
asset: SanityImageAssetReference;
media?: unknown;
hotspot?: SanityImageHotspot;
crop?: SanityImageCrop;
_type: "image";
};
}>;

// Query TypeMap
import "@sanity/client";
declare module "@sanity/client" {
interface SanityQueries {
'*[_type == "sponsor"]': SponsorsQueryResult;
}
}
3 changes: 3 additions & 0 deletions schema/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { sponsorType } from "./sponsorType";

export const schemaTypes = [sponsorType];
26 changes: 26 additions & 0 deletions schema/sponsorType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { defineField, defineType } from "sanity";

export const sponsorType = defineType({
name: "sponsor",
title: "Sponsor",
type: "document",
fields: [
defineField({
name: "title",
type: "string",
validation: (Rule) => Rule.required(),
}),
defineField({
name: "url",
title: "Website URL",
type: "url",
validation: (Rule) => Rule.required(),
}),
defineField({
name: "image",
type: "image",
description: "Sponsor logo - recommended 2:1 aspect ratio",
validation: (Rule) => Rule.required().assetRequired(),
}),
],
});
13 changes: 6 additions & 7 deletions src/components/home/Partners.astro
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
---
import { getCollection } from "astro:content";
import { sanityClient } from "sanity:client";
import { defineQuery } from "groq";

import PartnersMarquee from "~/components/partners/PartnersMarquee.svelte";

const partners = await getCollection(
"partners",
(partner) => !partner.data.hidden,
);
const sponsorsQuery = defineQuery(`*[_type == "sponsor"]`);
const sponsors = await sanityClient.fetch(sponsorsQuery);
---

<section>
<div class="mx-auto max-w-7xl p-8 text-center">
<h2 class="font-satoshi text-2xl font-bold sm:text-3xl">Past sponsors</h2>
<h2 class="font-satoshi text-2xl font-bold sm:text-3xl">Past partners</h2>
<p class="mt-1.5 text-pretty text-neutral-600 sm:mt-2 sm:text-lg">
Amazing organisations we've worked with to bring our events to life.
</p>
<div class="mt-4">
<PartnersMarquee partners={partners} client:idle />
<PartnersMarquee sponsors={sponsors} client:idle />
</div>
</div>
</section>
22 changes: 12 additions & 10 deletions src/components/partners/PartnersMarquee.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<script lang="ts">
import type { CollectionEntry } from "astro:content";
import { onMount } from "svelte";
import { animate } from "motion";
import type { SponsorsQueryResult } from "sanity.types";
import { imageUrl } from "~/lib/image";
import { Image } from "astro:assets";

const { partners }: { partners: CollectionEntry<"partners">[] } = $props();
const { sponsors }: { sponsors: SponsorsQueryResult } = $props();

let outerEl: HTMLDivElement;
let offsetWidth = $state<number>();
Expand All @@ -18,7 +20,7 @@
x: [-0, -offsetWidth],
},
{
duration: 6 * partners.length,
duration: 6 * sponsors.length,
repeat: Infinity,
ease: "linear",
},
Expand Down Expand Up @@ -50,21 +52,21 @@
</div>

{#snippet list()}
{#each partners as partner}
{#each sponsors as partner}
<a
href={partner.data.url}
href={partner.url}
target="_blank"
onmouseenter={onHover}
onmouseleave={onLeave}
tabindex="-1"
class="mr-4 flex-none transition duration-200 hover:scale-105 hover:opacity-100 hover:grayscale-0 hover:duration-300 pointer-fine:opacity-50 pointer-fine:grayscale"
>
<img
src={partner.data.logo.src}
alt={partner.data.title}
width={partner.data.logo.width}
height={partner.data.logo.height}
class="h-16 w-auto"
src={imageUrl.image(partner.image!).height(64).url()}
alt={partner.title}
width={128}
height={64}
class="h-16 w-auto object-contain"
loading="lazy"
decoding="async"
/>
Expand Down
4 changes: 4 additions & 0 deletions src/lib/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { sanityClient } from "sanity:client";
import { createImageUrlBuilder } from "@sanity/image-url";

export const imageUrl = createImageUrlBuilder(sanityClient);
Loading