Compare commits
3 Commits
920e83963c
...
c6084228fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6084228fc | ||
|
|
8ab37f7059 | ||
|
|
b9e57b7d1a |
@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbo",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
|
|||||||
106
payload-types.ts
106
payload-types.ts
@ -587,12 +587,98 @@ export interface HomeHero {
|
|||||||
};
|
};
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
};
|
};
|
||||||
heroItems?:
|
heroItems: {
|
||||||
| {
|
heroDataDesign: {
|
||||||
name: string;
|
root: {
|
||||||
id?: string | null;
|
type: string;
|
||||||
}[]
|
children: {
|
||||||
| null;
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
};
|
||||||
|
heroDataCollection: {
|
||||||
|
root: {
|
||||||
|
type: string;
|
||||||
|
children: {
|
||||||
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
};
|
||||||
|
heroDataAnalysis: {
|
||||||
|
root: {
|
||||||
|
type: string;
|
||||||
|
children: {
|
||||||
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
};
|
||||||
|
heroDataVisualisation: {
|
||||||
|
root: {
|
||||||
|
type: string;
|
||||||
|
children: {
|
||||||
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
};
|
||||||
|
heroTraining: {
|
||||||
|
root: {
|
||||||
|
type: string;
|
||||||
|
children: {
|
||||||
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
};
|
||||||
|
heroDataSovereignty: {
|
||||||
|
root: {
|
||||||
|
type: string;
|
||||||
|
children: {
|
||||||
|
type: string;
|
||||||
|
version: number;
|
||||||
|
[k: string]: unknown;
|
||||||
|
}[];
|
||||||
|
direction: ('ltr' | 'rtl') | null;
|
||||||
|
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||||
|
indent: number;
|
||||||
|
version: number;
|
||||||
|
};
|
||||||
|
[k: string]: unknown;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* This title will be used for SEO purposes, and displayed in the browser tab.
|
* This title will be used for SEO purposes, and displayed in the browser tab.
|
||||||
@ -658,8 +744,12 @@ export interface HomeHeroSelect<T extends boolean = true> {
|
|||||||
heroItems?:
|
heroItems?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
name?: T;
|
heroDataDesign?: T;
|
||||||
id?: T;
|
heroDataCollection?: T;
|
||||||
|
heroDataAnalysis?: T;
|
||||||
|
heroDataVisualisation?: T;
|
||||||
|
heroTraining?: T;
|
||||||
|
heroDataSovereignty?: T;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
metaTitle?: T;
|
metaTitle?: T;
|
||||||
|
|||||||
BIN
src/app/(website)/bg.jpg
Normal file
BIN
src/app/(website)/bg.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 MiB |
@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { RichText } from "@payloadcms/richtext-lexical/react";
|
import { RichText } from "@payloadcms/richtext-lexical/react";
|
||||||
import { motion, MotionValue, useScroll, useTransform } from "motion/react";
|
import { motion, useScroll, useTransform } from "motion/react";
|
||||||
import { useRef, useEffect, useState, useCallback } from "react";
|
import { useRef, useEffect, useState, useCallback } from "react";
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
@ -34,10 +34,11 @@ export default function HeroIntro({
|
|||||||
|
|
||||||
const drawBeam = useCallback(() => {
|
const drawBeam = useCallback(() => {
|
||||||
if (!windowSize) return;
|
if (!windowSize) return;
|
||||||
|
const isSmall = windowSize[0] < 1124;
|
||||||
const beam: [number, number][] = [
|
const beam: [number, number][] = [
|
||||||
[0, 1 - beamSize / 2], // modify over scroll
|
[0, 1 - beamSize / 2], // modify over scroll
|
||||||
[0.9, 0.1],
|
[0.9, 0.1],
|
||||||
[0 + beamSize / 2, 1], // modify over scroll
|
[isSmall ? 0.7 : beamSize / 2, 1], // modify over scroll
|
||||||
[0, 1],
|
[0, 1],
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ export default function HeroIntro({
|
|||||||
}, [windowSize, beamSize]);
|
}, [windowSize, beamSize]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<section
|
||||||
className="h-screen bg-black flex justify-center relative overflow-clip"
|
className="h-screen bg-black flex justify-center relative overflow-clip"
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
>
|
>
|
||||||
@ -69,10 +70,10 @@ export default function HeroIntro({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full h-full max-w-6xl p-12 grid grid-cols-2 gap-12 z-10">
|
<div className="w-full h-full max-w-6xl p-12 grid grid-cols-2 gap-12 z-10">
|
||||||
<div className="absolute top-1/2 left-0 h-1/2 w-1/2 flex-1 flex flex-col justify-center px-[5vw] gap-8">
|
<div className="absolute top-1/2 left-0 h-1/2 w-2/3 lg:w-1/2 flex-1 flex flex-col justify-center px-[5vw] gap-8 ">
|
||||||
<motion.h2
|
<motion.h2
|
||||||
style={{ opacity: scrollYProgress, y: titleY }}
|
style={{ opacity: scrollYProgress, y: titleY }}
|
||||||
className="text-5xl tracking-tight leading-tight"
|
className="text-3xl lg:text-5xl tracking-tight leading-tight font-display"
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
@ -84,11 +85,11 @@ export default function HeroIntro({
|
|||||||
>
|
>
|
||||||
<RichText
|
<RichText
|
||||||
data={desc}
|
data={desc}
|
||||||
className="text-white text-2xl leading-tight"
|
className="text-xl lg:text-2xl leading-tight"
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
86
src/app/(website)/components/Home/Hero/02-data.tsx
Normal file
86
src/app/(website)/components/Home/Hero/02-data.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { motion, useScroll, useTransform } from "motion/react";
|
||||||
|
import { useRef } from "react";
|
||||||
|
import type { HomeHero } from "@payload-types";
|
||||||
|
import { RichText } from "@payloadcms/richtext-lexical/react";
|
||||||
|
import useWindow from "@/app/(website)/hooks/useWindow";
|
||||||
|
|
||||||
|
const heroMap = {
|
||||||
|
heroDataDesign: "Data Design",
|
||||||
|
heroDataCollection: "Data Collection",
|
||||||
|
heroDataAnalysis: "Data Analysis",
|
||||||
|
heroDataVisualisation: "Data Visualisation",
|
||||||
|
heroTraining: "Training",
|
||||||
|
heroDataSovereignty: "Data Sovereignty",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
type HeroItems = HomeHero["heroGroup"]["heroItems"];
|
||||||
|
type HeroItem = HeroItems[keyof HeroItems];
|
||||||
|
|
||||||
|
export default function HeroData({
|
||||||
|
items,
|
||||||
|
}: {
|
||||||
|
items: HomeHero["heroGroup"]["heroItems"];
|
||||||
|
}) {
|
||||||
|
const itemKeys: (keyof typeof items)[] = Object.keys(items) as any;
|
||||||
|
const itemArray = itemKeys.map((k) => ({ key: k, ...items[k] }));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="bg-black flex flex-col items-center relative">
|
||||||
|
{itemArray.map((item) => (
|
||||||
|
<Item key={item.key} title={heroMap[item.key]} item={item} />
|
||||||
|
))}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Item = ({ title, item }: { title: string; item: HeroItem }) => {
|
||||||
|
const { height } = useWindow();
|
||||||
|
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
const { scrollYProgress } = useScroll({
|
||||||
|
target: containerRef,
|
||||||
|
offset: ["start end", "end start"],
|
||||||
|
});
|
||||||
|
|
||||||
|
const yp = 0.7;
|
||||||
|
const yoffset = useTransform(
|
||||||
|
scrollYProgress,
|
||||||
|
[0.2, 0.8],
|
||||||
|
[-height * yp, height * yp]
|
||||||
|
);
|
||||||
|
const opacity = useTransform(
|
||||||
|
scrollYProgress,
|
||||||
|
[0.3, 0.4, 0.6, 0.7],
|
||||||
|
[0, 1, 1, 0]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className="w-full h-screen max-w-6xl p-12 grid grid-cols-2 gap-12 z-10 items-center text-white"
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
style={{ opacity }}
|
||||||
|
className="flex items-center flex-col bg-accent-600 rounded aspect-video"
|
||||||
|
>
|
||||||
|
IMAGE
|
||||||
|
</motion.div>
|
||||||
|
<div className="relative">
|
||||||
|
<motion.div
|
||||||
|
style={{
|
||||||
|
y: yoffset,
|
||||||
|
opacity,
|
||||||
|
}}
|
||||||
|
className="flex flex-col gap-4 absolute top-1/2 -translate-y-1/2"
|
||||||
|
>
|
||||||
|
<h5 className="text-4xl font-display">{title}</h5>
|
||||||
|
<div>
|
||||||
|
<RichText className="text-xl" data={item} />
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -5,12 +5,12 @@ import { letters } from "./letters";
|
|||||||
|
|
||||||
export default function ScrollingNumbers({ numbers }: { numbers: string[][] }) {
|
export default function ScrollingNumbers({ numbers }: { numbers: string[][] }) {
|
||||||
return (
|
return (
|
||||||
<div className="absolute top-0 h-full w-full z-0 opacity-50 overflow-clip">
|
<div className="absolute top-0 h-full w-full z-0 opacity-50 pointer-events-none">
|
||||||
<div className="h-full w-full flex gap-4 skew-24 scale-150">
|
<div className="h-full w-full flex gap-4 skew-24 scale-150 overflow-hidden">
|
||||||
{numbers.map((col, i) => (
|
{numbers.map((col, i) => (
|
||||||
<NumberCol col={col} key={i} />
|
<NumberCol col={col} key={i} />
|
||||||
))}
|
))}
|
||||||
<div className="absolute w-full h-full mask-b-from-0 bg-black skew"></div>
|
<div className="absolute w-full h-full mask-b-from-0 bg-black"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -34,7 +34,7 @@ const NumberCol = ({ col }: { col: string[] }) => {
|
|||||||
className="flex-1 flex flex-col items-center"
|
className="flex-1 flex flex-col items-center"
|
||||||
>
|
>
|
||||||
{col.map((num, j) => (
|
{col.map((num, j) => (
|
||||||
<div key={j} className="text-accent-600 text-3xl">
|
<div key={j} className="text-accent-800 text-8xl">
|
||||||
{num}
|
{num}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -2,8 +2,15 @@
|
|||||||
|
|
||||||
import { ReactNode, useEffect } from "react";
|
import { ReactNode, useEffect } from "react";
|
||||||
import Lenis from "lenis";
|
import Lenis from "lenis";
|
||||||
|
import Snap from "lenis/snap";
|
||||||
|
|
||||||
export default function ({ children }: { children: ReactNode }) {
|
export default function ({
|
||||||
|
children,
|
||||||
|
snapAt,
|
||||||
|
}: {
|
||||||
|
children: ReactNode;
|
||||||
|
snapAt?: string[];
|
||||||
|
}) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const lenis = new Lenis();
|
const lenis = new Lenis();
|
||||||
|
|
||||||
@ -14,6 +21,17 @@ export default function ({ children }: { children: ReactNode }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(raf);
|
requestAnimationFrame(raf);
|
||||||
|
|
||||||
|
// const snap = new Snap(lenis, {
|
||||||
|
// type: "proximity",
|
||||||
|
// velocityThreshold: 1,
|
||||||
|
// debounce: 0,
|
||||||
|
// });
|
||||||
|
// snapAt?.forEach((id) => {
|
||||||
|
// const el = document.querySelector<HTMLDivElement>(id);
|
||||||
|
// if (!el) return;
|
||||||
|
// snap.addElement(el, { align: ["center"] });
|
||||||
|
// });
|
||||||
}, []);
|
}, []);
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap");
|
@import url("https://fonts.googleapis.com/css2?family=Inknut+Antiqua:wght@400;700&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap");
|
||||||
|
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@theme {
|
@theme {
|
||||||
/* FONT FAMILIES */
|
/* FONT FAMILIES */
|
||||||
--font-sans: Inter, sans;
|
--font-sans: "Work Sans", sans;
|
||||||
--font-display: var(--font-sans);
|
--font-display: "Inknut Antiqua";
|
||||||
|
|
||||||
/* COLOURS */
|
/* COLOURS */
|
||||||
--color-accent-50: #fff1f2;
|
--color-accent-50: #fff1f2;
|
||||||
|
|||||||
22
src/app/(website)/hooks/useWindow.ts
Normal file
22
src/app/(website)/hooks/useWindow.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export default function useWindow() {
|
||||||
|
const [width, setWidth] = useState(0);
|
||||||
|
const [height, setHeight] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!window) return;
|
||||||
|
setWidth(window.innerWidth);
|
||||||
|
setHeight(window.innerHeight);
|
||||||
|
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
setWidth(window.innerWidth);
|
||||||
|
setHeight(window.innerHeight);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -4,9 +4,13 @@ import ScrollingNumbers from "./components/Home/ScrollingNumbers";
|
|||||||
import { letters } from "./components/Home/letters";
|
import { letters } from "./components/Home/letters";
|
||||||
import HeroIntro from "./components/Home/Hero/01-intro";
|
import HeroIntro from "./components/Home/Hero/01-intro";
|
||||||
import SmoothScroll from "./components/SmoothScroll";
|
import SmoothScroll from "./components/SmoothScroll";
|
||||||
|
import HeroData from "./components/Home/Hero/02-data";
|
||||||
|
|
||||||
const randomNumbers = Array.from({ length: 50 }).map((i) =>
|
import bgImage from "./bg.jpg";
|
||||||
Array.from({ length: 200 }).map(
|
import Image from "next/image";
|
||||||
|
|
||||||
|
const randomNumbers = Array.from({ length: 10 }).map((i) =>
|
||||||
|
Array.from({ length: 20 }).map(
|
||||||
(j) => letters[Math.floor(Math.random() * letters.length)]
|
(j) => letters[Math.floor(Math.random() * letters.length)]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -18,16 +22,22 @@ export default async function Home() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SmoothScroll>
|
<SmoothScroll snapAt={["section"]}>
|
||||||
<div className="text-white">
|
<div className="text-white">
|
||||||
|
<div className="absolute h-full mt-[var(--header-height)] w-full opacity-50">
|
||||||
|
<Image src={bgImage} alt="Bg image" objectFit="cover" />
|
||||||
|
</div>
|
||||||
<div className="h-screen pt-[var(--header-height)] flex flex-col items-center justify-end text-white pb-[10vh] relative">
|
<div className="h-screen pt-[var(--header-height)] flex flex-col items-center justify-end text-white pb-[10vh] relative">
|
||||||
<ScrollingNumbers numbers={randomNumbers} />
|
{/* <ScrollingNumbers numbers={randomNumbers} /> */}
|
||||||
<h1 className="text-8xl max-w-6xl z-10">{titleGroup.title}</h1>
|
<h1 className="text-4xl p-8 lg:text-7xl leading-tight max-w-6xl z-10 font-display">
|
||||||
|
{titleGroup.title}
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<HeroIntro
|
<HeroIntro
|
||||||
title={heroGroup.heroTitle}
|
title={heroGroup.heroTitle}
|
||||||
desc={heroGroup.heroDescription}
|
desc={heroGroup.heroDescription}
|
||||||
/>
|
/>
|
||||||
|
<HeroData items={heroGroup.heroItems} />
|
||||||
</div>
|
</div>
|
||||||
</SmoothScroll>
|
</SmoothScroll>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,83 +1,114 @@
|
|||||||
import { GlobalConfig } from "payload";
|
import { GlobalConfig } from "payload";
|
||||||
|
|
||||||
export const HomeHero: GlobalConfig = {
|
export const HomeHero: GlobalConfig = {
|
||||||
slug: 'homeHero',
|
slug: "homeHero",
|
||||||
label: 'Hero',
|
label: "Hero",
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'titleGroup',
|
name: "titleGroup",
|
||||||
label: 'Landing page',
|
label: "Landing page",
|
||||||
type: 'group',
|
type: "group",
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'title',
|
name: "title",
|
||||||
label: 'Title',
|
label: "Title",
|
||||||
type: 'text',
|
type: "text",
|
||||||
required: true,
|
required: true,
|
||||||
defaultValue: 'Analytics, research, and data visualisation that make a difference'
|
defaultValue:
|
||||||
|
"Analytics, research, and data visualisation that make a difference",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'heroGroup',
|
name: "heroGroup",
|
||||||
label: 'Hero',
|
label: "Hero",
|
||||||
type: 'group',
|
type: "group",
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'heroTitle',
|
name: "heroTitle",
|
||||||
label: 'Hero Title',
|
label: "Hero Title",
|
||||||
type: 'text',
|
type: "text",
|
||||||
required: true,
|
required: true,
|
||||||
defaultValue: 'We help people tell stories with data'
|
defaultValue: "We help people tell stories with data",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'heroDescription',
|
name: "heroDescription",
|
||||||
label: 'Hero Description',
|
label: "Hero Description",
|
||||||
type: 'richText',
|
type: "richText",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'heroItems',
|
name: "heroItems",
|
||||||
label: 'Items',
|
label: "Items",
|
||||||
type: 'array',
|
type: "group",
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: "heroDataDesign",
|
||||||
label: 'Name',
|
label: "Data Design",
|
||||||
type: 'text',
|
type: "richText",
|
||||||
required: true,
|
required: true,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: "heroDataCollection",
|
||||||
|
label: "Data Collection",
|
||||||
|
type: "richText",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "heroDataAnalysis",
|
||||||
|
label: "Data Analysis",
|
||||||
|
type: "richText",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "heroDataVisualisation",
|
||||||
|
label: "Data Visualisation",
|
||||||
|
type: "richText",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "heroTraining",
|
||||||
|
label: "Training",
|
||||||
|
type: "richText",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "heroDataSovereignty",
|
||||||
|
label: "Data Sovereignty",
|
||||||
|
type: "richText",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
defaultValue: ["Data design", "Data collection", "Data analysis", "Data visualisation", "Training", "Data sovereignty"].map((item) => ({
|
|
||||||
name: item,
|
|
||||||
})),
|
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'metaTitle',
|
name: "metaTitle",
|
||||||
label: 'Meta Title',
|
label: "Meta Title",
|
||||||
type: 'text',
|
type: "text",
|
||||||
defaultValue: 'iNZight Analytics Ltd',
|
defaultValue: "iNZight Analytics Ltd",
|
||||||
required: true,
|
required: true,
|
||||||
admin: {
|
admin: {
|
||||||
position: 'sidebar',
|
position: "sidebar",
|
||||||
description: 'This title will be used for SEO purposes, and displayed in the browser tab.',
|
description:
|
||||||
}
|
"This title will be used for SEO purposes, and displayed in the browser tab.",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'metaDescription',
|
name: "metaDescription",
|
||||||
label: 'Meta Description',
|
label: "Meta Description",
|
||||||
type: 'textarea',
|
type: "textarea",
|
||||||
required: true,
|
required: true,
|
||||||
defaultValue: 'iNZight Analytics Ltd is a New Zealand-based company that provides data analysis and visualisation services.',
|
defaultValue:
|
||||||
|
"iNZight Analytics Ltd is a New Zealand-based company that provides data analysis and visualisation services.",
|
||||||
admin: {
|
admin: {
|
||||||
position: 'sidebar',
|
position: "sidebar",
|
||||||
description: 'This description will be used for SEO purposes (e.g., shown in search results and on social media cards).',
|
description:
|
||||||
}
|
"This description will be used for SEO purposes (e.g., shown in search results and on social media cards).",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
admin: {
|
admin: {
|
||||||
group: 'Home page'
|
group: "Home page",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user