diff --git a/.github/workflows/autoredeploy.yml b/.github/workflows/autoredeploy.yml
index 114348e..3986ca0 100644
--- a/.github/workflows/autoredeploy.yml
+++ b/.github/workflows/autoredeploy.yml
@@ -1,33 +1,35 @@
name: Server auto deploy
on:
- push:
- branches: ["main"]
+ push:
+ branches: ["main"]
jobs:
- docker-build:
- strategy:
- matrix:
- node-version: [20.x]
- runs-on: self-hosted
- steps:
- - uses: actions/checkout@v4
- - name: Stop and remove containers and images, using docker compose down
- run: docker-compose down --rmi "all"
- - name: Create .env files
- run: |
- # Create .env with all variables except HOST_URL Backend
- echo "HOST=${{ vars.HOST }}" >> .env
- echo "PORT=${{ vars.PORT }}" >> .env
- echo "DATABASE_CLIENT=${{ vars.DATABASE_CLIENT }}" >> .env
- echo "DATABASE_FILENAME=${{ vars.DATABASE_FILENAME }}" >> .env
- echo "ADMIN_JWT_SECRET=${{ secrets.ADMIN_JWT_SECRET }}" >> .env
- echo "API_TOKEN_SALT=${{ secrets.API_TOKEN_SALT }}" >> .env
- echo "APP_KEYS=${{ secrets.APP_KEYS }}" >> .env
- echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
- echo "TRANSFER_TOKEN_SALT=${{ secrets.TRANSFER_TOKEN_SALT }}" >> .env
- # Create .env.production with HOST_URL Frontend
- echo "STRAPI_URL=${{ vars.STRAPI_URL }}" >> .env.production
- - name: Docker build
- run: docker-compose build
- - name: Docker up
- run: docker-compose up -d
+ docker-build:
+ strategy:
+ matrix:
+ node-version: [20.x]
+ runs-on: self-hosted
+ steps:
+ - uses: actions/checkout@v4
+ - name: Stop and remove containers and images, using docker compose down
+ run: docker-compose down --rmi "all"
+ - name: Create .env files
+ run: |
+ # Create .env with all variables except HOST_URL Backend
+ echo "HOST=${{ vars.HOST }}" >> .env
+ echo "PORT=${{ vars.PORT }}" >> .env
+ echo "DATABASE_CLIENT=${{ vars.DATABASE_CLIENT }}" >> .env
+ echo "DATABASE_FILENAME=${{ vars.DATABASE_FILENAME }}" >> .env
+ echo "STRAPI_URL=${{ vars.STRAPI_URL }}" >> .env
+ echo "ADMIN_JWT_SECRET=${{ secrets.ADMIN_JWT_SECRET }}" >> .env
+ echo "API_TOKEN_SALT=${{ secrets.API_TOKEN_SALT }}" >> .env
+ echo "APP_KEYS=${{ secrets.APP_KEYS }}" >> .env
+ echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
+ echo "TRANSFER_TOKEN_SALT=${{ secrets.TRANSFER_TOKEN_SALT }}" >> .env
+
+ # Create .env.production with HOST_URL Frontend
+ echo "BACKEND_INTERNAL_URL=${{ vars.BACKEND_INTERNAL_URL }}" >> .env.production
+ - name: Docker build
+ run: docker-compose build
+ - name: Docker up
+ run: docker-compose up -d
diff --git a/backend/.env.example b/backend/.env.example
index 0ba278a..680ee45 100644
--- a/backend/.env.example
+++ b/backend/.env.example
@@ -1,10 +1,14 @@
+# All these should be set in the GitHub Repository actions and secrets at https://github.com/NTNU-SmallSat-Lab/outreach-website/settings/variables/actions
+# Any changes done here will not be reflected in the production environment
+# All variables named toBeGenerated should be generated with the command `openssl rand -base64 32`
HOST=0.0.0.0
PORT=1337
-APP_KEYS="toBeModified1,toBeModified2"
-API_TOKEN_SALT=tobemodified
-ADMIN_JWT_SECRET=tobemodified
-TRANSFER_TOKEN_SALT=tobemodified
-JWT_SECRET=tobemodified
+STRAPI_URL="https://hypso.space/strapi/"
+APP_KEYS="toBeGenerated1,toBeGenerated2"
+API_TOKEN_SALT=toBeGenerated
+ADMIN_JWT_SECRET=toBeGenerated
+TRANSFER_TOKEN_SALT=toBeGenerated
+JWT_SECRET=toBeGenerated
DATABASE_CLIENT=sqlite
DATABASE_FILENAME=dbLocation.sqlite # in dev, will use backend root dir, in prod, will be from server os root dir so should be /var/data/strapi.db or similar
diff --git a/backend/config/env/production/server.js b/backend/config/env/production/server.js
new file mode 100644
index 0000000..cc66640
--- /dev/null
+++ b/backend/config/env/production/server.js
@@ -0,0 +1,11 @@
+module.exports = ({ env }) => ({
+ host: env("HOST", "127.0.0.1"),
+ port: env.int("PORT", 1337),
+ app: {
+ keys: env.array("APP_KEYS"),
+ },
+ webhooks: {
+ populateRelations: env.bool("WEBHOOKS_POPULATE_RELATIONS", false),
+ },
+ url: env("STRAPI_URL", "http://localhost:1337"),
+});
diff --git a/backend/config/server.js b/backend/config/server.js
index 08cc4ef..fe927ab 100644
--- a/backend/config/server.js
+++ b/backend/config/server.js
@@ -1,11 +1,10 @@
module.exports = ({ env }) => ({
- host: env('HOST', '127.0.0.1'),
- port: env.int('PORT', 1337),
+ host: env("HOST", "127.0.0.1"),
+ port: env.int("PORT", 1337),
app: {
- keys: env.array('APP_KEYS'),
+ keys: env.array("APP_KEYS"),
},
webhooks: {
- populateRelations: env.bool('WEBHOOKS_POPULATE_RELATIONS', false),
+ populateRelations: env.bool("WEBHOOKS_POPULATE_RELATIONS", false),
},
- url: "https://hypso.space/strapi/"
});
diff --git a/frontend/.env.development b/frontend/.env.development
index 6daed48..a67a9b9 100644
--- a/frontend/.env.development
+++ b/frontend/.env.development
@@ -1,2 +1,2 @@
-# Database url for outside requests
-STRAPI_URL=http://localhost:1337
+# Strapi url which ApolloClient will use
+BACKEND_INTERNAL_URL=http://localhost:1337
diff --git a/frontend/.env.production b/frontend/.env.production
index 4b3d365..cd67490 100644
--- a/frontend/.env.production
+++ b/frontend/.env.production
@@ -1,3 +1,3 @@
-# Database url for outside requests, set in github repo variables
-STRAPI_URL=http://web.hypso.ies.ntnu.no:1337
+# Strapi url which ApolloClient will use, set in github repo variables, at https://github.com/NTNU-SmallSat-Lab/outreach-website/settings/variables/actions
+BACKEND_INTERNAL_URL=http://web.hypso.ies.ntnu.no:1337
diff --git a/frontend/knip.ts b/frontend/knip.ts
new file mode 100644
index 0000000..f39da6b
--- /dev/null
+++ b/frontend/knip.ts
@@ -0,0 +1,8 @@
+module.exports = {
+ ignore: [
+ "src/__generated__/*", // ignore generated files
+ "src/components/shadcn/*", // ignore shadcn
+ "src/unused_work_for_later_improvements/**", // ignore unused work
+ "src/**/_*.*", // ignore files starting with underscore
+ ],
+};
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 8ff0716..e3e4476 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -27,6 +27,7 @@
"@visx/geo": "^3.5.0",
"@visx/scale": "^3.5.0",
"@visx/shape": "^3.5.0",
+ "@visx/vendor": "^3.5.0",
"add": "^2.0.6",
"chart.js": "^4.4.1",
"chartjs-adapter-luxon": "^1.3.1",
@@ -75,7 +76,7 @@
"@tailwindcss/typography": "^0.5.10",
"@types/chart.js": "^2.9.41",
"@types/luxon": "^3.4.2",
- "@types/node": "^20",
+ "@types/node": "^20.12.7",
"@types/ol-ext": "npm:@siedlerchr/types-ol-ext@^3.2.4",
"@types/react": "^18",
"@types/react-dom": "^18",
@@ -85,11 +86,12 @@
"eslint": "^8",
"eslint-config-next": "14.1.0",
"eslint-config-prettier": "^9.1.0",
+ "knip": "^5.10.0",
"postcss": "^8",
"prettier": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.5.12",
"tailwindcss": "^3.3.0",
- "typescript": "^5.3.3"
+ "typescript": "^5.4.5"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -1688,6 +1690,45 @@
"node": ">=16"
}
},
+ "node_modules/@ericcornelissen/bash-parser": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/@ericcornelissen/bash-parser/-/bash-parser-0.5.2.tgz",
+ "integrity": "sha512-4pIMTa1nEFfMXitv7oaNEWOdM+zpOZavesa5GaiWTgda6Zk32CFGxjUp/iIaN0PwgUW1yTq/fztSjbpE8SLGZQ==",
+ "dev": true,
+ "dependencies": {
+ "array-last": "^1.1.1",
+ "babylon": "^6.9.1",
+ "compose-function": "^3.0.3",
+ "deep-freeze": "0.0.1",
+ "filter-iterator": "0.0.1",
+ "filter-obj": "^1.1.0",
+ "has-own-property": "^0.1.0",
+ "identity-function": "^1.0.0",
+ "is-iterable": "^1.1.0",
+ "iterable-lookahead": "^1.0.0",
+ "lodash.curry": "^4.1.1",
+ "magic-string": "^0.16.0",
+ "map-obj": "^2.0.0",
+ "object-pairs": "^0.1.0",
+ "object-values": "^1.0.0",
+ "reverse-arguments": "^1.0.0",
+ "shell-quote-word": "^1.0.1",
+ "to-pascal-case": "^1.0.0",
+ "unescape-js": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@ericcornelissen/bash-parser/node_modules/magic-string": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.16.0.tgz",
+ "integrity": "sha512-c4BEos3y6G2qO0B9X7K0FVLOPT9uGrjYwYRLFmDqyl5YMboUviyecnXWp94fJTSMwPw2/sf+CEYt5AGpmklkkQ==",
+ "dev": true,
+ "dependencies": {
+ "vlq": "^0.2.1"
+ }
+ },
"node_modules/@esbuild-plugins/node-globals-polyfill": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz",
@@ -4902,6 +4943,23 @@
"dev": true,
"peer": true
},
+ "node_modules/@snyk/github-codeowners": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz",
+ "integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==",
+ "dev": true,
+ "dependencies": {
+ "commander": "^4.1.1",
+ "ignore": "^5.1.8",
+ "p-map": "^4.0.0"
+ },
+ "bin": {
+ "github-codeowners": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=8.10"
+ }
+ },
"node_modules/@strapi/blocks-react-renderer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@strapi/blocks-react-renderer/-/blocks-react-renderer-1.0.0.tgz",
@@ -6821,9 +6879,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.11.5",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz",
- "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==",
+ "version": "20.12.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
+ "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
"devOptional": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -8725,6 +8783,12 @@
"dequal": "^2.0.3"
}
},
+ "node_modules/arity-n": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz",
+ "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==",
+ "dev": true
+ },
"node_modules/array-bounds": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-bounds/-/array-bounds-1.0.1.tgz",
@@ -8772,6 +8836,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/array-last": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+ "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-last/node_modules/is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/array-normalize": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/array-normalize/-/array-normalize-1.1.4.tgz",
@@ -9105,6 +9190,15 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true,
+ "bin": {
+ "babylon": "bin/babylon.js"
+ }
+ },
"node_modules/bail": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
@@ -10206,6 +10300,15 @@
"node": ">=4.0.0"
}
},
+ "node_modules/compose-function": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz",
+ "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==",
+ "dev": true,
+ "dependencies": {
+ "arity-n": "^1.0.4"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -10880,6 +10983,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/deep-freeze": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz",
+ "integrity": "sha512-Z+z8HiAvsGwmjqlphnHW5oz6yWlOwu6EQfFTjmeTWlDeda3FS2yv3jhq35TX/ewmsnqB+RX2IdsIOyjJCQN5tg==",
+ "dev": true
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -11192,6 +11301,18 @@
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
+ "node_modules/easy-table": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+ "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "optionalDependencies": {
+ "wcwidth": "^1.0.1"
+ }
+ },
"node_modules/edge-runtime": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.7.tgz",
@@ -12673,6 +12794,21 @@
"node": ">=8"
}
},
+ "node_modules/filter-iterator": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/filter-iterator/-/filter-iterator-0.0.1.tgz",
+ "integrity": "sha512-v4lhL7Qa8XpbW3LN46CEnmhGk3eHZwxfNl5at20aEkreesht4YKb/Ba3BUIbnPhAC/r3dmu7ABaGk6MAvh2alA==",
+ "dev": true
+ },
+ "node_modules/filter-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+ "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -13775,6 +13911,12 @@
"is-browser": "^2.0.1"
}
},
+ "node_modules/has-own-property": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/has-own-property/-/has-own-property-0.1.0.tgz",
+ "integrity": "sha512-14qdBKoonU99XDhWcFKZTShK+QV47qU97u8zzoVo9cL5TZ3BmBHXogItSt9qJjR0KUMFRhcCW8uGIGl8nkl7Aw==",
+ "dev": true
+ },
"node_modules/has-passive-events": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-passive-events/-/has-passive-events-1.0.0.tgz",
@@ -14027,6 +14169,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/identity-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/identity-function/-/identity-function-1.0.0.tgz",
+ "integrity": "sha512-kNrgUK0qI+9qLTBidsH85HjDLpZfrrS0ElquKKe/fJFdB3D7VeKdXXEvOPDUHSHOzdZKCAAaQIWWyp0l2yq6pw==",
+ "dev": true
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -14504,6 +14652,15 @@
"node": ">=8"
}
},
+ "node_modules/is-iterable": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-iterable/-/is-iterable-1.1.1.tgz",
+ "integrity": "sha512-EdOZCr0NsGE00Pot+x1ZFx9MJK3C6wy91geZpXwvwexDLJvA4nzYyZf7r+EIwSeVsOLDdBz7ATg9NqKTzuNYuQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/is-lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz",
@@ -14816,6 +14973,15 @@
"ws": "*"
}
},
+ "node_modules/iterable-lookahead": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/iterable-lookahead/-/iterable-lookahead-1.0.0.tgz",
+ "integrity": "sha512-hJnEP2Xk4+44DDwJqUQGdXal5VbyeWLaPyDl2AQc242Zr7iqz4DgpQOrEzglWVMGHMDCkguLHEKxd1+rOsmgSQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/iterator.prototype": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
@@ -15079,6 +15245,164 @@
"node": ">=6"
}
},
+ "node_modules/knip": {
+ "version": "5.10.0",
+ "resolved": "https://registry.npmjs.org/knip/-/knip-5.10.0.tgz",
+ "integrity": "sha512-cC8wbMoJ1DJEI39tSTA0ToinTHr7rYpoSec+lpQ+CIuvplsRoQdnMd8Uqi62ycqJFoVfrKldLtGo+LlYITitow==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/webpro"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpro"
+ }
+ ],
+ "dependencies": {
+ "@ericcornelissen/bash-parser": "0.5.2",
+ "@nodelib/fs.walk": "2.0.0",
+ "@snyk/github-codeowners": "1.1.0",
+ "easy-table": "1.2.0",
+ "fast-glob": "3.3.2",
+ "file-entry-cache": "8.0.0",
+ "jiti": "1.21.0",
+ "js-yaml": "4.1.0",
+ "minimist": "1.2.8",
+ "picocolors": "1.0.0",
+ "picomatch": "^4.0.1",
+ "pretty-ms": "9.0.0",
+ "resolve": "1.22.8",
+ "smol-toml": "1.1.4",
+ "strip-json-comments": "5.0.1",
+ "summary": "2.1.0",
+ "zod": "^3.22.4",
+ "zod-validation-error": "^3.0.3"
+ },
+ "bin": {
+ "knip": "bin/knip.js",
+ "knip-bun": "bin/knip-bun.js"
+ },
+ "engines": {
+ "node": ">=18.6.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18",
+ "typescript": ">=5.0.4"
+ }
+ },
+ "node_modules/knip/node_modules/@nodelib/fs.scandir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-3.0.0.tgz",
+ "integrity": "sha512-ktI9+PxfHYtKjF3cLTUAh2N+b8MijCRPNwKJNqTVdL0gB0QxLU2rIRaZ1t71oEa3YBDE6bukH1sR0+CDnpp/Mg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "3.0.0",
+ "run-parallel": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=16.14.0"
+ }
+ },
+ "node_modules/knip/node_modules/@nodelib/fs.stat": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-3.0.0.tgz",
+ "integrity": "sha512-2tQOI38s19P9i7X/Drt0v8iMA+KMsgdhB/dyPER+e+2Y8L1Z7QvnuRdW/uLuf5YRFUYmnj4bMA6qCuZHFI1GDQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.14.0"
+ }
+ },
+ "node_modules/knip/node_modules/@nodelib/fs.walk": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-2.0.0.tgz",
+ "integrity": "sha512-54voNDBobGdMl3BUXSu7UaDh1P85PGHWlJ5e0XhPugo1JulOyCtp2I+5ri4wplGDJ8QGwPEQW7/x3yTLU7yF1A==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "3.0.0",
+ "fastq": "^1.15.0"
+ },
+ "engines": {
+ "node": ">=16.14.0"
+ }
+ },
+ "node_modules/knip/node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/knip/node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/knip/node_modules/parse-ms": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/knip/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/knip/node_modules/pretty-ms": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz",
+ "integrity": "sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==",
+ "dev": true,
+ "dependencies": {
+ "parse-ms": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/knip/node_modules/strip-json-comments": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
+ "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/language-subtag-registry": {
"version": "0.3.22",
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz",
@@ -15228,6 +15552,12 @@
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"dev": true
},
+ "node_modules/lodash.curry": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz",
+ "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==",
+ "dev": true
+ },
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -15479,6 +15809,15 @@
"wrappy": "1"
}
},
+ "node_modules/map-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
+ "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/mapbox-gl": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.3.tgz",
@@ -16753,6 +17092,21 @@
"node": ">= 0.4"
}
},
+ "node_modules/object-pairs": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-pairs/-/object-pairs-0.1.0.tgz",
+ "integrity": "sha512-3ECr6K831I4xX/Mduxr9UC+HPOz/d6WKKYj9p4cmC8Lg8p7g8gitzsxNX5IWlSIgFWN/a4JgrJaoAMKn20oKwA==",
+ "dev": true
+ },
+ "node_modules/object-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/object-values/-/object-values-1.0.0.tgz",
+ "integrity": "sha512-+8hwcz/JnQ9EpLIXzN0Rs7DLsBpJNT/xYehtB/jU93tHYr5BFEO8E+JGQNOSqE7opVzz5cGksKFHt7uUJVLSjQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object.assign": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
@@ -18618,6 +18972,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/reverse-arguments": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/reverse-arguments/-/reverse-arguments-1.0.0.tgz",
+ "integrity": "sha512-/x8uIPdTafBqakK0TmPNJzgkLP+3H+yxpUJhCQHsLBg1rYEVNR2D8BRYNWQhVBjyOd7oo1dZRVzIkwMY2oqfYQ==",
+ "dev": true
+ },
"node_modules/rfdc": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
@@ -19505,6 +19865,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/shell-quote-word": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/shell-quote-word/-/shell-quote-word-1.0.1.tgz",
+ "integrity": "sha512-lT297f1WLAdq0A4O+AknIFRP6kkiI3s8C913eJ0XqBxJbZPGWUNkRQk2u8zk4bEAjUJ5i+fSLwB6z1HzeT+DEg==",
+ "dev": true
+ },
"node_modules/shellac": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/shellac/-/shellac-0.8.0.tgz",
@@ -19588,6 +19954,16 @@
"node": ">=8"
}
},
+ "node_modules/smol-toml": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.1.4.tgz",
+ "integrity": "sha512-Y0OT8HezWsTNeEOSVxDnKOW/AyNXHQ4BwJNbAXlLTF5wWsBvrcHhIkE5Rf8kQMLmgf7nDX3PVOlgC6/Aiggu3Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 18",
+ "pnpm": ">= 8"
+ }
+ },
"node_modules/snake-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
@@ -19948,6 +20324,12 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
+ "node_modules/string.fromcodepoint": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz",
+ "integrity": "sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==",
+ "dev": true
+ },
"node_modules/string.prototype.matchall": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz",
@@ -20136,6 +20518,12 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/summary": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/summary/-/summary-2.1.0.tgz",
+ "integrity": "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==",
+ "dev": true
+ },
"node_modules/supercluster": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
@@ -20607,6 +20995,21 @@
"integrity": "sha512-keDnAusn/vc+R3iEiSDw8TOF7gPiTLdK1ArvWtYbJQiVfmRg6i/CAvbKq3uIS0vWroAC7ZecN3DjQKw3aSklUg==",
"peer": true
},
+ "node_modules/to-no-case": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
+ "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==",
+ "dev": true
+ },
+ "node_modules/to-pascal-case": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-pascal-case/-/to-pascal-case-1.0.0.tgz",
+ "integrity": "sha512-QGMWHqM6xPrcQW57S23c5/3BbYb0Tbe9p+ur98ckRnGDwD4wbbtDiYI38CfmMKNB5Iv0REjs5SNDntTwvDxzZA==",
+ "dev": true,
+ "dependencies": {
+ "to-space-case": "^1.0.0"
+ }
+ },
"node_modules/to-px": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/to-px/-/to-px-1.0.1.tgz",
@@ -20627,6 +21030,15 @@
"node": ">=8.0"
}
},
+ "node_modules/to-space-case": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
+ "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==",
+ "dev": true,
+ "dependencies": {
+ "to-no-case": "^1.0.0"
+ }
+ },
"node_modules/toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -20942,9 +21354,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"devOptional": true,
"bin": {
"tsc": "bin/tsc",
@@ -21026,6 +21438,15 @@
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"devOptional": true
},
+ "node_modules/unescape-js": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/unescape-js/-/unescape-js-1.1.4.tgz",
+ "integrity": "sha512-42SD8NOQEhdYntEiUQdYq/1V/YHwr1HLwlHuTJB5InVVdOSbgI6xu8jK5q65yIzuFCfczzyDF/7hbGzVbyCw0g==",
+ "dev": true,
+ "dependencies": {
+ "string.fromcodepoint": "^0.2.1"
+ }
+ },
"node_modules/unified": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz",
@@ -21905,6 +22326,12 @@
"@esbuild/win32-x64": "0.20.2"
}
},
+ "node_modules/vlq": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
+ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==",
+ "dev": true
+ },
"node_modules/vt-pbf": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz",
@@ -22613,6 +23040,18 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
+ "node_modules/zod-validation-error": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.2.0.tgz",
+ "integrity": "sha512-cYlPR6zuyrgmu2wRTdumEAJGuwI7eHVHGT+VyneAQxmRAKtGRL1/7pjz4wfLhz4J05f5qoSZc3rGacswgyTjjw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.18.0"
+ }
+ },
"node_modules/zstddec": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 77aed42..51ea83d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,7 +14,8 @@
"test": "npx playwright test",
"testui": "npx playwright test --ui",
"codegen": "npx playwright codegen",
- "test-ct": "playwright test -c playwright-ct.config.ts"
+ "test-ct": "playwright test -c playwright-ct.config.ts",
+ "find-unused-files": "knip"
},
"dependencies": {
"@apollo/client": "^3.9.0-alpha.5",
@@ -36,6 +37,7 @@
"@visx/geo": "^3.5.0",
"@visx/scale": "^3.5.0",
"@visx/shape": "^3.5.0",
+ "@visx/vendor": "^3.5.0",
"add": "^2.0.6",
"chart.js": "^4.4.1",
"chartjs-adapter-luxon": "^1.3.1",
@@ -84,7 +86,7 @@
"@tailwindcss/typography": "^0.5.10",
"@types/chart.js": "^2.9.41",
"@types/luxon": "^3.4.2",
- "@types/node": "^20",
+ "@types/node": "^20.12.7",
"@types/ol-ext": "npm:@siedlerchr/types-ol-ext@^3.2.4",
"@types/react": "^18",
"@types/react-dom": "^18",
@@ -94,10 +96,11 @@
"eslint": "^8",
"eslint-config-next": "14.1.0",
"eslint-config-prettier": "^9.1.0",
+ "knip": "^5.10.0",
"postcss": "^8",
"prettier": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.5.12",
"tailwindcss": "^3.3.0",
- "typescript": "^5.3.3"
+ "typescript": "^5.4.5"
}
}
diff --git a/frontend/src/app/blog/[articleSlug]/page.tsx b/frontend/src/app/blog/[articleSlug]/page.tsx
index 22ec4ba..9357121 100644
--- a/frontend/src/app/blog/[articleSlug]/page.tsx
+++ b/frontend/src/app/blog/[articleSlug]/page.tsx
@@ -6,8 +6,9 @@ import { gql } from "@/__generated__/gql";
import { getClient } from "@/lib/ApolloClient";
import ShareButtons from "@/components/ShareButtons";
import NextImage from "next/image";
+import fullNameToInitials from "@/lib/helpers";
-const STRAPI_URL = process.env.STRAPI_URL;
+const STRAPI_URL = process.env.BACKEND_INTERNAL_URL;
const GET_ARTICLE_BY_SLUG = gql(
`query ArticleWithSlug($articlesFilters: ArticleFiltersInput) {
@@ -100,11 +101,10 @@ export default async function Page({
)}
{!avatarURL && (
- {// Get initials from author name
- authorName
- ?.split(" ")
- .map((name: any) => name[0])
- .join("")}
+ {
+ // Get initials from author name
+ fullNameToInitials(authorName)
+ }
)}
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 8ee1d01..8f1a48f 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -6,7 +6,7 @@ import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
import React from "react";
import { ApolloWrapper } from "@/components/wrappers/ApolloWrapper";
-import SatelliteInitialFetch from "@/components/satelliteData/SatelliteInitialFetch";
+import SatelliteInitialClientFetch from "@/components/satelliteData/SatelliteInitialFetch";
// imports to get satellites from strapi and fetch the data serverside
import fetchSatelliteNamesAndId from "@/lib/data/fetchSatelliteNamesAndId";
@@ -21,6 +21,7 @@ export const metadata: Metadata = {
import ErrorBoundaryNavigation from "@/components/ErrorBoundaryNavigation";
import Starfield from "@/components/starBackground/Starfield";
+import { SatelliteEntry } from "@/lib/store";
export default async function RootLayout({
children,
@@ -29,18 +30,18 @@ export default async function RootLayout({
}>) {
// fetch satellite names and id to be set in the store in the navbar
const satellites = await fetchSatelliteNamesAndId();
- let satData: any[] = [];
+ let satData: SatelliteEntry[] = [];
if (satellites) {
for (const sat of satellites) {
- if (sat.id) {
+ if (sat.num) {
try {
- const data = await satLoaderById(sat.id);
- satData.push({ name: sat.name, id: sat.id, data });
+ const entry = await satLoaderById(sat.num);
+ satData.push(entry);
} catch (e) {
console.error(
"Either CelesTrak has IP banned the server, or the satellite data is not available for the provided NORAD ID: " +
- sat.id +
+ sat.num +
", or CelesTrak is down.",
);
}
@@ -52,7 +53,7 @@ export default async function RootLayout({
-
+
diff --git a/frontend/src/app/projects/[projectSlug]/page.tsx b/frontend/src/app/projects/[projectSlug]/page.tsx
index 98db280..6004f0e 100644
--- a/frontend/src/app/projects/[projectSlug]/page.tsx
+++ b/frontend/src/app/projects/[projectSlug]/page.tsx
@@ -4,7 +4,7 @@ import { getClient } from "@/lib/ApolloClient";
import { BlocksContent } from "@strapi/blocks-react-renderer";
import RelatedProjectsAndSatellites from "@/components/RelatedProjectsAndSatellites";
import { ProjectOrSatellite } from "@/app/satellites/[satelliteSlug]/page";
-const STRAPI_URL = process.env.STRAPI_URL;
+const STRAPI_URL = process.env.BACKEND_INTERNAL_URL;
const GET_PROJECT_BY_SLUG = gql(`
query Projects($projectFilters: ProjectFiltersInput) {
diff --git a/frontend/src/app/projects/page.tsx b/frontend/src/app/projects/page.tsx
index dc63dd3..7941333 100644
--- a/frontend/src/app/projects/page.tsx
+++ b/frontend/src/app/projects/page.tsx
@@ -14,8 +14,8 @@ import {
PageHeaderAndSubtitle,
PageSubtitle,
} from "@/components/PageHeader";
-import { OuiImage } from "@/components/fullBlogCard";
-const STRAPI_URL = process.env.STRAPI_URL;
+import { PlaceholderImage } from "@/components/fullBlogCard";
+const STRAPI_URL = process.env.BACKEND_INTERNAL_URL;
const GET_PROJECTS = gql(`
query GET_PROJECTS {
@@ -102,7 +102,7 @@ export default async function ProjectsPage() {
/>
) : (
)}
diff --git a/frontend/src/app/satellites/[satelliteSlug]/page.tsx b/frontend/src/app/satellites/[satelliteSlug]/page.tsx
index 344cf8b..a4b83a1 100644
--- a/frontend/src/app/satellites/[satelliteSlug]/page.tsx
+++ b/frontend/src/app/satellites/[satelliteSlug]/page.tsx
@@ -12,13 +12,14 @@ import {
PageHeaderAndSubtitle,
} from "@/components/PageHeader";
import Image from "next/image";
+import { SatelliteName, SatelliteNumber } from "@/lib/store";
export interface SatelliteInfo {
launchDate: string | undefined;
- name: string;
+ name: SatelliteName;
content: BlocksContent;
relatedProjects?: ProjectOrSatellite[];
- noradId: string | undefined;
+ noradId: SatelliteNumber | undefined;
missionStatus: string | undefined;
massKg: number | undefined;
satelliteImage: string | undefined;
@@ -32,7 +33,7 @@ export interface ProjectOrSatellite {
isProject: boolean;
}
-const STRAPI_URL = process.env.STRAPI_URL;
+const STRAPI_URL = process.env.BACKEND_INTERNAL_URL;
export default async function SatelliteInfoPage({
params,
@@ -113,7 +114,7 @@ export default async function SatelliteInfoPage({
{/* Container for map */}
{satelliteInfo.noradId ? (
-
+
) : null}
diff --git a/frontend/src/components/2dmap/Map2d.tsx b/frontend/src/components/2dmap/Map2d.tsx
index aba8cf8..9c63051 100644
--- a/frontend/src/components/2dmap/Map2d.tsx
+++ b/frontend/src/components/2dmap/Map2d.tsx
@@ -1,6 +1,6 @@
"use client";
import Map2dNaturalProjection from "./2dMapProjection";
-import { useSatelliteStore } from "@/lib/store";
+import { SatelliteNumber, useSatelliteStore } from "@/lib/store";
import React, { useState, useEffect, useRef, useLayoutEffect } from "react";
import {
SatelliteInfo,
@@ -10,8 +10,8 @@ import {
const updateInterval = 100;
-export default function Map2d({ satName }: { satName: string }) {
- const { satelliteData } = useSatelliteStore();
+export default function Map2d({ satNum }: { satNum: SatelliteNumber }) {
+ const { satNumToEntry } = useSatelliteStore();
const [satelliteInfo, setSatelliteInfo] = useState(
null,
);
@@ -27,8 +27,8 @@ export default function Map2d({ satName }: { satName: string }) {
useEffect(() => {
const intervalId = setInterval(() => {
// Access satellite data by name
- const satData = satelliteData[satName];
- if (satData) {
+ const satData = satNumToEntry[satNum];
+ if (satData && satData.satrec) {
const updatedInfo = convertSatrec(satData.satrec, satData.name);
setSatelliteInfo(updatedInfo);
}
@@ -36,7 +36,7 @@ export default function Map2d({ satName }: { satName: string }) {
// Clear interval on component unmount
return () => clearInterval(intervalId);
- }, [satelliteData, satName]);
+ }, [satNumToEntry, satNum]);
// Calculate and update size based on the container's width
useLayoutEffect(() => {
@@ -63,10 +63,10 @@ export default function Map2d({ satName }: { satName: string }) {
// Get future satellite positions on component mount
useEffect(() => {
- if (!satelliteData[satName] || !satelliteData[satName].satrec) return;
+ if (!satNumToEntry[satNum] || !satNumToEntry[satNum].satrec) return;
const predictions = predictFuturePositions(
- satelliteData[satName].satrec,
+ satNumToEntry[satNum]?.satrec,
projectionAmount,
);
const futurePosTuples: [number, number][] = predictions.map(
@@ -77,7 +77,7 @@ export default function Map2d({ satName }: { satName: string }) {
) as [number, number][];
setFuturePositions(futurePosTuples);
- }, [satelliteData, satName, projectionAmount]);
+ }, [satNum, projectionAmount, satNumToEntry]);
// Function to handle projection amount change
const handleSliderChange = (event: { target: { value: any } }) => {
diff --git a/frontend/src/components/ExternalLink.tsx b/frontend/src/components/ExternalLink.tsx
deleted file mode 100644
index 1f47274..0000000
--- a/frontend/src/components/ExternalLink.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ReactNode } from "react";
-type ExternalLinkProps = {
- href: string;
- children: ReactNode;
-};
-
-export function ExternalLink({ href, children }: ExternalLinkProps) {
- return (
-
- {children}
-
- );
-}
diff --git a/frontend/src/components/HeroWrapper.tsx b/frontend/src/components/HeroWrapper.tsx
index 7e6bfba..ae63851 100644
--- a/frontend/src/components/HeroWrapper.tsx
+++ b/frontend/src/components/HeroWrapper.tsx
@@ -2,7 +2,7 @@ import { gql } from "@/__generated__/gql";
import { getClient } from "@/lib/ApolloClient";
import Hero from "@components/ui/hero";
-const STRAPI_URL = process.env.STRAPI_URL;
+const STRAPI_URL = process.env.BACKEND_INTERNAL_URL;
const GET_HERO_DATA = gql(`
query Query($publicationState: PublicationState) {
diff --git a/frontend/src/components/RelatedProjectsAndSatellites.tsx b/frontend/src/components/RelatedProjectsAndSatellites.tsx
index 4b48518..c46e281 100644
--- a/frontend/src/components/RelatedProjectsAndSatellites.tsx
+++ b/frontend/src/components/RelatedProjectsAndSatellites.tsx
@@ -1,14 +1,14 @@
import { ProjectOrSatellite } from "@/app/satellites/[satelliteSlug]/page";
import Link from "next/link";
import Image from "next/image";
-const STRAPI_URL = process.env.STRAPI_URL;
+const STRAPI_URL = process.env.BACKEND_INTERNAL_URL;
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/components/shadcn/card";
-import { OuiImage } from "@/components/fullBlogCard";
+import { PlaceholderImage } from "@/components/fullBlogCard";
export default function RelatedProjectsAndSatellites({
project,
@@ -45,7 +45,7 @@ export default function RelatedProjectsAndSatellites({
/>
) : (
)}
diff --git a/frontend/src/components/SatelliteResponsiveTable.tsx b/frontend/src/components/SatelliteResponsiveTable.tsx
index 2b598a9..cf674d7 100644
--- a/frontend/src/components/SatelliteResponsiveTable.tsx
+++ b/frontend/src/components/SatelliteResponsiveTable.tsx
@@ -72,6 +72,9 @@ export default function SatelliteResponsiveTable({
handleRowClick(satellite.attributes.slug)
}
diff --git a/frontend/src/components/fullBlogCard.tsx b/frontend/src/components/fullBlogCard.tsx
index 973f040..41c0b3d 100644
--- a/frontend/src/components/fullBlogCard.tsx
+++ b/frontend/src/components/fullBlogCard.tsx
@@ -12,7 +12,7 @@ import Image from "next/image";
import { cn } from "@/lib/utils";
import { SVGProps } from "react";
-export function OuiImage(props: SVGProps) {
+export function PlaceholderImage(props: SVGProps) {
return (
) : (
)}
diff --git a/frontend/src/components/homeComponents/SatDropdown.tsx b/frontend/src/components/homeComponents/SatDropdown.tsx
index d778233..c4a1ff9 100644
--- a/frontend/src/components/homeComponents/SatDropdown.tsx
+++ b/frontend/src/components/homeComponents/SatDropdown.tsx
@@ -3,24 +3,30 @@ import React, { useState } from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
import { satLoaderById } from "@/lib/getSatelliteData";
+import {
+ SatelliteActions,
+ SatelliteName,
+ SatelliteNumber,
+ SatelliteState,
+} from "@/lib/store";
type DropdownProps = {
- satelliteNames: string[];
- selectedSatellite: string;
- // eslint-disable-next-line no-unused-vars
- setSelectedSatellite: (satellite: string) => void;
- // eslint-disable-next-line no-unused-vars
- setSatellites: (satellites: any) => void;
+ selectedSatellite: SatelliteState["selectedSatellite"];
+ setSelectedSatellite: SatelliteActions["setSelectedSatellite"];
+ setSatellites: SatelliteActions["setSatellites"];
+ selectedSatelliteName?: SatelliteName;
+ satNumToEntry: SatelliteState["satNumToEntry"];
};
export default function SatDropdown({
- satelliteNames,
selectedSatellite,
setSelectedSatellite,
setSatellites,
+ selectedSatelliteName,
+ satNumToEntry,
}: DropdownProps) {
const [isOpen, setIsOpen] = useState
(false);
- const [noradID, setNoradID] = useState("");
+ const [noradID, setNoradID] = useState();
const [error, setError] = useState("");
const toggleDropdown = () => {
@@ -28,12 +34,12 @@ export default function SatDropdown({
setIsOpen(!isOpen);
};
- const handleSelect = (satellite: string) => {
+ const handleSelect = (satellite: SatelliteNumber) => {
setSelectedSatellite(satellite);
setIsOpen(false);
};
- const handleAddSatellite = async (noradID: string) => {
+ const handleAddSatellite = async (noradID: SatelliteNumber) => {
if (!noradID) {
setError("Please enter a valid NORAD ID.");
return;
@@ -44,11 +50,12 @@ export default function SatDropdown({
if (data) {
const newSatellite = {
name: data.name,
- id: noradID,
- data: data,
+ num: noradID,
+ satrec: data.satrec,
+ timestamp: data.timestamp,
};
setSatellites([newSatellite]);
- setSelectedSatellite(newSatellite.name);
+ setSelectedSatellite(newSatellite.num);
setError("");
} else {
throw new Error("No data returned for the provided NORAD ID.");
@@ -76,7 +83,9 @@ export default function SatDropdown({
const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.key === "Enter") {
- handleAddSatellite(noradID);
+ if (noradID) {
+ handleAddSatellite(noradID);
+ }
}
};
@@ -84,7 +93,7 @@ export default function SatDropdown({
const value = event.target.value;
// Allow only numeric input
if (/^\d*$/.test(value)) {
- setNoradID(value);
+ setNoradID(Number(value) as SatelliteNumber);
}
};
@@ -100,7 +109,7 @@ export default function SatDropdown({
onClick={toggleDropdown}
>
-
{selectedSatellite || "Select a Satellite"}
+
{selectedSatelliteName || "Select a Satellite"}
Selected Satellite