diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..b512c09d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/api/package.json b/api/package.json
index 0a3cb7e5..6cd2965e 100644
--- a/api/package.json
+++ b/api/package.json
@@ -11,9 +11,6 @@
"start": "node dist/index.js",
"dev": "nodemon index.ts",
"email": "email dev",
- "start-web": "cd ../web && yarn run dev",
- "start-api": "yarn run dev",
- "con": "concurrently \"yarn run start-api\" \"yarn run start-web\"",
"db:generate": "drizzle-kit generate",
"db:migrate": "node -r esbuild-register ./scripts/migrate.ts",
"db:seed": "node -r esbuild-register ./scripts/seed.ts",
@@ -28,7 +25,6 @@
"@types/node": "^20.11.17",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.18",
- "concurrently": "^8.2.2",
"drizzle-kit": "^0.22.1",
"nodemon": "^3.0.3",
"typescript": "^5.3.3"
diff --git a/api/yarn.lock b/api/yarn.lock
index 76ec0c6c..8e0a4274 100644
--- a/api/yarn.lock
+++ b/api/yarn.lock
@@ -10,13 +10,6 @@
lodash.assignwith "^4.2.0"
typical "^7.1.1"
-"@babel/runtime@^7.21.0":
- version "7.24.5"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz"
- integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==
- dependencies:
- regenerator-runtime "^0.14.0"
-
"@blakeembrey/deque@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@blakeembrey/deque/-/deque-1.0.5.tgz#f4fa17fc5ee18317ec01a763d355782c7b395eaf"
@@ -764,21 +757,6 @@ concat-map@0.0.1:
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-concurrently@^8.2.2:
- version "8.2.2"
- resolved "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz"
- integrity sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==
- dependencies:
- chalk "^4.1.2"
- date-fns "^2.30.0"
- lodash "^4.17.21"
- rxjs "^7.8.1"
- shell-quote "^1.8.1"
- spawn-command "0.0.2"
- supports-color "^8.1.1"
- tree-kill "^1.2.2"
- yargs "^17.7.2"
-
content-disposition@0.5.4:
version "0.5.4"
resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz"
@@ -840,13 +818,6 @@ csstype@^3.0.2:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
-date-fns@^2.30.0:
- version "2.30.0"
- resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
- integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
- dependencies:
- "@babel/runtime" "^7.21.0"
-
debug@2.6.9:
version "2.6.9"
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
@@ -1821,11 +1792,6 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
-regenerator-runtime@^0.14.0:
- version "0.14.1"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
- integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
-
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@@ -1836,13 +1802,6 @@ resolve-pkg-maps@^1.0.0:
resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f"
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
-rxjs@^7.8.1:
- version "7.8.1"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
- integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
- dependencies:
- tslib "^2.1.0"
-
safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
@@ -1923,11 +1882,6 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-shell-quote@^1.8.1:
- version "1.8.1"
- resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz"
- integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==
-
side-channel@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz"
@@ -1987,11 +1941,6 @@ sparse-bitfield@^3.0.3:
dependencies:
memory-pager "^1.0.2"
-spawn-command@0.0.2:
- version "0.0.2"
- resolved "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz"
- integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==
-
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz"
@@ -2063,13 +2012,6 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
-supports-color@^8.1.1:
- version "8.1.1"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz"
- integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
- dependencies:
- has-flag "^4.0.0"
-
swr@2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/swr/-/swr-2.2.0.tgz"
@@ -2150,7 +2092,7 @@ ts-node@^10.9.1, ts-node@^10.9.2:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
-tslib@2.4.1, tslib@^2.0.3, tslib@^2.1.0:
+tslib@2.4.1, tslib@^2.0.3:
version "2.4.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz"
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
@@ -2331,7 +2273,7 @@ yargs-parser@^21.1.1:
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
-yargs@^17.1.1, yargs@^17.7.2:
+yargs@^17.1.1:
version "17.7.2"
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..c2cd59ef
--- /dev/null
+++ b/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "auis-portal",
+ "version": "1.0.0",
+ "repository": "https://github.com/UoaWDCC/auis-portal.git",
+ "license": "MIT",
+ "scripts": {
+ "setup": "yarn && cd ./web && yarn && cd ../strapi && yarn && cd ../api && yarn",
+ "dev": "concurrently \"cd ./database && docker compose up\" \"cd ./web && yarn dev\" \"cd ./strapi && yarn develop\" \"cd ./api && yarn dev\"",
+ "build": "cd ./web && yarn build && cd ../strapi && yarn build && cd ../api && yarn build"
+ },
+ "devDependencies": {
+ "concurrently": "^8.2.2"
+ }
+}
diff --git a/web/__test__/TestScreen.test.tsx b/web/__test__/TestScreen.test.tsx
deleted file mode 100644
index a460a230..00000000
--- a/web/__test__/TestScreen.test.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { expect, it } from "vitest";
-import { render, screen } from "@testing-library/react";
-import React from "react";
-import TestScreen from "../src/screens/Test";
-import { describe } from "node:test";
-import '@testing-library/jest-dom'
-
-describe("TestScreen component", () => {
- it("should display the 'Test' message", () => {
- render();
- const message = screen.getByText(/Test/i);
- expect(message).toBeInTheDocument();
- });
-});
diff --git a/web/__test__/Footer.test.tsx b/web/__test__/components/Footer.test.tsx
similarity index 87%
rename from web/__test__/Footer.test.tsx
rename to web/__test__/components/Footer.test.tsx
index 277c9c6f..75a7b552 100644
--- a/web/__test__/Footer.test.tsx
+++ b/web/__test__/components/Footer.test.tsx
@@ -1,11 +1,11 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import { describe, it, expect, vi } from "vitest";
-import Footer from "../src/components/Footer";
+import Footer from "../../src/components/Footer";
import "@testing-library/jest-dom";
// Mock the Socials component
-vi.mock("../src/components/Socials", () => ({
+vi.mock("../../src/components/Socials", () => ({
default: () =>
-
- Our Upcoming Events!
-
+ const { loading, data, error } = useQuery(GET_SOME_PHOTOS);
+ if (loading) return
;
+ if (error) return
CMS Offline
;
+ const photos: SomePhoto[] = Mapper.mapToSomePhotos(data);
+ return (
+
+
+ Our Upcoming Events!
+
+
+
+ {photos.map((photo) => (
+
+
+
+
+
{photo.title}
+ {photo.year}
+
+
+
+ ))}
- >
- );
- }
-
- export default SomePhotos;
-
\ No newline at end of file
+
+
+ );
+}
+
+export default SomePhotos;
diff --git a/web/src/components/Values.tsx b/web/src/components/Values.tsx
new file mode 100644
index 00000000..19b76ecf
--- /dev/null
+++ b/web/src/components/Values.tsx
@@ -0,0 +1,36 @@
+import { useQuery } from "@apollo/client";
+import { GET_VALUES } from "../graphql/queries";
+import LoadingSpinner from "./LoadingSpinner";
+import { Value } from "../types/types";
+import { Mapper } from "../utils/Mapper";
+
+function Values() {
+ const { loading, data, error } = useQuery(GET_VALUES);
+ if (loading) return
;
+ if (error) return
CMS Offline
;
+ const values: Value[] = Mapper.mapToValue(data);
+
+ return (
+
+
+ {values.map((value) => (
+
+
+
+
+
{value.title}
+ {value.description}
+
+
+
+ ))}
+
+
+ );
+}
+
+export default Values;
diff --git a/web/src/data/data.ts b/web/src/data/data.ts
index 2eed2ac7..42afe2d3 100644
--- a/web/src/data/data.ts
+++ b/web/src/data/data.ts
@@ -1,50 +1,3 @@
-import type { Exec } from "../types/types";
-
-export const execs: Exec[] = [
- {
- id: 1,
- image: "exec.png",
- position: "President",
- name: "Manas Sonar",
- bio: "Consectetur adipiscing elit",
- },
- {
- id: 2,
- image: "exec.png",
- position: "Vice-President",
- name: "Sanchani Brabhaharan",
- bio: "Consectetur adipiscing elit...",
- },
- {
- id: 3,
- image: "exec.png",
- position: "Secretary",
- name: "Diya Chottera",
- bio: "Consectetur adipiscing elit...",
- },
- {
- id: 4,
- image: "exec.png",
- position: "Treasurer",
- name: "Krish Kumar",
- bio: "Consectetur adipiscing elit...",
- },
- {
- id: 5,
- image: "exec.png",
- position: "Secretary",
- name: "Diya Chottera",
- bio: "Consectetur adipiscing elit...",
- },
- {
- id: 6,
- image: "exec.png",
- position: "Treasurer",
- name: "Krish Kumar",
- bio: "Consectetur adipiscing elit...",
- },
-];
-
export const FacebookLink = "https://www.facebook.com/auis.uoa/";
export const InstagramLink =
"https://www.instagram.com/au.indiansociety/?hl=en";
diff --git a/web/src/graphql/queries.ts b/web/src/graphql/queries.ts
index 7fe21598..ad1c4520 100644
--- a/web/src/graphql/queries.ts
+++ b/web/src/graphql/queries.ts
@@ -6,10 +6,106 @@ export const GET_EXECS = gql`
data {
id
attributes {
- name
- bio
- position
- image {
+ Name
+ Description
+ Position
+ Role
+ Image {
+ data {
+ attributes {
+ url
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`;
+
+export const GET_PARTNERS = gql`
+ query {
+ partners {
+ data {
+ id
+ attributes {
+ Type
+ Name
+ Location
+ Description
+ Image {
+ data {
+ attributes {
+ url
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`;
+
+export const GET_INTRODUCTION = gql`
+ query {
+ introductions {
+ data {
+ id
+ attributes {
+ Description
+ Events
+ Members
+ Followers
+ }
+ }
+ }
+ }
+`;
+
+export const GET_SOCIALS = gql`
+ query {
+ socials {
+ data {
+ id
+ attributes {
+ Type
+ Link
+ }
+ }
+ }
+ }
+`;
+
+export const GET_SOME_PHOTOS = gql`
+ query {
+ somePhotos {
+ data {
+ id
+ attributes {
+ Title
+ Year
+ Image {
+ data {
+ attributes {
+ url
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`;
+
+export const GET_VALUES = gql`
+ query {
+ values {
+ data {
+ id
+ attributes {
+ Title
+ Description
+ Image {
data {
attributes {
url
diff --git a/web/src/main.tsx b/web/src/main.tsx
index 5c6d9d5b..6307d6dd 100644
--- a/web/src/main.tsx
+++ b/web/src/main.tsx
@@ -20,6 +20,7 @@ import PVVScreen from "./screens/PVVScreen.tsx";
import LoginScreen from "./screens/LoginScreen.tsx";
import { ClerkProvider } from "@clerk/clerk-react";
import { graphqlClient } from "./graphql/client.ts";
+import CreditsScreen from "./screens/CreditsScreen.tsx";
//Add any routes for screens below
const router = createBrowserRouter(
@@ -27,6 +28,7 @@ const router = createBrowserRouter(
}>
} />
} />
+
} />
} />
} />
} />
diff --git a/web/src/screens/ExecScreen.tsx b/web/src/screens/ExecScreen.tsx
index 3b49b964..1a0bd9fc 100644
--- a/web/src/screens/ExecScreen.tsx
+++ b/web/src/screens/ExecScreen.tsx
@@ -1,15 +1,15 @@
import ReactMarkdown from "react-markdown";
import type { Exec } from "../types/types";
-import { mapToExec } from "../utils/mapToExec";
import { useQuery } from "@apollo/client";
import { GET_EXECS } from "../graphql/queries";
import LoadingSpinner from "../components/LoadingSpinner";
+import { Mapper } from "../utils/Mapper";
function ExecScreen() {
const { loading, data, error } = useQuery(GET_EXECS);
if (loading) return
;
if (error) return
CMS Offline
;
- const execs: Exec[] = mapToExec(data);
+ const execs: Exec[] = Mapper.mapToExec(data);
return (
@@ -26,7 +26,8 @@ function ExecScreen() {
{exec.name}
{exec.position}
-
{exec.bio}
+
{exec.description}
+
{exec.role}
**Test**
diff --git a/web/src/screens/Test.tsx b/web/src/screens/Test.tsx
index 66b520b8..00b70dd3 100644
--- a/web/src/screens/Test.tsx
+++ b/web/src/screens/Test.tsx
@@ -1,9 +1,17 @@
// import {SignedIn, SignedOut, SignInButton, UserButton} from "@clerk/clerk-react";
+import SomePhotos from "../components/SomePhotos";
+import Partners from "../components/Partners";
+import Values from "../components/Values";
+import Introductions from "@components/Introductions";
+
function TestScreen() {
return (
-
-
Test Screen
+
);
}
diff --git a/web/src/types/types.ts b/web/src/types/types.ts
index 097a2fdc..1db044c1 100644
--- a/web/src/types/types.ts
+++ b/web/src/types/types.ts
@@ -2,10 +2,48 @@ export interface Exec {
id: number;
image: string;
position: string;
+ role: string;
name: string;
- bio: string;
+ description: string;
}
export interface Props {
execs: Exec[];
}
+
+export interface Partner {
+ id: number;
+ type: string;
+ name: string;
+ description: string;
+ image: string;
+ location: string;
+}
+
+export interface Social {
+ id: number;
+ type: string;
+ link: string;
+}
+
+export interface SomePhoto {
+ id: number;
+ title: string;
+ year: string;
+ image: string;
+}
+
+export interface Value {
+ id: number;
+ title: string;
+ description: string;
+ image: string;
+}
+
+export interface Introduction {
+ id: number;
+ description: string;
+ events: string;
+ members: string;
+ followers: string;
+}
diff --git a/web/src/utils/Mapper.ts b/web/src/utils/Mapper.ts
new file mode 100644
index 00000000..5b1a82dd
--- /dev/null
+++ b/web/src/utils/Mapper.ts
@@ -0,0 +1,96 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import type {
+ Exec,
+ Partner,
+ Social,
+ SomePhoto,
+ Value,
+ Introduction,
+} from "../types/types";
+
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export class Mapper {
+ static mapToExec(data: any): Exec[] {
+ return data.execs.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ const imageUrl = attributes.Image?.data?.attributes?.url || "";
+
+ return {
+ id: item.id,
+ name: attributes.Name || "",
+ description: attributes.Description || "",
+ position: attributes.Position || "",
+ role: attributes.Role || "",
+ image: imageUrl,
+ };
+ });
+ }
+
+ static mapToPartner(data: any): Partner[] {
+ return data.partners.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ const imageUrl = attributes.Image?.data?.attributes?.url || "";
+
+ return {
+ id: item.id,
+ type: attributes.Type || "",
+ name: attributes.Name || "",
+ description: attributes.Description || "",
+ location: attributes.Location || "",
+ image: imageUrl,
+ };
+ });
+ }
+
+ static mapToSocials(data: any): Social[] {
+ return data.socials.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ return {
+ id: item.id,
+ type: attributes.Type || "",
+ link: attributes.Link || "",
+ };
+ });
+ }
+
+ static mapToSomePhotos(data: any): SomePhoto[] {
+ return data.somePhotos.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ const imageUrl = attributes.Image?.data?.attributes?.url || "";
+
+ return {
+ id: item.id,
+ title: attributes.Title || "",
+ year: attributes.Year || "",
+ image: imageUrl,
+ };
+ });
+ }
+
+ static mapToValue(data: any): Value[] {
+ return data.values.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ const imageUrl = attributes.Image?.data?.attributes?.url || "";
+
+ return {
+ id: item.id,
+ title: attributes.Title || "",
+ description: attributes.Description || "",
+ image: imageUrl,
+ };
+ });
+ }
+
+ static mapToIntroduction = (data: any): Introduction[] => {
+ return data.introductions.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ return {
+ id: item.id,
+ description: attributes.Description || "",
+ events: attributes.Events || "",
+ members: attributes.Members || "",
+ followers: attributes.Followers || "",
+ };
+ });
+ };
+}
diff --git a/web/src/utils/mapToExec.ts b/web/src/utils/mapToExec.ts
deleted file mode 100644
index f026938d..00000000
--- a/web/src/utils/mapToExec.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { Exec } from "../types/types";
-
-// biome-ignore lint/suspicious/noExplicitAny: Need type any for handling CMS
-export const mapToExec = (data: any): Exec[] => {
- // biome-ignore lint/suspicious/noExplicitAny: Need type any for handling CMS
- return data.execs.data.map((item: any) => {
- const attributes = item.attributes || {};
- const imageUrl = attributes.image?.data?.attributes?.url || "";
-
- return {
- id: item.id,
- name: attributes.name || "",
- bio: attributes.bio || "",
- position: attributes.position || "",
- image: imageUrl,
- };
- });
-};
diff --git a/web/src/utils/mapToValue.ts b/web/src/utils/mapToValue.ts
new file mode 100644
index 00000000..904cab62
--- /dev/null
+++ b/web/src/utils/mapToValue.ts
@@ -0,0 +1,18 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import type { Value } from "../types/types";
+
+// biome-ignore lint/suspicious/noExplicitAny: Need type any for handling CMS
+export const mapToValue = (data: any): Value[] => {
+ // biome-ignore lint/suspicious/noExplicitAny: Need type any for handling CMS
+ return data.values.data.map((item: any) => {
+ const attributes = item.attributes || {};
+ const imageUrl = attributes.Image?.data?.attributes?.url || "";
+
+ return {
+ id: item.id,
+ title: attributes.Title || "",
+ description: attributes.Description || "",
+ image: imageUrl,
+ };
+ });
+};
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 00000000..c2c3d50d
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,202 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/runtime@^7.21.0":
+ version "7.24.7"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12"
+ integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^4.0.0, ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+chalk@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+cliui@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
+ integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.1"
+ wrap-ansi "^7.0.0"
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+concurrently@^8.2.2:
+ version "8.2.2"
+ resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.2.2.tgz#353141985c198cfa5e4a3ef90082c336b5851784"
+ integrity sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==
+ dependencies:
+ chalk "^4.1.2"
+ date-fns "^2.30.0"
+ lodash "^4.17.21"
+ rxjs "^7.8.1"
+ shell-quote "^1.8.1"
+ spawn-command "0.0.2"
+ supports-color "^8.1.1"
+ tree-kill "^1.2.2"
+ yargs "^17.7.2"
+
+date-fns@^2.30.0:
+ version "2.30.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
+ integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
+ dependencies:
+ "@babel/runtime" "^7.21.0"
+
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
+escalade@^3.1.1:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
+ integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
+
+get-caller-file@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
+ integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+is-fullwidth-code-point@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+ integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
+lodash@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+regenerator-runtime@^0.14.0:
+ version "0.14.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
+ integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
+
+require-directory@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+ integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+
+rxjs@^7.8.1:
+ version "7.8.1"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
+ integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
+ dependencies:
+ tslib "^2.1.0"
+
+shell-quote@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680"
+ integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==
+
+spawn-command@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e"
+ integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==
+
+string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-color@^8.1.1:
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
+tree-kill@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
+ integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
+
+tslib@^2.1.0:
+ version "2.6.3"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
+ integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
+
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
+y18n@^5.0.5:
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+ integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
+yargs-parser@^21.1.1:
+ version "21.1.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+ integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+
+yargs@^17.7.2:
+ version "17.7.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
+ integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
+ dependencies:
+ cliui "^8.0.1"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.3"
+ y18n "^5.0.5"
+ yargs-parser "^21.1.1"