diff --git a/src/app/prosjekter/page.tsx b/src/app/prosjekter/page.tsx
index c599497f..d8d946e3 100644
--- a/src/app/prosjekter/page.tsx
+++ b/src/app/prosjekter/page.tsx
@@ -2,20 +2,34 @@ import Header from "@/components/Layout/Header.component";
import PageHeader from "@/components/UI/PageHeader.component";
import ProsjektCard from "@/components/Prosjekter/ProsjektCard.component";
-import { projectsQuery } from "@/lib/sanity/queries";
import { client } from "@/lib/sanity/client";
import type { Project } from "@/types/sanity.types";
-import { Metadata } from "next/types";
+import type { Metadata } from "next/types";
export const metadata: Metadata = {
title: "Prosjekter - Dfweb",
description: "Daniel Fjeldstad | Frontend Web Utvikler | Portefølje",
};
+const projectsQuery = `*[_type == "project"] | order(featured desc, featureOrder asc, _createdAt desc) {
+ id,
+ name,
+ description,
+ subdescription,
+ projectimage,
+ urlwww,
+ urlgithub,
+ featured,
+ featureOrder
+}`;
+
export default async function Prosjekter() {
const posts: Project[] = await client.fetch(projectsQuery);
+ const featuredProjects = posts.filter((project) => project.featured);
+ const nonFeaturedProjects = posts.filter((project) => !project.featured);
+
return (
<>
@@ -25,10 +39,21 @@ export default async function Prosjekter() {
className="mt-32 bg-graybg"
>
Prosjekter
-
- {posts?.map((project) => (
-
- ))}
+
+ {featuredProjects.length > 0 && (
+
+
+ {featuredProjects.map((project) => (
+
+ ))}
+
+
+ )}
+
+ {nonFeaturedProjects.map((project) => (
+
+ ))}
+
>
diff --git a/src/types/sanity.types.ts b/src/types/sanity.types.ts
index da46b9ad..6644e5b7 100644
--- a/src/types/sanity.types.ts
+++ b/src/types/sanity.types.ts
@@ -14,230 +14,252 @@
// Source: schema.json
export type SanityImagePaletteSwatch = {
- _type: "sanity.imagePaletteSwatch";
- background?: string;
- foreground?: string;
- population?: number;
- title?: string;
-};
+ _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;
-};
+ _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;
-};
+ _type: 'sanity.imageDimensions'
+ height?: number
+ width?: number
+ aspectRatio?: number
+}
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;
-};
+ _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 Geopoint = {
- _type: "geopoint";
- lat?: number;
- lng?: number;
- alt?: number;
-};
+ _type: 'geopoint'
+ lat?: number
+ lng?: number
+ alt?: number
+}
export type Herocontent = {
- _type: "herocontent";
- text?: string;
-};
+ _type: 'herocontent'
+ text?: string
+}
export type Pagecontent = {
- _type: "pagecontent";
- id?: number;
- title?: string;
+ _type: 'pagecontent'
+ id?: number
+ title?: string
text?: Array<{
children?: Array<{
- marks?: Array
;
- text?: string;
- _type: "span";
- _key: string;
- }>;
- style?: "normal" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "blockquote";
- listItem?: "bullet" | "number";
+ marks?: Array
+ text?: string
+ _type: 'span'
+ _key: string
+ }>
+ style?: 'normal' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'blockquote'
+ listItem?: 'bullet' | 'number'
markDefs?: Array<{
- href?: string;
- _type: "link";
- _key: string;
- }>;
- level?: number;
- _type: "block";
- _key: string;
- }>;
-};
+ href?: string
+ _type: 'link'
+ _key: string
+ }>
+ level?: number
+ _type: 'block'
+ _key: string
+ }>
+}
export type Link = {
- _type: "link";
- title?: string;
- url?: string;
- external?: boolean;
-};
+ _type: 'link'
+ title?: string
+ url?: string
+ external?: boolean
+}
export type Navigation = {
- _id: string;
- _type: "Navigation";
- _createdAt: string;
- _updatedAt: string;
- _rev: string;
- title?: string;
- slug?: Slug;
+ _id: string
+ _type: 'Navigation'
+ _createdAt: string
+ _updatedAt: string
+ _rev: string
+ title?: string
+ slug?: Slug
navigation?: Array<
{
- _key: string;
+ _key: string
} & Link
- >;
-};
+ >
+}
export type Slug = {
- _type: "slug";
- current?: string;
- source?: string;
-};
+ _type: 'slug'
+ current?: string
+ source?: string
+}
export type Page = {
- _id: string;
- _type: "page";
- _createdAt: string;
- _updatedAt: string;
- _rev: string;
- title?: string;
- header?: string;
+ _id: string
+ _type: 'page'
+ _createdAt: string
+ _updatedAt: string
+ _rev: string
+ title?: string
+ header?: string
hero?: Array<
{
- _key: string;
+ _key: string
} & Herocontent
- >;
+ >
content?: Array<
{
- _key: string;
+ _key: string
} & Pagecontent
- >;
-};
+ >
+}
export type Project = {
- _id: string;
- _type: "project";
- _createdAt: string;
- _updatedAt: string;
- _rev: string;
- id?: number;
- name: string;
- description?: string;
- subdescription?: string;
+ _id: string
+ _type: 'project'
+ _createdAt: string
+ _updatedAt: string
+ _rev: string
+ id?: number
+ name: string
+ description?: string
+ subdescription?: string
projectcategory?: {
- _ref: string;
- _type: "reference";
- _weak?: boolean;
- [internalGroqTypeReferenceTo]?: "category";
- };
+ _ref: string
+ _type: 'reference'
+ _weak?: boolean
+ [internalGroqTypeReferenceTo]?: 'category'
+ }
urlwww?: Array<
{
- _key: string;
+ _key: string
} & Link
- >;
+ >
urlgithub?: Array<
{
- _key: string;
+ _key: string
} & Link
- >;
- projectimage: string;
-};
+ >
+ projectimage: string
+ featured?: boolean
+ featureOrder?: number
+}
export type SanityImageCrop = {
- _type: "sanity.imageCrop";
- top?: number;
- bottom?: number;
- left?: number;
- right?: number;
-};
+ _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;
-};
+ _type: 'sanity.imageHotspot'
+ x?: number
+ y?: number
+ height?: number
+ width?: number
+}
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;
-};
+ _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 SanityAssetSourceData = {
- _type: "sanity.assetSourceData";
- name?: string;
- id?: string;
- url?: string;
-};
+ _type: 'sanity.assetSourceData'
+ name?: string
+ id?: string
+ url?: string
+}
export type SanityImageMetadata = {
- _type: "sanity.imageMetadata";
- location?: Geopoint;
- dimensions?: SanityImageDimensions;
- palette?: SanityImagePalette;
- lqip?: string;
- blurHash?: string;
- hasAlpha?: boolean;
- isOpaque?: boolean;
-};
+ _type: 'sanity.imageMetadata'
+ location?: Geopoint
+ dimensions?: SanityImageDimensions
+ palette?: SanityImagePalette
+ lqip?: string
+ blurHash?: string
+ hasAlpha?: boolean
+ isOpaque?: boolean
+}
export type Category = {
- _id: string;
- _type: "category";
- _createdAt: string;
- _updatedAt: string;
- _rev: string;
- id?: number;
- name?: string;
-};
-export declare const internalGroqTypeReferenceTo: unique symbol;
+ _id: string
+ _type: 'category'
+ _createdAt: string
+ _updatedAt: string
+ _rev: string
+ id?: number
+ name?: string
+}
+
+export type AllSanitySchemaTypes =
+ | SanityImagePaletteSwatch
+ | SanityImagePalette
+ | SanityImageDimensions
+ | SanityFileAsset
+ | Geopoint
+ | Herocontent
+ | Pagecontent
+ | Link
+ | Navigation
+ | Slug
+ | Page
+ | Project
+ | SanityImageCrop
+ | SanityImageHotspot
+ | SanityImageAsset
+ | SanityAssetSourceData
+ | SanityImageMetadata
+ | Category
+export declare const internalGroqTypeReferenceTo: unique symbol
diff --git a/studio/schema.json b/studio/schema.json
index 3c86342d..2e3eff29 100644
--- a/studio/schema.json
+++ b/studio/schema.json
@@ -991,6 +991,20 @@
}
},
"optional": true
+ },
+ "featured": {
+ "type": "objectAttribute",
+ "value": {
+ "type": "boolean"
+ },
+ "optional": true
+ },
+ "featureOrder": {
+ "type": "objectAttribute",
+ "value": {
+ "type": "number"
+ },
+ "optional": true
}
}
},
diff --git a/studio/schemaTypes/documents/project.js b/studio/schemaTypes/documents/project.js
index 3cb87978..a6c97345 100644
--- a/studio/schemaTypes/documents/project.js
+++ b/studio/schemaTypes/documents/project.js
@@ -1,64 +1,68 @@
-import { Browser } from "phosphor-react";
+import {Browser} from 'phosphor-react'
const project = {
- // This is the display name for the type
- title: "Project",
-
- // The identifier for this document type used in the api's
- name: "project",
-
+ title: 'Project',
+ name: 'project',
icon: Browser,
-
- // Documents have the type 'document'. Your schema may describe types beyond documents
- // but let's get back to that later.
- type: "document",
-
- // Now we proceed to list the fields of our document
+ type: 'document',
fields: [
{
- title: "Id",
- name: "id",
- type: "number"
+ title: 'Id',
+ name: 'id',
+ type: 'number',
},
{
- title: "Name",
- name: "name",
- type: "string"
+ title: 'Name',
+ name: 'name',
+ type: 'string',
},
{
- title: "Description",
- name: "description",
- type: "string"
+ title: 'Description',
+ name: 'description',
+ type: 'string',
},
{
- title: "Technologies",
- name: "subdescription",
- type: "string"
+ title: 'Technologies',
+ name: 'subdescription',
+ type: 'string',
},
{
- title: "Project category",
- name: "projectcategory",
- type: "reference",
- to: [{ type: "category" }]
+ title: 'Project category',
+ name: 'projectcategory',
+ type: 'reference',
+ to: [{type: 'category'}],
},
{
- title: "Project URL",
- name: "urlwww",
- type: "array",
- of: [{ type: "link" }]
+ title: 'Project URL',
+ name: 'urlwww',
+ type: 'array',
+ of: [{type: 'link'}],
},
{
- title: "Github URL",
- name: "urlgithub",
- type: "array",
- of: [{ type: "link" }]
+ title: 'Github URL',
+ name: 'urlgithub',
+ type: 'array',
+ of: [{type: 'link'}],
},
{
- title: "Project image",
- name: "projectimage",
- type: "image"
- }
- ]
-};
+ title: 'Project image',
+ name: 'projectimage',
+ type: 'image',
+ },
+ {
+ title: 'Featured',
+ name: 'featured',
+ type: 'boolean',
+ description: 'Set to true to feature this project at the top of the page',
+ },
+ {
+ title: 'Feature Order',
+ name: 'featureOrder',
+ type: 'number',
+ description: 'Order of the featured project (lower numbers appear first)',
+ hidden: ({document}) => !document?.featured,
+ },
+ ],
+}
-export default project;
+export default project