From bf122cd7f565a39bfce98168354e4af89e00085e Mon Sep 17 00:00:00 2001 From: ayana Date: Tue, 24 Sep 2024 21:35:35 -0700 Subject: [PATCH 01/10] initial CMS commit --- next.config.mjs | 9 ++++- .../sections/events/CurrentEvents/index.tsx | 39 ++++++++++++++++--- src/lib/teamMemberData.json | 2 +- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 4678774..2aec8dd 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,11 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = {images: { + remotePatterns: [ + { + protocol: "https", + hostname: "images.ctfassets.net", + }, + ], + },}; export default nextConfig; diff --git a/src/app/sections/events/CurrentEvents/index.tsx b/src/app/sections/events/CurrentEvents/index.tsx index af45f02..839afc0 100644 --- a/src/app/sections/events/CurrentEvents/index.tsx +++ b/src/app/sections/events/CurrentEvents/index.tsx @@ -1,18 +1,45 @@ +'use client' import EventCard from "@/components/EventCard"; -import eventData from "@/lib/eventsData.json" +import eventData from "@/lib/eventsData.json"; +import {useEffect, useState} from 'react'; +// revise the type declarations -- using any might not be best practice +// people -- socials +// types in the code -- type safety +// finish CMS and work on other content models export default function CurrentEvents() { + + const [data, setData] = useState(null); +// clarifying binary data or formatting in client when making request + + const request_data = useEffect(() => { + async function fetchdata() { + const res = await fetch(""); + const result = await res.json(); + setData(result); + } + fetchdata() + }, []) + + console.log(data); return (
- {eventData.map((thisEvent, index) =>{ - return( - - ) - } )} + {data?.items.map((thisEvent: any, index: any) => { + const { title, time, location } = thisEvent.fields; + + return ( + + ); + })}
diff --git a/src/lib/teamMemberData.json b/src/lib/teamMemberData.json index 54dc29d..e77c3fa 100644 --- a/src/lib/teamMemberData.json +++ b/src/lib/teamMemberData.json @@ -4,7 +4,7 @@ "name": "Matthew Wong", "position": "President", "major": "Computing Science", - "src": "/headshots/matthewwong2.jpg", + "src": "https://images.ctfassets.net/c1uwktyzlrjn/16pRayAdEwiDBS3rWnZQpo/a53ba19764d8b2dfa0ce1f3db97229d6/matthewwong2.jpg", "team": "Directors", "socials": [ { "platform": "Portfolio", "url": "https://wongmatt.dev/" }, From 78b32dbd46b721eaa28ca3f268ea20b853aec3c8 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Tue, 8 Oct 2024 22:07:08 -0700 Subject: [PATCH 02/10] added contentful library for content fetching --- package.json | 1 + pnpm-lock.yaml | 186 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 184 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3162eb8..e063e56 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "contentful": "^11.0.3", "geist": "^1.3.1", "next": "14.2.6", "posthog-js": "^1.161.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 492c915..8f66c42 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + contentful: + specifier: ^11.0.3 + version: 11.0.3 geist: specifier: ^1.3.1 version: 1.3.1(next@14.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) @@ -55,6 +58,13 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@contentful/content-source-maps@0.11.3': + resolution: {integrity: sha512-RFF9reUVU6o6A/Rm1662Ez+BhyVgcATs8yvNKIVJWvXQkwsgevLLZduAn2jU7Dl/q1EgJLeJFeuOREtk8LY3zQ==} + + '@contentful/rich-text-types@16.8.5': + resolution: {integrity: sha512-q18RJuJCOuYveGiCIjE5xLCQc5lZ3L2Qgxrlg/H2YEobDFqdtmklazRi1XwEWaK3tMg6yVXBzKKkQfLB4qW14A==} + engines: {node: '>=6.0.0'} + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -249,6 +259,9 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vercel/stega@0.1.2': + resolution: {integrity: sha512-P7mafQXjkrsoyTRppnt0N21udKS9wUmLXHRyP9saLXLHw32j/FgUJ3FscSWgvSqRs4cj7wKZtwqJEvWJ2jbGmA==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -333,6 +346,9 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -341,6 +357,9 @@ packages: resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} engines: {node: '>=4'} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -399,6 +418,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -406,6 +429,18 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + contentful-resolve-response@1.9.0: + resolution: {integrity: sha512-LtgPx/eREpHXOX82od48zFZbFhXzYw/NfUoYK4Qf1OaKpLzmYPE4cAY4aD+rxVgnMM5JN/mQaPCsofUlJRYEUA==} + engines: {node: '>=4.7.2'} + + contentful-sdk-core@8.3.2: + resolution: {integrity: sha512-L2LNWRXb1/5RLpLemCoP2Lzz6211xyE63GXh2nVXekvM4Dnswo+9N2D6JmWTne9zq89Izo88vOGAzzIAxb4Ukw==} + engines: {node: '>=18'} + + contentful@11.0.3: + resolution: {integrity: sha512-Pn0vPPujVFkSs/FZ7BGr63e42dO9yUcvhxZMZrqD4kXHcC5n/xOFF11wWPgH5n3ZDCOBmEuiwUYLFcgcJODP7Q==} + engines: {node: '>=18'} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -465,6 +500,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -641,6 +680,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + fast-copy@2.1.7: + resolution: {integrity: sha512-ozrGwyuCTAy7YgFCua8rmqmytECYk/JYAMXcswOcm0qvGoE3tPb7ivBeIHTOK2DiapBhDZgacIhzhQIKU5TCfA==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -679,13 +721,29 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + foreach@2.0.6: + resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==} + foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -957,12 +1015,18 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-pointer@0.6.2: + resolution: {integrity: sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -1000,6 +1064,12 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -1018,6 +1088,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1130,6 +1208,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-throttle@4.1.1: + resolution: {integrity: sha512-TuU8Ato+pRTPJoDzYD4s7ocJYcNSEZRvlxoq3hcPI2kZDZ49IQ1Wkj7/gDJc3X7XiEAAvRGtDzdXJI0tC3IL1g==} + engines: {node: '>=10'} + package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} @@ -1237,10 +1319,17 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -1475,6 +1564,10 @@ packages: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} + engines: {node: '>=16'} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -1559,6 +1652,13 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@contentful/content-source-maps@0.11.3': + dependencies: + '@vercel/stega': 0.1.2 + json-pointer: 0.6.2 + + '@contentful/rich-text-types@16.8.5': {} + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 @@ -1740,6 +1840,8 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vercel/stega@0.1.2': {} + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: acorn: 8.12.1 @@ -1847,12 +1949,22 @@ snapshots: ast-types-flow@0.0.8: {} + asynckit@0.4.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 axe-core@4.10.0: {} + axios@1.7.7: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@4.1.0: {} balanced-match@1.0.2: {} @@ -1915,10 +2027,38 @@ snapshots: color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@4.1.1: {} concat-map@0.0.1: {} + contentful-resolve-response@1.9.0: + dependencies: + fast-copy: 2.1.7 + + contentful-sdk-core@8.3.2: + dependencies: + fast-copy: 2.1.7 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + p-throttle: 4.1.1 + qs: 6.13.0 + + contentful@11.0.3: + dependencies: + '@contentful/content-source-maps': 0.11.3 + '@contentful/rich-text-types': 16.8.5 + axios: 1.7.7 + contentful-resolve-response: 1.9.0 + contentful-sdk-core: 8.3.2 + json-stringify-safe: 5.0.1 + type-fest: 4.26.1 + transitivePeerDependencies: + - debug + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -1992,6 +2132,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delayed-stream@1.0.0: {} + didyoumean@1.2.2: {} dir-glob@3.0.1: @@ -2133,7 +2275,7 @@ snapshots: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.0) eslint-plugin-react: 7.35.2(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -2164,7 +2306,7 @@ snapshots: is-bun-module: 1.1.0 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -2182,7 +2324,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): + eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -2324,6 +2466,8 @@ snapshots: esutils@2.0.3: {} + fast-copy@2.1.7: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.2: @@ -2365,15 +2509,25 @@ snapshots: flatted@3.3.1: {} + follow-redirects@1.15.9: {} + for-each@0.3.3: dependencies: is-callable: 1.2.7 + foreach@2.0.6: {} + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -2655,10 +2809,16 @@ snapshots: json-buffer@3.0.1: {} + json-pointer@0.6.2: + dependencies: + foreach: 2.0.6 + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} + json-stringify-safe@5.0.1: {} + json5@1.0.2: dependencies: minimist: 1.2.8 @@ -2695,6 +2855,10 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + lodash.merge@4.6.2: {} loose-envify@1.4.0: @@ -2710,6 +2874,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -2833,6 +3003,8 @@ snapshots: dependencies: p-limit: 3.1.0 + p-throttle@4.1.1: {} + package-json-from-dist@1.0.0: {} parent-module@1.0.1: @@ -2923,8 +3095,14 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proxy-from-env@1.1.0: {} + punycode@2.3.1: {} + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + queue-microtask@1.2.3: {} react-dom@18.3.1(react@18.3.1): @@ -3205,6 +3383,8 @@ snapshots: type-fest@0.20.2: {} + type-fest@4.26.1: {} + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 From 872f47091028801b7dde5f4877dc333f3e2f1c37 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Wed, 16 Oct 2024 01:25:09 -0700 Subject: [PATCH 03/10] implemented contentful connector with queries for certain collections --- src/app/events/page.tsx | 13 +++++--- src/lib/content/contentfulConnector.ts | 40 ++++++++++++++++++++++++ src/lib/content/types/ContentTypeEnum.ts | 5 +++ src/lib/content/types/Event.ts | 5 +++ src/lib/content/types/JobListing.ts | 1 + 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/lib/content/contentfulConnector.ts create mode 100644 src/lib/content/types/ContentTypeEnum.ts create mode 100644 src/lib/content/types/Event.ts create mode 100644 src/lib/content/types/JobListing.ts diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index 4cfcb87..67e15f8 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -1,11 +1,16 @@ -import EventsHero from "@/app/sections/events/EventsHero"; +import EventsHero from "../sections/events/EventsHero"; import JoinDiscord from "@/components/JoinDiscord"; -import CurrentEvents from "@/app/sections/events/CurrentEvents"; +import CurrentEvents from "../sections/events/CurrentEvents"; +import { + fetchEventCollection, + fetchJobListingCollection, + fetchSpace, +} from "@/lib/content/contentfulConnector"; -export default function Page() { +export default async function Page() { return (
- +
diff --git a/src/lib/content/contentfulConnector.ts b/src/lib/content/contentfulConnector.ts new file mode 100644 index 0000000..f584387 --- /dev/null +++ b/src/lib/content/contentfulConnector.ts @@ -0,0 +1,40 @@ +import * as contentful from "contentful"; +import { ContentTypeEnum } from "./types/ContentTypeEnum"; + +const contentfulClient = contentful.createClient({ + accessToken: process.env.CONTENTFUL_ACCESS_TOKEN || "", + space: process.env.CONTENTFUL_SPACE_ID || "", +}); + +export async function fetchSpace() { + const data = await contentfulClient.getSpace(); + if (data) { + return { + data: data, + }; + } +} + +export async function fetchEventCollection() { + const events = await contentfulClient.getEntries({ + content_type: ContentTypeEnum.EVENT, + }); + + if (events.items) { + return { + items: events.items, + }; + } +} + +export async function fetchJobListingCollection() { + const jobListings = await contentfulClient.getEntries({ + content_type: ContentTypeEnum.JOB_LISTING, + }); + + if (jobListings.items) { + return { + items: jobListings.items, + }; + } +} diff --git a/src/lib/content/types/ContentTypeEnum.ts b/src/lib/content/types/ContentTypeEnum.ts new file mode 100644 index 0000000..cec0e05 --- /dev/null +++ b/src/lib/content/types/ContentTypeEnum.ts @@ -0,0 +1,5 @@ +export enum ContentTypeEnum { + EVENT = "events", + JOB_LISTING = "jobListing", + TEAM_MEMBER = "teamMember", +} diff --git a/src/lib/content/types/Event.ts b/src/lib/content/types/Event.ts new file mode 100644 index 0000000..bd8392a --- /dev/null +++ b/src/lib/content/types/Event.ts @@ -0,0 +1,5 @@ +export interface Event { + title: string; + location: string; + time: string; +} diff --git a/src/lib/content/types/JobListing.ts b/src/lib/content/types/JobListing.ts new file mode 100644 index 0000000..9bd0e9f --- /dev/null +++ b/src/lib/content/types/JobListing.ts @@ -0,0 +1 @@ +export interface JobListing {} From c2cd6d2ddcbcdf3b75ecb94ba31457d20d17118b Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Wed, 16 Oct 2024 01:26:53 -0700 Subject: [PATCH 04/10] moved queries to separate file --- src/lib/content/contentfulConnector.ts | 36 +------------------------- src/lib/content/contentfulQueries.ts | 35 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 35 deletions(-) create mode 100644 src/lib/content/contentfulQueries.ts diff --git a/src/lib/content/contentfulConnector.ts b/src/lib/content/contentfulConnector.ts index f584387..5e609d4 100644 --- a/src/lib/content/contentfulConnector.ts +++ b/src/lib/content/contentfulConnector.ts @@ -1,40 +1,6 @@ import * as contentful from "contentful"; -import { ContentTypeEnum } from "./types/ContentTypeEnum"; -const contentfulClient = contentful.createClient({ +export const contentfulClient = contentful.createClient({ accessToken: process.env.CONTENTFUL_ACCESS_TOKEN || "", space: process.env.CONTENTFUL_SPACE_ID || "", }); - -export async function fetchSpace() { - const data = await contentfulClient.getSpace(); - if (data) { - return { - data: data, - }; - } -} - -export async function fetchEventCollection() { - const events = await contentfulClient.getEntries({ - content_type: ContentTypeEnum.EVENT, - }); - - if (events.items) { - return { - items: events.items, - }; - } -} - -export async function fetchJobListingCollection() { - const jobListings = await contentfulClient.getEntries({ - content_type: ContentTypeEnum.JOB_LISTING, - }); - - if (jobListings.items) { - return { - items: jobListings.items, - }; - } -} diff --git a/src/lib/content/contentfulQueries.ts b/src/lib/content/contentfulQueries.ts new file mode 100644 index 0000000..1fe81c4 --- /dev/null +++ b/src/lib/content/contentfulQueries.ts @@ -0,0 +1,35 @@ +import { contentfulClient } from "./contentfulConnector"; +import { ContentTypeEnum } from "./types/ContentTypeEnum"; + +export async function fetchSpace() { + const data = await contentfulClient.getSpace(); + if (data) { + return { + data: data, + }; + } +} + +export async function fetchEventCollection() { + const events = await contentfulClient.getEntries({ + content_type: ContentTypeEnum.EVENT, + }); + + if (events.items) { + return { + items: events.items, + }; + } +} + +export async function fetchJobListingCollection() { + const jobListings = await contentfulClient.getEntries({ + content_type: ContentTypeEnum.JOB_LISTING, + }); + + if (jobListings.items) { + return { + items: jobListings.items, + }; + } +} From 9e6ecba850835c977e1c657c07bfaca7324d8712 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Wed, 16 Oct 2024 11:12:13 -0700 Subject: [PATCH 05/10] removed unused imports --- src/app/events/page.tsx | 5 ----- src/app/sections/about/Testimonials/index.tsx | 1 - 2 files changed, 6 deletions(-) diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index 67e15f8..effa127 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -1,11 +1,6 @@ import EventsHero from "../sections/events/EventsHero"; import JoinDiscord from "@/components/JoinDiscord"; import CurrentEvents from "../sections/events/CurrentEvents"; -import { - fetchEventCollection, - fetchJobListingCollection, - fetchSpace, -} from "@/lib/content/contentfulConnector"; export default async function Page() { return ( diff --git a/src/app/sections/about/Testimonials/index.tsx b/src/app/sections/about/Testimonials/index.tsx index a2986e6..f9ccbd9 100644 --- a/src/app/sections/about/Testimonials/index.tsx +++ b/src/app/sections/about/Testimonials/index.tsx @@ -1,4 +1,3 @@ -import EventCard from "@/components/EventCard"; import TestimonialCard from "@/components/TestimonialCard"; import eventData from "@/lib/testimonials.json"; From b7e98f8c3d744781cae4fea8f5f9ae9814408799 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Wed, 16 Oct 2024 11:46:14 -0700 Subject: [PATCH 06/10] converted currentevents section to server component, with contentful query --- .../sections/events/CurrentEvents/index.tsx | 35 +++++-------------- src/lib/content/contentfulQueries.ts | 23 +++++++----- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/src/app/sections/events/CurrentEvents/index.tsx b/src/app/sections/events/CurrentEvents/index.tsx index 839afc0..5de1576 100644 --- a/src/app/sections/events/CurrentEvents/index.tsx +++ b/src/app/sections/events/CurrentEvents/index.tsx @@ -1,7 +1,5 @@ -'use client' import EventCard from "@/components/EventCard"; -import eventData from "@/lib/eventsData.json"; -import {useEffect, useState} from 'react'; +import { fetchEventCollection } from "@/lib/content/contentfulQueries"; // revise the type declarations -- using any might not be best practice // people -- socials @@ -9,39 +7,22 @@ import {useEffect, useState} from 'react'; // types in the code -- type safety // finish CMS and work on other content models -export default function CurrentEvents() { - - const [data, setData] = useState(null); - -// clarifying binary data or formatting in client when making request - - const request_data = useEffect(() => { - async function fetchdata() { - const res = await fetch(""); - const result = await res.json(); - setData(result); - } - fetchdata() - }, []) - - console.log(data); +export default async function CurrentEvents() { + let eventData = await fetchEventCollection(); return (
- {data?.items.map((thisEvent: any, index: any) => { - const { title, time, location } = thisEvent.fields; - + {eventData.map((event: any, index: any) => { + const { title, time, location } = event; return ( ); })} - -
); } diff --git a/src/lib/content/contentfulQueries.ts b/src/lib/content/contentfulQueries.ts index 1fe81c4..e7329ed 100644 --- a/src/lib/content/contentfulQueries.ts +++ b/src/lib/content/contentfulQueries.ts @@ -1,5 +1,6 @@ import { contentfulClient } from "./contentfulConnector"; import { ContentTypeEnum } from "./types/ContentTypeEnum"; +import { Event } from "./types/Event"; export async function fetchSpace() { const data = await contentfulClient.getSpace(); @@ -11,15 +12,21 @@ export async function fetchSpace() { } export async function fetchEventCollection() { - const events = await contentfulClient.getEntries({ - content_type: ContentTypeEnum.EVENT, - }); + let data: Event[] = []; - if (events.items) { - return { - items: events.items, - }; - } + try { + const events = await contentfulClient.withoutLinkResolution + .getEntries({ + content_type: ContentTypeEnum.EVENT, + }) + .then((data) => { + return data.items.map((e) => e.fields as unknown as Event); + }); + + data = events; + } catch (e) {} + + return data; } export async function fetchJobListingCollection() { From 181eb4c18e91f6d84f3ddb1cd1137706249d2750 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Thu, 17 Oct 2024 11:55:38 -0700 Subject: [PATCH 07/10] Added data shapes for events and job listings, added corresponding DTOs for serialization, integrated contentful queries into respective sections/pages --- src/app/sections/join/MainSection/index.tsx | 16 +++--- src/components/OpenRolesSection.tsx | 28 ++++----- src/lib/content/contentfulQueries.ts | 63 ++++++++++++++------- src/lib/content/types/Event.ts | 18 +++++- src/lib/content/types/JobListing.ts | 36 +++++++++++- 5 files changed, 115 insertions(+), 46 deletions(-) diff --git a/src/app/sections/join/MainSection/index.tsx b/src/app/sections/join/MainSection/index.tsx index 9cf3875..1996478 100644 --- a/src/app/sections/join/MainSection/index.tsx +++ b/src/app/sections/join/MainSection/index.tsx @@ -4,19 +4,22 @@ import Card from "@/components/Card"; import OpenRolesSection from "@/components/OpenRolesSection"; import ButtonScroll from "@/components/ButtonScroll"; import InfoItem from "@/components/InfoItem"; -import skills from "/public/join/skills.png" -import experience from "/public/join/experience.png" -import friends from "/public/join/friends.png" -import rocket from "/public/join/rocket.png" +import skills from "/public/join/skills.png"; +import experience from "/public/join/experience.png"; +import friends from "/public/join/friends.png"; +import rocket from "/public/join/rocket.png"; import text_content from "@/lib/content/text_content.json"; import HomeCard from "@/components/HomeCard"; +import { fetchJobListingCollection } from "@/lib/content/contentfulQueries"; export const metadata: Metadata = { title: "Join SFU Surge", }; -export default function JoinTeam() { +export default async function JoinTeam() { + let jobListingData = await fetchJobListingCollection(); + return (
@@ -64,7 +67,6 @@ export default function JoinTeam() { description="Connect with like-minded peers and build lasting friendships." src={friends} /> -
@@ -87,7 +89,7 @@ export default function JoinTeam() { - +
); } diff --git a/src/components/OpenRolesSection.tsx b/src/components/OpenRolesSection.tsx index 9a0e860..3aab829 100644 --- a/src/components/OpenRolesSection.tsx +++ b/src/components/OpenRolesSection.tsx @@ -1,31 +1,27 @@ "use client"; -import jobs from "@/lib/jobListing.json"; import JobCard from "@/components/JobCard"; import { teams } from "@/lib/teamData"; import { useEffect, useState } from "react"; - +import { JobListing, JobListingDTO } from "@/lib/content/types/JobListing"; import JobTeamButton from "./JobTeamButton"; -type numberOfJobs = { - name: string; - count: number; -} - type OpenRolesSectionProps = { - id: string; + jobs: JobListingDTO[]; }; -export default function OpenRolesSection({ id }: OpenRolesSectionProps) { +export default function OpenRolesSection({ jobs }: OpenRolesSectionProps) { const [activeButton, setActiveButton] = useState(null); const jobMap = new Map(); - - jobs.forEach(job => { + jobs.forEach((job) => { jobMap.set(job.team, (jobMap.get(job.team) || 0) + 1); }); - const totalJobCount = Array.from(jobMap.values()).reduce((total, count) => total + count, 0); + const totalJobCount = Array.from(jobMap.values()).reduce( + (total, count) => total + count, + 0 + ); useEffect(() => { const selectedJobTeam = localStorage.getItem("selectedJobTeam") || "All"; @@ -38,13 +34,17 @@ export default function OpenRolesSection({ id }: OpenRolesSectionProps) { }; return ( -
+
Open Roles

We want you to help us run hackathons and events

-

SFU Surge is an all-inclusive organization to promote curiosity and excitement for a future in technology, while guiding students on their paths to career success.

+

+ SFU Surge is an all-inclusive organization to promote curiosity and + excitement for a future in technology, while guiding students on their + paths to career success. +

diff --git a/src/lib/content/contentfulQueries.ts b/src/lib/content/contentfulQueries.ts index e7329ed..01f4e44 100644 --- a/src/lib/content/contentfulQueries.ts +++ b/src/lib/content/contentfulQueries.ts @@ -1,6 +1,11 @@ import { contentfulClient } from "./contentfulConnector"; import { ContentTypeEnum } from "./types/ContentTypeEnum"; -import { Event } from "./types/Event"; +import { Event, EventDTO, EventSkeleton } from "./types/Event"; +import { + JobListing, + JobListingDTO, + JobListingSkeleton, +} from "./types/JobListing"; export async function fetchSpace() { const data = await contentfulClient.getSpace(); @@ -11,32 +16,46 @@ export async function fetchSpace() { } } -export async function fetchEventCollection() { - let data: Event[] = []; - +export async function fetchEventCollection(): Promise { try { - const events = await contentfulClient.withoutLinkResolution - .getEntries({ + const events: EventDTO[] = await contentfulClient.withoutLinkResolution + .getEntries({ content_type: ContentTypeEnum.EVENT, }) - .then((data) => { - return data.items.map((e) => e.fields as unknown as Event); + .then((events) => { + return events.items.map((event) => { + const dto: EventDTO = { ...event.fields }; + return dto; + }); }); - - data = events; - } catch (e) {} - - return data; + return events; + } catch (e) { + console.log( + e, + "Event type does not match the requested content. Please check if the content type has been updated" + ); + return []; + } } -export async function fetchJobListingCollection() { - const jobListings = await contentfulClient.getEntries({ - content_type: ContentTypeEnum.JOB_LISTING, - }); - - if (jobListings.items) { - return { - items: jobListings.items, - }; +export async function fetchJobListingCollection(): Promise { + try { + const jobListings = await contentfulClient + .getEntries({ + content_type: ContentTypeEnum.JOB_LISTING, + }) + .then((jobListings) => { + return jobListings.items.map((jobListing) => { + const dto: JobListingDTO = { ...jobListing.fields }; + return dto; + }); + }); + return jobListings; + } catch (e) { + console.log( + e, + "JobListing type does not match the requested content. Please check if the content type has been updated" + ); + return []; } } diff --git a/src/lib/content/types/Event.ts b/src/lib/content/types/Event.ts index bd8392a..ccee946 100644 --- a/src/lib/content/types/Event.ts +++ b/src/lib/content/types/Event.ts @@ -1,5 +1,19 @@ -export interface Event { +import { EntryFieldType, EntryFieldTypes, EntrySkeletonType } from "contentful"; +import { ContentTypeEnum } from "./ContentTypeEnum"; + +export type EventSkeleton = { + contentTypeId: ContentTypeEnum.EVENT; + fields: Event; +}; + +export type Event = { + title: EntryFieldTypes.Text; + location: EntryFieldTypes.Text; + time: EntryFieldTypes.Text; +}; + +export type EventDTO = { title: string; location: string; time: string; -} +}; diff --git a/src/lib/content/types/JobListing.ts b/src/lib/content/types/JobListing.ts index 9bd0e9f..39b1a52 100644 --- a/src/lib/content/types/JobListing.ts +++ b/src/lib/content/types/JobListing.ts @@ -1 +1,35 @@ -export interface JobListing {} +import { EntryFieldTypes as EFT, EntrySkeletonType } from "contentful"; +import { ContentTypeEnum } from "./ContentTypeEnum"; + +export type JobListingSkeleton = { + contentTypeId: ContentTypeEnum.JOB_LISTING; + fields: JobListing; +}; + +export type JobListing = { + id: EFT.Integer; + url: EFT.Text; + team: EFT.Text; + title: EFT.Text; + description: EFT.Text; + director: EFT.Text; + about: EFT.Text; + responsibilities: EFT.Text[]; + skills: EFT.Text[]; + commitment: EFT.Text[]; + listing: EFT.Text; +}; + +export type JobListingDTO = { + id: number; + url: string; + team: string; + title: string; + description: string; + director: string; + about: string; + responsibilities: string[]; + skills: string[]; + commitment: string[]; + listing: string; +}; From e0c65245222f1cc07f14fd0050fc0a6ddd2b03e4 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Sun, 20 Oct 2024 15:35:32 -0700 Subject: [PATCH 08/10] fix type in jobId route --- src/app/sections/join/[jobId]/Index.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/sections/join/[jobId]/Index.tsx b/src/app/sections/join/[jobId]/Index.tsx index fe2741f..8388b0c 100644 --- a/src/app/sections/join/[jobId]/Index.tsx +++ b/src/app/sections/join/[jobId]/Index.tsx @@ -16,13 +16,12 @@ type Job = { }; type JobPageProps = { - job?: Job; + job?: Job; }; - export default function JobPage({ job }: JobPageProps) { const pagejob = jobs.find((role) => role.url === job?.url); - console.log(pagejob?.team) + console.log(pagejob?.team); return (
@@ -30,7 +29,7 @@ export default function JobPage({ job }: JobPageProps) {

{pagejob?.title}

- {pagejob? svgIcons[pagejob.team]:null} + {pagejob ? svgIcons[pagejob.team] : null} {pagejob?.team} @@ -51,12 +50,15 @@ export default function JobPage({ job }: JobPageProps) { {pagejob?.description} - {pagejob? svgIcons["Directors"]:null} + {pagejob ? svgIcons["Directors"] : null} {`Director of ${pagejob?.team}: ${pagejob?.director}`}
- + Apply Now
@@ -86,7 +88,7 @@ export default function JobPage({ job }: JobPageProps) {
-

Commitement

+

Commitment

    {pagejob?.commitment.map((responsibility, index) => (
  • From 5d24235e4107927dd855e8f40cffb93fec962560 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Sun, 20 Oct 2024 19:29:40 -0700 Subject: [PATCH 09/10] organized join team page and job listing page, added server-side cache to CMS requests --- .../join}/OpenRolesSection.tsx | 28 +++-- src/app/join/[jobId]/page.tsx | 119 ++++++++++++++---- src/app/join/page.tsx | 89 ++++++++++++- .../sections/events/CurrentEvents/index.tsx | 4 +- src/app/sections/join/MainSection/index.tsx | 95 -------------- src/app/sections/join/[jobId]/Index.tsx | 103 --------------- src/components/JobCard.tsx | 25 ---- src/lib/content/contentfulQueries.ts | 7 +- 8 files changed, 207 insertions(+), 263 deletions(-) rename src/{components => app/join}/OpenRolesSection.tsx (80%) delete mode 100644 src/app/sections/join/MainSection/index.tsx delete mode 100644 src/app/sections/join/[jobId]/Index.tsx delete mode 100644 src/components/JobCard.tsx diff --git a/src/components/OpenRolesSection.tsx b/src/app/join/OpenRolesSection.tsx similarity index 80% rename from src/components/OpenRolesSection.tsx rename to src/app/join/OpenRolesSection.tsx index 3aab829..6653c08 100644 --- a/src/components/OpenRolesSection.tsx +++ b/src/app/join/OpenRolesSection.tsx @@ -1,10 +1,10 @@ "use client"; -import JobCard from "@/components/JobCard"; import { teams } from "@/lib/teamData"; +import Link from "next/link"; import { useEffect, useState } from "react"; -import { JobListing, JobListingDTO } from "@/lib/content/types/JobListing"; +import { JobListingDTO } from "@/lib/content/types/JobListing"; -import JobTeamButton from "./JobTeamButton"; +import JobTeamButton from "../../components/JobTeamButton"; type OpenRolesSectionProps = { jobs: JobListingDTO[]; @@ -87,7 +87,6 @@ export default function OpenRolesSection({ jobs }: OpenRolesSectionProps) {
- {/* check if theres jobs? */} {jobs.length !== 0 ? ( // there is jobs. Does the chosen team (active button) have any roles in the array OR is the active button set to all? jobs.some((job) => job.team === activeButton) || @@ -95,13 +94,22 @@ export default function OpenRolesSection({ jobs }: OpenRolesSectionProps) { jobs.map((job, index) => // there is a role in the chosen team available. what role is available OR is it the active button thats checked? if first then spit out roles, if second spit out all activeButton === job.team || activeButton === "All" ? ( - + href={{ + pathname: `join/${job.id}`, + }} + className="w-full bg-surface rounded-3xl flex flex-col p-8 gap-4 border border-gray-500/0 hover:border-border-tertiary/10 transition-all duration-500 cursor-pointer" + > + {job.team} +

{job.title}

+

+ {job.description} +

+ + ) : // otherwise dont render anything (applies to other indexes when looping) null ) diff --git a/src/app/join/[jobId]/page.tsx b/src/app/join/[jobId]/page.tsx index 964061b..163b9ac 100644 --- a/src/app/join/[jobId]/page.tsx +++ b/src/app/join/[jobId]/page.tsx @@ -1,29 +1,106 @@ -import jobs from "@/lib/jobListing.json"; // Assuming your jobs.json file is here +import { JobListingDTO } from "@/lib/content/types/JobListing"; import { Metadata } from "next"; -import JoinTeam from "@/app/sections/join/[jobId]/Index"; +import { svgIcons } from "@/lib/teamData"; import JobError from "@/app/sections/join/JobError"; +import { getJobListingsCollection } from "@/lib/content/contentfulQueries"; -type JobPageProps = { - params: { - jobId: string; - }; +type JobListingPageProps = { + params: { jobId: string }; }; -export function generateMetadata({ - params: { jobId }, -}: JobPageProps): Metadata { - const job = jobs.find((job) => job.url === jobId); - return { - title: `${job ? job.team + " " + job.title : "Job not found "}`, - description: "job", - }; -} +// export function generateMetadata({ params }: JobListingPageProps): Metadata { +// return { +// title: `${job ? job.team + " " + job.title : "Job not found "}`, +// description: "job", +// }; +// } -export default function JobPage({ params: { jobId } }: JobPageProps) { - const job = jobs.find((role) => role.url === jobId); +export default async function JobListingPage({ params }: JobListingPageProps) { + const jobId = Number(params.jobId); + const job = await getJobListingsCollection().then((data) => + data.find((job) => job.id === jobId) + ); + return ( + <> + {job ? ( +
+
+

{job?.title}

+
+ + {job ? svgIcons[job.team] : null} + {job?.team} + + + + + + {job?.description} + + + {job ? svgIcons["Directors"] : null} + {`Director of ${job?.team}: ${job?.director}`} + +
- if (!job) { - return ; - } - return ; + + Apply Now + +
+
+
+

About this Role

+

{job?.about}

+
+
+

Responsibilities

+
    + {job?.responsibilities.map((responsibility, index) => ( +
  • + {responsibility} +
  • + ))} +
+
+
+

Skills

+
    + {job?.skills.map((responsibility, index) => ( +
  • + {responsibility} +
  • + ))} +
+
+
+

Commitment

+
    + {job?.commitment.map((responsibility, index) => ( +
  • + {responsibility} +
  • + ))} +
+
+
+
+ ) : ( + + )} + + ); } diff --git a/src/app/join/page.tsx b/src/app/join/page.tsx index bda52f2..b46cb0e 100644 --- a/src/app/join/page.tsx +++ b/src/app/join/page.tsx @@ -1,15 +1,94 @@ import type { Metadata } from "next"; import Image from "next/image"; import Card from "@/components/Card"; -import OpenRolesSection from "@/components/OpenRolesSection"; +import OpenRolesSection from "./OpenRolesSection"; import ButtonScroll from "@/components/ButtonScroll"; -import JoinTeam from "@/app/sections/join/MainSection"; -import TeamGallery from "@/app/sections/about/TeamGallery"; +import InfoItem from "@/components/InfoItem"; +import skills from "/public/join/skills.png"; +import experience from "/public/join/experience.png"; +import friends from "/public/join/friends.png"; +import rocket from "/public/join/rocket.png"; + +import text_content from "@/lib/content/text_content.json"; +import { getJobListingsCollection } from "@/lib/content/contentfulQueries"; export const metadata: Metadata = { title: "Join SFU Surge", }; -export default function joinTeam() { - return ; +export default async function JoinTeam() { + let jobListingData = await getJobListingsCollection(); + + return ( +
+
+
+

+ {text_content.join.heading} +

+

{text_content.join.description}

+ + + {text_content.join.cta} + +
+ +
+ {"hello"} +
+
+ +
+ + {text_content.join.benefits.callout} + +

+ {text_content.join.benefits.heading} +

+ +
+ + + +
+
+ +
+ + {text_content.join.opportunities.callout} + +

+ {" "} + {text_content.join.opportunities.heading} +

+

+ {text_content.join.opportunities.description} +

+
+ + + + +
+
+ + +
+ ); } diff --git a/src/app/sections/events/CurrentEvents/index.tsx b/src/app/sections/events/CurrentEvents/index.tsx index 5de1576..d4ef80c 100644 --- a/src/app/sections/events/CurrentEvents/index.tsx +++ b/src/app/sections/events/CurrentEvents/index.tsx @@ -1,5 +1,5 @@ import EventCard from "@/components/EventCard"; -import { fetchEventCollection } from "@/lib/content/contentfulQueries"; +import { getEventCollection } from "@/lib/content/contentfulQueries"; // revise the type declarations -- using any might not be best practice // people -- socials @@ -8,7 +8,7 @@ import { fetchEventCollection } from "@/lib/content/contentfulQueries"; // finish CMS and work on other content models export default async function CurrentEvents() { - let eventData = await fetchEventCollection(); + let eventData = await getEventCollection(); return (
diff --git a/src/app/sections/join/MainSection/index.tsx b/src/app/sections/join/MainSection/index.tsx deleted file mode 100644 index 1996478..0000000 --- a/src/app/sections/join/MainSection/index.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import type { Metadata } from "next"; -import Image from "next/image"; -import Card from "@/components/Card"; -import OpenRolesSection from "@/components/OpenRolesSection"; -import ButtonScroll from "@/components/ButtonScroll"; -import InfoItem from "@/components/InfoItem"; -import skills from "/public/join/skills.png"; -import experience from "/public/join/experience.png"; -import friends from "/public/join/friends.png"; -import rocket from "/public/join/rocket.png"; - -import text_content from "@/lib/content/text_content.json"; -import HomeCard from "@/components/HomeCard"; -import { fetchJobListingCollection } from "@/lib/content/contentfulQueries"; - -export const metadata: Metadata = { - title: "Join SFU Surge", -}; - -export default async function JoinTeam() { - let jobListingData = await fetchJobListingCollection(); - - return ( -
-
-
-

- {text_content.join.heading} -

-

{text_content.join.description}

- - - {text_content.join.cta} - -
- -
- {"hello"} -
-
- -
- - {text_content.join.benefits.callout} - -

- {text_content.join.benefits.heading} -

- -
- - - -
-
- -
- - {text_content.join.opportunities.callout} - -

- {" "} - {text_content.join.opportunities.heading} -

-

- {text_content.join.opportunities.description} -

-
- - - - -
-
- - -
- ); -} diff --git a/src/app/sections/join/[jobId]/Index.tsx b/src/app/sections/join/[jobId]/Index.tsx deleted file mode 100644 index 8388b0c..0000000 --- a/src/app/sections/join/[jobId]/Index.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import jobs from "@/lib/jobListing.json"; // Assuming your jobs.json file is here -import { Metadata } from "next"; -import { svgIcons } from "@/lib/teamData"; - -type Job = { - url: string; - team: string; - title: string; - description: string; - director: string; - about: string; - responsibilities: string[]; - skills: string[]; - commitment: string[]; - listing: string; -}; - -type JobPageProps = { - job?: Job; -}; - -export default function JobPage({ job }: JobPageProps) { - const pagejob = jobs.find((role) => role.url === job?.url); - console.log(pagejob?.team); - - return ( -
-
-

{pagejob?.title}

-
- - {pagejob ? svgIcons[pagejob.team] : null} - {pagejob?.team} - - - - - - {pagejob?.description} - - - {pagejob ? svgIcons["Directors"] : null} - {`Director of ${pagejob?.team}: ${pagejob?.director}`} - -
- - - Apply Now - -
-
-
-

About this Role

-

{pagejob?.about}

-
-
-

Responsibilities

-
    - {pagejob?.responsibilities.map((responsibility, index) => ( -
  • - {responsibility} -
  • - ))} -
-
-
-

Skills

-
    - {pagejob?.skills.map((responsibility, index) => ( -
  • - {responsibility} -
  • - ))} -
-
-
-

Commitment

-
    - {pagejob?.commitment.map((responsibility, index) => ( -
  • - {responsibility} -
  • - ))} -
-
-
-
- ); -} diff --git a/src/components/JobCard.tsx b/src/components/JobCard.tsx deleted file mode 100644 index 53276b7..0000000 --- a/src/components/JobCard.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import Link from "next/link"; - -type JobCardProps = { - className?: string, - title: string, - description: string, - url:string - team:string - }; - export default function JobCard({ - team, - title, - description, - url, - className, - }: JobCardProps) { - return ( - - {team} -

{title}

-

{description}

- - - ); - } \ No newline at end of file diff --git a/src/lib/content/contentfulQueries.ts b/src/lib/content/contentfulQueries.ts index 01f4e44..4fe0719 100644 --- a/src/lib/content/contentfulQueries.ts +++ b/src/lib/content/contentfulQueries.ts @@ -1,3 +1,4 @@ +import { cache } from "react"; import { contentfulClient } from "./contentfulConnector"; import { ContentTypeEnum } from "./types/ContentTypeEnum"; import { Event, EventDTO, EventSkeleton } from "./types/Event"; @@ -16,7 +17,7 @@ export async function fetchSpace() { } } -export async function fetchEventCollection(): Promise { +async function fetchEventCollection(): Promise { try { const events: EventDTO[] = await contentfulClient.withoutLinkResolution .getEntries({ @@ -37,8 +38,9 @@ export async function fetchEventCollection(): Promise { return []; } } +export const getEventCollection = cache(fetchEventCollection); -export async function fetchJobListingCollection(): Promise { +async function fetchJobListingCollection(): Promise { try { const jobListings = await contentfulClient .getEntries({ @@ -59,3 +61,4 @@ export async function fetchJobListingCollection(): Promise { return []; } } +export const getJobListingsCollection = cache(fetchJobListingCollection); From 1182c8860efd1c62f57782fe3003102882016402 Mon Sep 17 00:00:00 2001 From: ChrisFong604 Date: Sun, 20 Oct 2024 21:11:01 -0700 Subject: [PATCH 10/10] added metadata generation to individual job listing page --- .../JobError/index.tsx => join/JobError.tsx} | 0 src/app/join/[jobId]/page.tsx | 23 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) rename src/app/{sections/join/JobError/index.tsx => join/JobError.tsx} (100%) diff --git a/src/app/sections/join/JobError/index.tsx b/src/app/join/JobError.tsx similarity index 100% rename from src/app/sections/join/JobError/index.tsx rename to src/app/join/JobError.tsx diff --git a/src/app/join/[jobId]/page.tsx b/src/app/join/[jobId]/page.tsx index 163b9ac..ead1fc7 100644 --- a/src/app/join/[jobId]/page.tsx +++ b/src/app/join/[jobId]/page.tsx @@ -1,19 +1,24 @@ -import { JobListingDTO } from "@/lib/content/types/JobListing"; -import { Metadata } from "next"; import { svgIcons } from "@/lib/teamData"; -import JobError from "@/app/sections/join/JobError"; +import JobError from "../JobError"; import { getJobListingsCollection } from "@/lib/content/contentfulQueries"; +import { Metadata } from "next"; type JobListingPageProps = { params: { jobId: string }; }; -// export function generateMetadata({ params }: JobListingPageProps): Metadata { -// return { -// title: `${job ? job.team + " " + job.title : "Job not found "}`, -// description: "job", -// }; -// } +export async function generateMetadata({ + params, +}: JobListingPageProps): Promise { + const jobId = Number(params.jobId); + const job = await getJobListingsCollection().then((data) => + data.find((job) => job.id === jobId) + ); + return { + title: `${job ? job.title : "Job not found "}`, + description: "job", + }; +} export default async function JobListingPage({ params }: JobListingPageProps) { const jobId = Number(params.jobId);