some progress
This commit is contained in:
parent
b1c2720d85
commit
4192a15779
@ -8,6 +8,6 @@ services:
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=admin
|
||||
- POSTGRES_DB=prisma
|
||||
- POSTGRES_DB=website
|
||||
volumes:
|
||||
- ./pgdata:/var/lib/postgresql/data
|
||||
|
||||
@ -11,25 +11,29 @@
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.2.0",
|
||||
"@payloadcms/db-postgres": "^3.31.0",
|
||||
"@payloadcms/next": "^3.31.0",
|
||||
"@payloadcms/richtext-lexical": "^3.31.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"graphql": "^16.10.0",
|
||||
"motion": "^12.6.5",
|
||||
"next": "15.2.4",
|
||||
"payload": "^3.31.0",
|
||||
"postcss": "^8.5.3",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"sharp": "^0.33.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@tailwindcss/postcss": "^4.0.17",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"clsx": "^2.1.1",
|
||||
"prettier": "^3.5.3",
|
||||
"tailwindcss": "^4",
|
||||
"tailwindcss": "^4.0.17",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"pnpm": {
|
||||
|
||||
106
payload-types.ts
106
payload-types.ts
@ -93,10 +93,12 @@ export interface Config {
|
||||
defaultIDType: number;
|
||||
};
|
||||
globals: {
|
||||
home: Home;
|
||||
homeHero: HomeHero;
|
||||
homeProjects: HomeProject;
|
||||
};
|
||||
globalsSelect: {
|
||||
home: HomeSelect<false> | HomeSelect<true>;
|
||||
homeHero: HomeHeroSelect<false> | HomeHeroSelect<true>;
|
||||
homeProjects: HomeProjectsSelect<false> | HomeProjectsSelect<true>;
|
||||
};
|
||||
locale: null;
|
||||
user: User & {
|
||||
@ -549,33 +551,54 @@ export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "home".
|
||||
* via the `definition` "homeHero".
|
||||
*/
|
||||
export interface Home {
|
||||
export interface HomeHero {
|
||||
id: number;
|
||||
title?: string | null;
|
||||
heroTitle?: string | null;
|
||||
heroDescription?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
titleGroup: {
|
||||
title: string;
|
||||
};
|
||||
heroGroup: {
|
||||
heroTitle: string;
|
||||
heroDescription: {
|
||||
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;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
heroItems?:
|
||||
| {
|
||||
name: string;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
heroItems?:
|
||||
| {
|
||||
name: string;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
};
|
||||
/**
|
||||
* This title will be used for SEO purposes, and displayed in the browser tab.
|
||||
*/
|
||||
metaTitle: string;
|
||||
/**
|
||||
* This description will be used for SEO purposes (e.g., shown in search results and on social media cards).
|
||||
*/
|
||||
metaDescription: string;
|
||||
updatedAt?: string | null;
|
||||
createdAt?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "homeProjects".
|
||||
*/
|
||||
export interface HomeProject {
|
||||
id: number;
|
||||
projectsTitle?: string | null;
|
||||
projectsDescription?: {
|
||||
root: {
|
||||
@ -597,18 +620,37 @@ export interface Home {
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "home_select".
|
||||
* via the `definition` "homeHero_select".
|
||||
*/
|
||||
export interface HomeSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
heroTitle?: T;
|
||||
heroDescription?: T;
|
||||
heroItems?:
|
||||
export interface HomeHeroSelect<T extends boolean = true> {
|
||||
titleGroup?:
|
||||
| T
|
||||
| {
|
||||
name?: T;
|
||||
id?: T;
|
||||
title?: T;
|
||||
};
|
||||
heroGroup?:
|
||||
| T
|
||||
| {
|
||||
heroTitle?: T;
|
||||
heroDescription?: T;
|
||||
heroItems?:
|
||||
| T
|
||||
| {
|
||||
name?: T;
|
||||
id?: T;
|
||||
};
|
||||
};
|
||||
metaTitle?: T;
|
||||
metaDescription?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
globalType?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "homeProjects_select".
|
||||
*/
|
||||
export interface HomeProjectsSelect<T extends boolean = true> {
|
||||
projectsTitle?: T;
|
||||
projectsDescription?: T;
|
||||
updatedAt?: T;
|
||||
|
||||
@ -3,13 +3,14 @@ import { FixedToolbarFeature, lexicalEditor } from '@payloadcms/richtext-lexical
|
||||
import { postgresAdapter } from '@payloadcms/db-postgres'
|
||||
import { buildConfig } from 'payload'
|
||||
|
||||
import { Home } from '@/globals/Home'
|
||||
import { HomeHero } from '@/globals/Home/Hero'
|
||||
|
||||
import { News } from './src/collections/News'
|
||||
import { Projects } from '@/collections/Projects'
|
||||
import { Images } from '@/collections/media/Images'
|
||||
import { Documents } from '@/collections/media/Documents'
|
||||
import { Data } from '@/collections/media/Data'
|
||||
import { HomeProjects } from '@/globals/Home/Projects'
|
||||
|
||||
export default buildConfig({
|
||||
// If you'd like to use Rich Text, pass your editor here
|
||||
@ -22,7 +23,7 @@ export default buildConfig({
|
||||
|
||||
serverURL: process.env.SERVER_URL || 'http://localhost:3000',
|
||||
|
||||
globals: [Home],
|
||||
globals: [HomeHero, HomeProjects],
|
||||
|
||||
// Define and configure your collections in this array
|
||||
collections: [Projects, News, Images, Documents, Data],
|
||||
|
||||
82
pnpm-lock.yaml
generated
82
pnpm-lock.yaml
generated
@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@heroicons/react':
|
||||
specifier: ^2.2.0
|
||||
version: 2.2.0(react@19.0.0)
|
||||
'@payloadcms/db-postgres':
|
||||
specifier: ^3.31.0
|
||||
version: 3.31.0(@types/react@19.0.12)(payload@3.31.0(graphql@16.10.0)(typescript@5.8.2))(react@19.0.0)
|
||||
@ -23,12 +26,18 @@ importers:
|
||||
graphql:
|
||||
specifier: ^16.10.0
|
||||
version: 16.10.0
|
||||
motion:
|
||||
specifier: ^12.6.5
|
||||
version: 12.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
next:
|
||||
specifier: 15.2.4
|
||||
version: 15.2.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.77.4)
|
||||
payload:
|
||||
specifier: ^3.31.0
|
||||
version: 3.31.0(graphql@16.10.0)(typescript@5.8.2)
|
||||
postcss:
|
||||
specifier: ^8.5.3
|
||||
version: 8.5.3
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.0.0
|
||||
@ -40,7 +49,7 @@ importers:
|
||||
version: 0.33.5
|
||||
devDependencies:
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4
|
||||
specifier: ^4.0.17
|
||||
version: 4.0.17
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.16
|
||||
@ -54,11 +63,14 @@ importers:
|
||||
'@types/react-dom':
|
||||
specifier: ^19
|
||||
version: 19.0.4(@types/react@19.0.12)
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
prettier:
|
||||
specifier: ^3.5.3
|
||||
version: 3.5.3
|
||||
tailwindcss:
|
||||
specifier: ^4
|
||||
specifier: ^4.0.17
|
||||
version: 4.0.17
|
||||
typescript:
|
||||
specifier: ^5
|
||||
@ -651,6 +663,11 @@ packages:
|
||||
'@floating-ui/utils@0.2.9':
|
||||
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
|
||||
|
||||
'@heroicons/react@2.2.0':
|
||||
resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==}
|
||||
peerDependencies:
|
||||
react: '>= 16 || ^19.0.0-rc'
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
@ -1482,6 +1499,20 @@ packages:
|
||||
focus-trap@7.5.4:
|
||||
resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==}
|
||||
|
||||
framer-motion@12.6.5:
|
||||
resolution: {integrity: sha512-MKvnWov0paNjvRJuIy6x418w23tFqRfS6CXHhZrCiSEpXVlo/F+usr8v4/3G6O0u7CpsaO1qop+v4Ip7PRCBqQ==}
|
||||
peerDependencies:
|
||||
'@emotion/is-prop-valid': '*'
|
||||
react: ^18.0.0 || ^19.0.0
|
||||
react-dom: ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@emotion/is-prop-valid':
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
@ -1837,6 +1868,26 @@ packages:
|
||||
monaco-editor@0.38.0:
|
||||
resolution: {integrity: sha512-11Fkh6yzEmwx7O0YoLxeae0qEGFwmyPRlVxpg7oF9czOOCB/iCjdJrG5I67da5WiXK3YJCxoz9TJFE8Tfq/v9A==}
|
||||
|
||||
motion-dom@12.6.5:
|
||||
resolution: {integrity: sha512-jpM9TQLXzYMWMJ7Ec7sAj0iis8oIuu6WvjI3yNKJLdrZyrsI/b2cRInDVL8dCl683zQQq19DpL9cSMP+k8T1NA==}
|
||||
|
||||
motion-utils@12.6.5:
|
||||
resolution: {integrity: sha512-IsOeKsOF+FWBhxQEDFBO6ZYC8/jlidmVbbLpe9/lXSA9j9kzGIMUuIBx2SZY+0reAS0DjZZ1i7dJp4NHrjocPw==}
|
||||
|
||||
motion@12.6.5:
|
||||
resolution: {integrity: sha512-X3IIy76nxyk4I87xQEm5Ah8ojQ4qisd+/H592eXF14ha+xqpbDJcWOSf9PEKCOCC0K4PN/0UBaz+MvSQUkIeXQ==}
|
||||
peerDependencies:
|
||||
'@emotion/is-prop-valid': '*'
|
||||
react: ^18.0.0 || ^19.0.0
|
||||
react-dom: ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@emotion/is-prop-valid':
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
@ -2855,6 +2906,10 @@ snapshots:
|
||||
|
||||
'@floating-ui/utils@0.2.9': {}
|
||||
|
||||
'@heroicons/react@2.2.0(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||
@ -3796,6 +3851,15 @@ snapshots:
|
||||
dependencies:
|
||||
tabbable: 6.2.0
|
||||
|
||||
framer-motion@12.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
dependencies:
|
||||
motion-dom: 12.6.5
|
||||
motion-utils: 12.6.5
|
||||
tslib: 2.8.1
|
||||
optionalDependencies:
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
@ -4229,6 +4293,20 @@ snapshots:
|
||||
|
||||
monaco-editor@0.38.0: {}
|
||||
|
||||
motion-dom@12.6.5:
|
||||
dependencies:
|
||||
motion-utils: 12.6.5
|
||||
|
||||
motion-utils@12.6.5: {}
|
||||
|
||||
motion@12.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
dependencies:
|
||||
framer-motion: 12.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
tslib: 2.8.1
|
||||
optionalDependencies:
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const config = {
|
||||
plugins: ["@tailwindcss/postcss"],
|
||||
plugins: { "@tailwindcss/postcss": {} },
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@ -1 +0,0 @@
|
||||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 391 B |
@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
BIN
public/ial-white-transp.png
Normal file
BIN
public/ial-white-transp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 128 B |
@ -1 +0,0 @@
|
||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||
|
Before Width: | Height: | Size: 385 B |
32
src/app/(frontend)/components/Header/Client.tsx
Normal file
32
src/app/(frontend)/components/Header/Client.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
"use client";
|
||||
|
||||
import clsx from "clsx";
|
||||
import { motion } from "motion/react";
|
||||
import React from "react";
|
||||
|
||||
export default function ClientHeader({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
// const { scrollY } = useScroll();
|
||||
// const [scrolled, setScrolled] = React.useState(0);
|
||||
|
||||
// const scrollPoint = window.innerHeight / 2;
|
||||
|
||||
// useMotionValueEvent(scrollY, "change", (latest) => {
|
||||
// setScrolled(
|
||||
// latest == 0 ? 0 : latest > scrollPoint ? 1 : latest / scrollPoint
|
||||
// );
|
||||
// });
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className={clsx(
|
||||
"text-white absolute w-full top-0 z-50 bg-transparent lg:h-[var(--header-height)]"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
10
src/app/(frontend)/components/Header/Header.tsx
Normal file
10
src/app/(frontend)/components/Header/Header.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import ClientHeader from "./Client";
|
||||
import ServerHeader from "./Server";
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<ClientHeader>
|
||||
<ServerHeader />
|
||||
</ClientHeader>
|
||||
);
|
||||
}
|
||||
44
src/app/(frontend)/components/Header/Server.tsx
Normal file
44
src/app/(frontend)/components/Header/Server.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
// import SignIn from "@/components/sign-in";
|
||||
// import SignOut from "@/components/sign-out";
|
||||
import Image from "next/image";
|
||||
|
||||
import ialLogo from "../../../../../public/ial-white-transp.png";
|
||||
import Link from "next/link";
|
||||
import Button from "../ui/Button";
|
||||
|
||||
// import { auth } from "@/auth";
|
||||
|
||||
export default async function ServerHeader() {
|
||||
// const session = await auth();
|
||||
|
||||
return (
|
||||
<nav className="flex h-full p-4 justify-between items-center container mx-auto">
|
||||
{/* left */}
|
||||
<div className="h-10 lg:h-20 relative w-20 lg:w-80">
|
||||
<Image
|
||||
src={ialLogo}
|
||||
alt="iNZight Analytics Ltd"
|
||||
className="h-full object-contain object-left"
|
||||
fill
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* right */}
|
||||
<div className="items-center gap-8 font-bold hidden lg:flex">
|
||||
<Link href="/about">About</Link>
|
||||
<Link href="/projects">Projects</Link>
|
||||
<Link href="/news">News</Link>
|
||||
<Link href="/apps">
|
||||
<Button
|
||||
type="primary"
|
||||
variant="outlined"
|
||||
className="border-white text-white hover:bg-white hover:text-black"
|
||||
>
|
||||
Apps
|
||||
</Button>
|
||||
</Link>
|
||||
{/* {session ? <SignOut /> : <SignIn />} */}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
22
src/app/(frontend)/components/home/CTA.tsx
Normal file
22
src/app/(frontend)/components/home/CTA.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { ChevronRightIcon } from "@heroicons/react/20/solid";
|
||||
import Button from "../ui/Button";
|
||||
|
||||
export default function CTA() {
|
||||
return (
|
||||
<section className="bg-linear-to-tr from-accent-950 to-accent-700">
|
||||
<div className="container px-4 lg:px-24 py-8 lg:py-48 mx-auto flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4">
|
||||
<h2 className="text-3xl lg:text-5xl leading-tight text-white font-medium">
|
||||
Want to collaborate?
|
||||
</h2>
|
||||
<Button
|
||||
className="lg:button-large border-white text-white hover:bg-white hover:text-accent-950 group"
|
||||
type="alternate"
|
||||
variant="outlined"
|
||||
>
|
||||
Get in touch
|
||||
<ChevronRightIcon className="h-5 lg:h-10 w-5 lg:w-10 ml-2 group-hover:translate-x-2 transition" />
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
81
src/app/(frontend)/components/home/Hero.tsx
Normal file
81
src/app/(frontend)/components/home/Hero.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import React from "react";
|
||||
|
||||
import configPromise from "@payload-config";
|
||||
import { getPayload } from "payload";
|
||||
|
||||
import ScrollToSection from "./ScrollToSection";
|
||||
import { RichText } from "@payloadcms/richtext-lexical/react";
|
||||
|
||||
export default async function Hero() {
|
||||
const payload = await getPayload({ config: configPromise });
|
||||
|
||||
const hero = await payload.findGlobal({
|
||||
slug: "homeHero",
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="relative h-screen bg-black lg:pt-[var(--header-height)]">
|
||||
hi
|
||||
<div className="relative z-10 p-4 container mx-auto flex flex-col justify-end h-full pb-12 gap-8">
|
||||
<h1 className="text-4xl lg:text-8xl lg:px-20 font-medium leading-tight text-white">
|
||||
{hero.titleGroup.title}
|
||||
</h1>
|
||||
<div className="flex justify-center">
|
||||
<ScrollToSection anchor="#about" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
id="about"
|
||||
className="h-screen overflow-clip bg-linear-to-b from:black to-accent-950 lg:bg-black"
|
||||
>
|
||||
<div className="px-4 py-8 lg:py-0 lg:px-24 h-full flex flex-col lg:flex-row container gap-16 lg:gap-32 lg:items-center justify-center mx-auto text-white">
|
||||
<div className="flex flex-col lg:flex-1 gap-4 lg:gap-8 z-10">
|
||||
<h2 className="text-3xl lg:text-5xl leading-tight">
|
||||
{hero.heroGroup?.heroTitle}
|
||||
</h2>
|
||||
<div className="text-lg lg:text-2xl leading-tight">
|
||||
<RichText data={hero.heroGroup.heroDescription} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 lg:h-full flex lg:items-center lg:justify-center relative">
|
||||
<div className="hidden lg:block h-[200%] bg-radial aspect-square absolute from-accent-900 to-black to-80%"></div>
|
||||
<div className="hidden lg:block h-[100%] bg-radial aspect-square absolute from-white/10 to-transparent to-20%"></div>
|
||||
<Oribal />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const Oribal = () => {
|
||||
return (
|
||||
<div className="lg:flex-1 lg:h-1/2 relative space-y-8">
|
||||
<div className="hidden lg:block absolute h-full w-1/2 rounded-[100%] border-dashed border-white border rotate-10 left-1/2 -translate-x-1/2 translate-y-5"></div>
|
||||
<div className="hidden lg:block absolute h-full w-1/2 rounded-[100%] border-dashed border-white border rotate-20 left-1/2 -translate-x-1/2"></div>
|
||||
<div className="hidden lg:block absolute h-full w-1/2 rounded-[100%] border-dashed border-white border rotate-30 left-1/2 -translate-x-1/2 translate-y-10"></div>
|
||||
|
||||
<Planet text="Data design" className="right-2/5" />
|
||||
<Planet text="Data collection" className="left-3/4 top-1/4" />
|
||||
<Planet text="Data analysis" className="left-3/5 top-3/5" />
|
||||
<Planet text="Data visualisation" className="left-2/7 top-full" />
|
||||
<Planet text="Training" className="right-4/5 top-5/7" />
|
||||
<Planet text="Data sovereignty" className="right-3/5 top-2/5" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Planet = ({ text, className }: { text: string; className?: string }) => {
|
||||
return (
|
||||
<div className={className}>
|
||||
<span
|
||||
className={`lg:absolute bg-accent-800/0 border border-white/10 backdrop-blur-md text-accent-100 font-bold px-6 shadow-lg py-2 rounded-full whitespace-nowrap ${className} hover:bg-accent-800`}
|
||||
>
|
||||
{text}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
59
src/app/(frontend)/components/home/News.tsx
Normal file
59
src/app/(frontend)/components/home/News.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import Button from "@/components/ui/button";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { ChevronRightIcon } from "@heroicons/react/20/solid";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default function News() {
|
||||
return (
|
||||
<section className="bg-secondary-50">
|
||||
<div className="container px-4 lg:px-24 py-8 lg:py-48 mx-auto">
|
||||
<div className="flex flex-col lg:flex-row justify-between items-start lg:items-center gap-4">
|
||||
<h2 className="text-3xl lg:text-5xl leading-tight text-black">
|
||||
We've got some news
|
||||
</h2>
|
||||
<Button type="primary" variant="outlined" className="group">
|
||||
View all news
|
||||
<ChevronRightIcon className="h-5 w-5 ml-2 group-hover:translate-x-1" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="py-12">
|
||||
<Gallery />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
async function Gallery() {
|
||||
const news = await prisma.news.findMany({
|
||||
where: {
|
||||
draft: false,
|
||||
},
|
||||
orderBy: {
|
||||
date: "desc",
|
||||
},
|
||||
take: 3,
|
||||
});
|
||||
|
||||
// TODO: parse markdown
|
||||
return (
|
||||
<div className="flex flex-col lg:grid lg:grid-cols-3 place-items-start gap-10 lg:gap-20">
|
||||
{news.map((item) => (
|
||||
<div key={item.id} className="space-y-2 lg:space-y-4">
|
||||
<div className="text-sm text-accent-700">
|
||||
{dayjs(item.date).format("DD/MM/YYYY")}
|
||||
</div>
|
||||
<h3 className="text-md lg:text-2xl text-black">{item.title}</h3>
|
||||
<hr className="border-accent-800/20 hidden lg:block" />
|
||||
<p className="text-gray-600 text-base leading-normal line-clamp-[10] hidden lg:block">
|
||||
{item.body}
|
||||
</p>
|
||||
<Button type="alternate" variant="outlined">
|
||||
Read more <ChevronRightIcon className="h-5 w-5 ml-2" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
54
src/app/(frontend)/components/home/Partners.tsx
Normal file
54
src/app/(frontend)/components/home/Partners.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
"use client";
|
||||
|
||||
import clsx from "clsx";
|
||||
import { useState } from "react";
|
||||
|
||||
const PARTNERS = [
|
||||
{ label: "Aotearoa", partners: [] },
|
||||
{ label: "International", partners: [] },
|
||||
];
|
||||
|
||||
export default function Partners() {
|
||||
const [partner, setPartner] = useState(PARTNERS[0].label);
|
||||
|
||||
return (
|
||||
<section className="bg-gray-100">
|
||||
<div className="container px-4 lg:px-24 py-8 lg:py-48 mx-auto lg:space-y-20">
|
||||
<h2 className="text-3xl lg:text-5xl leading-tight text-black">
|
||||
We've worked with …
|
||||
</h2>
|
||||
|
||||
<div className="flex gap-6 lg:gap-20 flex-col lg:flex-row text-black">
|
||||
<ul className="lg:border-t border-gray-500 lg:pr-8 pt-8 lg:space-y-4 flex lg:flex-col items-center lg:items-start gap-x-4">
|
||||
{PARTNERS.map((group) => (
|
||||
<li
|
||||
key={group.label}
|
||||
className={clsx(
|
||||
"lg:space-y-4 text-xl lg:text-3xl flex items-center lg:gap-4 font-medium cursor-pointer",
|
||||
group.label === partner && "text-accent-500"
|
||||
)}
|
||||
onClick={() => setPartner(group.label)}
|
||||
>
|
||||
{group.label}
|
||||
<div
|
||||
className={clsx(
|
||||
"size-3 bg-accent-500 rounded-full hidden lg:block",
|
||||
group.label !== partner && "opacity-0"
|
||||
)}
|
||||
></div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="pt-8 border-t border-gray-500 grid grid-cols-2 lg:grid-cols-4 gap-6 lg:gap-12 flex-1 justify-items-stretch">
|
||||
{Array.from({ length: 12 }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-gray-400/50 h-auto aspect-video rounded shadow"
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
79
src/app/(frontend)/components/home/Projects.tsx
Normal file
79
src/app/(frontend)/components/home/Projects.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import Button from "@/components/ui/button";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { ChevronRightIcon } from "@heroicons/react/20/solid";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Projects() {
|
||||
return (
|
||||
<section className="bg-white text-black">
|
||||
<div className="min-h-screen container px-4 lg:px-24 py-8 lg:py-48 mx-auto">
|
||||
<div className="lg:w-3/5 space-y-8">
|
||||
<h2 className="text-3xl lg:text-5xl leading-tight">
|
||||
We do data differently
|
||||
</h2>
|
||||
|
||||
<p className="text-lg lg:text-2xl leading-tight">
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Commodi
|
||||
modi repudiandae deleniti ut at, voluptatibus alias asperiores
|
||||
temporibus sed id numquam nemo error ipsa adipisci perferendis.
|
||||
Consequuntur vitae tenetur dolore.
|
||||
</p>
|
||||
<p className="text-lg lg:text-2xl leading-tight">
|
||||
Eveniet doloremque ducimus deserunt labore, distinctio odit sunt
|
||||
mollitia ab repellat excepturi aliquam fuga impedit! Maiores porro
|
||||
qui consequatur nisi voluptates, odit facere nobis corrupti labore
|
||||
ducimus cumque! Voluptates, beatae?
|
||||
</p>
|
||||
<Button type="primary" variant="outlined" className="group">
|
||||
View all projects
|
||||
<ChevronRightIcon className="h-5 w-5 ml-2 group-hover:translate-x-1" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="py-12">
|
||||
<Gallery />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
async function Gallery() {
|
||||
const projects = await prisma.project.findMany({
|
||||
where: {
|
||||
feature: true,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-20">
|
||||
{projects.map((project) => (
|
||||
<div
|
||||
key={project.id}
|
||||
className="lg:w-3/5 py-8 lg:not-even:self-end space-y-8 border-b"
|
||||
>
|
||||
<div className="bg-gray-100 aspect-video relative shadow rounded overflow-clip">
|
||||
{project.image && (
|
||||
<Image
|
||||
src={project.image}
|
||||
alt={project.title}
|
||||
fill={true}
|
||||
className="object-cover"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col lg:flex-row justify-between lg:items-center gap-4 items-start">
|
||||
<h3 className="text-2xl lg:text-4xl text-accent-700">
|
||||
{project.title}
|
||||
</h3>
|
||||
<Button type="alternate" variant="outlined" className="group">
|
||||
View project{" "}
|
||||
<ChevronRightIcon className="h-5 w-5 ml-2 transition group-hover:translate-x-1" />
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-gray-500 text-lg lg:text-2xl">{project.summary}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
13
src/app/(frontend)/components/home/ScrollToSection.tsx
Normal file
13
src/app/(frontend)/components/home/ScrollToSection.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
"use client";
|
||||
import { ArrowDownCircleIcon } from "@heroicons/react/20/solid";
|
||||
|
||||
export default function ScrollToSection({ anchor }: { anchor: string }) {
|
||||
return (
|
||||
<ArrowDownCircleIcon
|
||||
className="h-10 text-white cursor-pointer opacity-20 hover:opacity-100"
|
||||
onClick={() => {
|
||||
document.querySelector(anchor)?.scrollIntoView({ behavior: "smooth" });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
23
src/app/(frontend)/components/ui/Button.tsx
Normal file
23
src/app/(frontend)/components/ui/Button.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
export default function Button({
|
||||
children,
|
||||
type,
|
||||
variant,
|
||||
className,
|
||||
...props
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
type: "primary" | "secondary" | "alternate";
|
||||
variant?: "filled" | "outlined";
|
||||
className?: string;
|
||||
// [x: string]:
|
||||
}) {
|
||||
const btnVariant = variant ?? "filled";
|
||||
return (
|
||||
<button
|
||||
className={`button-${type} button-${btnVariant} transition whitespace-nowrap flex items-center ${className}`}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
@ -1,21 +1,30 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import configPromise from "@payload-config";
|
||||
import { getPayload } from "payload";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
import "../globals.css";
|
||||
import Header from "./components/Header/Header";
|
||||
|
||||
import { Inter } from "next/font/google";
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
variable: "--font-inter",
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const payload = await getPayload({ config: configPromise });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
const homeHero = await payload.findGlobal({
|
||||
slug: "homeHero",
|
||||
});
|
||||
|
||||
return {
|
||||
title: homeHero.metaTitle,
|
||||
description: homeHero.metaDescription,
|
||||
};
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
@ -24,10 +33,10 @@ export default function RootLayout({
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
{children}
|
||||
<body className={`${inter.variable} antialiased`}>
|
||||
<Header />
|
||||
<div className="">{children}</div>
|
||||
{/* <Footer /> */}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@ -1,41 +1,11 @@
|
||||
import configPromise from "@payload-config";
|
||||
import { RichText } from "@payloadcms/richtext-lexical/react";
|
||||
import Link from "next/link";
|
||||
import { getPayload } from "payload";
|
||||
import CTA from "./components/home/CTA";
|
||||
import Hero from "./components/home/Hero";
|
||||
|
||||
export default async function Page() {
|
||||
const payload = await getPayload({ config: configPromise });
|
||||
|
||||
const newsItems = await payload.find({
|
||||
collection: "news",
|
||||
depth: 1,
|
||||
limit: 5,
|
||||
select: {
|
||||
title: true,
|
||||
content: true,
|
||||
},
|
||||
sort: "-created_at",
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>My Homepage</h1>
|
||||
<p>My Homepage content.</p>
|
||||
|
||||
<h2>
|
||||
<Link href="/news">Latest News</Link>
|
||||
</h2>
|
||||
<ul>
|
||||
{newsItems.docs.map((newsItem) => (
|
||||
<li key={newsItem.id} className="p-4">
|
||||
<h3 className="text-2xl">{newsItem.title}</h3>
|
||||
<RichText
|
||||
data={newsItem.content}
|
||||
className="prose bg-gray-50 p-2"
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<>
|
||||
<Hero />
|
||||
<CTA />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
119
src/app/globals.css
Normal file
119
src/app/globals.css
Normal file
@ -0,0 +1,119 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
|
||||
--header-height: 175px;
|
||||
|
||||
--color-primary: var(--rojo);
|
||||
|
||||
--color-accent-50: #fff1f2;
|
||||
--color-accent-100: #ffe1e3;
|
||||
--color-accent-200: #ffc8cc;
|
||||
--color-accent-300: #ffa1a8;
|
||||
--color-accent-400: #fe6b76;
|
||||
--color-accent-500: #f73c49;
|
||||
--color-accent-600: #e52331;
|
||||
--color-accent-700: #c01521;
|
||||
--color-accent-800: #9f151f;
|
||||
--color-accent-900: #841820;
|
||||
--color-accent-950: #48070c;
|
||||
|
||||
--color-secondary-50: #f5f8f5;
|
||||
--color-secondary-100: #e8f0e9;
|
||||
--color-secondary-200: #d2e0d3;
|
||||
--color-secondary-300: #aec7af;
|
||||
--color-secondary-400: #82a684;
|
||||
--color-secondary-500: #5f8862;
|
||||
--color-secondary-600: #4b6e4d;
|
||||
--color-secondary-700: #415d43;
|
||||
--color-secondary-800: #344735;
|
||||
--color-secondary-900: #2c3b2d;
|
||||
--color-secondary-950: #141f16;
|
||||
}
|
||||
|
||||
/*
|
||||
The default border color has changed to `currentColor` in Tailwind CSS v4,
|
||||
so we've added these compatibility styles to make sure everything still
|
||||
looks the same as it did with Tailwind CSS v3.
|
||||
|
||||
If we ever want to remove these styles, we need to add an explicit border
|
||||
color utility to any element that depends on these defaults.
|
||||
*/
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentColor);
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
|
||||
/* https://coolors.co/000000-ffffff-e52331-709775-415d43 */
|
||||
--black: #000000;
|
||||
--white: #ffffff;
|
||||
--rojo: #e52331;
|
||||
--cambridge-blue: #709775;
|
||||
--hunter-green: #415d43;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
font-family: var(--font-inter);
|
||||
}
|
||||
|
||||
@utility button-default {
|
||||
@apply font-bold py-2 px-4 rounded-sm cursor-pointer;
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.button-primary {
|
||||
@apply button-default;
|
||||
}
|
||||
.button-primary.button-filled {
|
||||
@apply bg-accent-800 text-accent-100;
|
||||
}
|
||||
.button-primary.button-outlined {
|
||||
@apply border border-accent-800 text-accent-800 hover:bg-accent-800 hover:text-accent-100;
|
||||
}
|
||||
|
||||
.button-secondary {
|
||||
@apply button-default;
|
||||
/* bg-secondary-800 text-secondary-100 hover:bg-linear-to-tr hover:from-secondary-700 hover:to-secondary-800 hover:text-secondary-50; */
|
||||
}
|
||||
.button-secondary.button-filled {
|
||||
@apply bg-secondary-800 text-secondary-100;
|
||||
}
|
||||
.button-secondary.button-outlined {
|
||||
@apply border border-secondary-800 text-secondary-800 hover:bg-secondary-800 hover:text-secondary-100;
|
||||
}
|
||||
|
||||
.button-alternate {
|
||||
@apply button-default;
|
||||
}
|
||||
.button-alternate.button-filled {
|
||||
@apply bg-black text-white;
|
||||
}
|
||||
.button-alternate.button-outlined {
|
||||
@apply border border-black text-black hover:bg-black hover:text-white;
|
||||
}
|
||||
|
||||
.button-large {
|
||||
@apply button-default;
|
||||
@apply text-3xl px-8 py-4;
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
import { GlobalConfig } from "payload";
|
||||
|
||||
export const Home: GlobalConfig = {
|
||||
slug: 'home',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
label: 'Title',
|
||||
type: 'text',
|
||||
defaultValue: 'Analytics, research, and data visualisation that make a difference'
|
||||
},
|
||||
{
|
||||
name: 'heroTitle',
|
||||
label: 'Hero Title',
|
||||
type: 'text',
|
||||
defaultValue: 'We help people tell stories with data'
|
||||
},
|
||||
{
|
||||
name: 'heroDescription',
|
||||
label: 'Hero Description',
|
||||
type: 'richText',
|
||||
},
|
||||
{
|
||||
name: 'heroItems',
|
||||
label: 'Hero Items',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
type: 'text',
|
||||
required: true,
|
||||
}
|
||||
],
|
||||
defaultValue: ["Data design", "Data collection", "Data analysis", "Data visualisation", "Training", "Data sovereignty"].map((item) => ({
|
||||
name: item,
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'projectsTitle',
|
||||
label: 'Projects Title',
|
||||
type: 'text',
|
||||
defaultValue: 'We do data differently'
|
||||
},
|
||||
{
|
||||
name: 'projectsDescription',
|
||||
label: 'Projects Description',
|
||||
type: 'richText'
|
||||
}
|
||||
],
|
||||
};
|
||||
83
src/globals/Home/Hero.ts
Normal file
83
src/globals/Home/Hero.ts
Normal file
@ -0,0 +1,83 @@
|
||||
import { GlobalConfig } from "payload";
|
||||
|
||||
export const HomeHero: GlobalConfig = {
|
||||
slug: 'homeHero',
|
||||
label: 'Hero',
|
||||
fields: [
|
||||
{
|
||||
name: 'titleGroup',
|
||||
label: 'Landing page',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
label: 'Title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
defaultValue: 'Analytics, research, and data visualisation that make a difference'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'heroGroup',
|
||||
label: 'Hero',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
name: 'heroTitle',
|
||||
label: 'Hero Title',
|
||||
type: 'text',
|
||||
required: true,
|
||||
defaultValue: 'We help people tell stories with data'
|
||||
},
|
||||
{
|
||||
name: 'heroDescription',
|
||||
label: 'Hero Description',
|
||||
type: 'richText',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'heroItems',
|
||||
label: 'Items',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
type: 'text',
|
||||
required: true,
|
||||
}
|
||||
],
|
||||
defaultValue: ["Data design", "Data collection", "Data analysis", "Data visualisation", "Training", "Data sovereignty"].map((item) => ({
|
||||
name: item,
|
||||
})),
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'metaTitle',
|
||||
label: 'Meta Title',
|
||||
type: 'text',
|
||||
defaultValue: 'iNZight Analytics Ltd',
|
||||
required: true,
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
description: 'This title will be used for SEO purposes, and displayed in the browser tab.',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'metaDescription',
|
||||
label: 'Meta Description',
|
||||
type: 'textarea',
|
||||
required: true,
|
||||
defaultValue: 'iNZight Analytics Ltd is a New Zealand-based company that provides data analysis and visualisation services.',
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
description: 'This description will be used for SEO purposes (e.g., shown in search results and on social media cards).',
|
||||
}
|
||||
},
|
||||
],
|
||||
admin: {
|
||||
group: 'Home page'
|
||||
}
|
||||
};
|
||||
22
src/globals/Home/Projects.ts
Normal file
22
src/globals/Home/Projects.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { GlobalConfig } from "payload";
|
||||
|
||||
export const HomeProjects: GlobalConfig = {
|
||||
slug: 'homeProjects',
|
||||
label: 'Projects',
|
||||
fields: [
|
||||
{
|
||||
name: 'projectsTitle',
|
||||
label: 'Projects Title',
|
||||
type: 'text',
|
||||
defaultValue: 'We do data differently'
|
||||
},
|
||||
{
|
||||
name: 'projectsDescription',
|
||||
label: 'Projects Description',
|
||||
type: 'richText'
|
||||
}
|
||||
],
|
||||
admin: {
|
||||
group: 'Home page'
|
||||
}
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user