From d0747886a36bd577c3951ffc6e3388f7dba43b19 Mon Sep 17 00:00:00 2001 From: EliasKnudsen <38568225+EliasKnudsen@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:52:50 +0200 Subject: [PATCH] 268 add launch date to satellite (#289) * Launch date satellite * Add launch date #268 * Fix since launch time * content Types --- .../content-types/satellite/schema.json | 3 + backend/types/generated/contentTypes.d.ts | 1 + frontend/src/__generated__/gql.ts | 4 +- frontend/src/__generated__/graphql.ts | 7 +- .../app/satellites/[satelliteSlug]/page.tsx | 9 +- frontend/src/components/2dmap/Map2d.tsx | 2 +- .../src/components/ui/launchDateCountDown.tsx | 93 +++++++++++++++++++ frontend/src/lib/data/fetchSatelliteInfo.ts | 43 +++++---- 8 files changed, 136 insertions(+), 26 deletions(-) create mode 100644 frontend/src/components/ui/launchDateCountDown.tsx diff --git a/backend/src/api/satellite/content-types/satellite/schema.json b/backend/src/api/satellite/content-types/satellite/schema.json index 9378b19..76650c7 100644 --- a/backend/src/api/satellite/content-types/satellite/schema.json +++ b/backend/src/api/satellite/content-types/satellite/schema.json @@ -45,6 +45,9 @@ "missionStatus": { "type": "string" }, + "launchDate": { + "type": "datetime" + }, "slug": { "type": "uid", "targetField": "name", diff --git a/backend/types/generated/contentTypes.d.ts b/backend/types/generated/contentTypes.d.ts index dab7b1a..1b7f91e 100644 --- a/backend/types/generated/contentTypes.d.ts +++ b/backend/types/generated/contentTypes.d.ts @@ -987,6 +987,7 @@ export interface ApiSatelliteSatellite extends Schema.CollectionType { 'api::project.project' >; missionStatus: Attribute.String; + launchDate: Attribute.DateTime; slug: Attribute.UID<'api::satellite.satellite', 'name'> & Attribute.Required; createdAt: Attribute.DateTime; diff --git a/frontend/src/__generated__/gql.ts b/frontend/src/__generated__/gql.ts index 7e9384d..a292ae4 100644 --- a/frontend/src/__generated__/gql.ts +++ b/frontend/src/__generated__/gql.ts @@ -20,7 +20,7 @@ const documents = { "\nquery Query($publicationState: PublicationState) {\n hero(publicationState: $publicationState) {\n data {\n attributes {\n text\n image {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n }": types.QueryDocument, "\nquery GET_ARTICLES($pagination: PaginationArg, $filters: ArticleFiltersInput) {\n articles(sort: [\"datePublished:desc\"], pagination: $pagination, filters: $filters) {\n data {\n id\n attributes {\n author {\n data {\n attributes {\n name\n avatar {\n data {\n attributes {\n url\n }\n }\n }\n }\n }\n }\n previewTitle\n datePublished\n body\n coverImage {\n data {\n attributes {\n url\n }\n }\n }\n createdAt\n publishedAt\n slug\n Tag\n }\n }\n meta {\n pagination {\n total\n }\n }\n }\n}\n": types.Get_ArticlesDocument, "\nquery FeaturedImage {\n featuredImage {\n data {\n attributes {\n featuredImage {\n data {\n attributes {\n url\n }\n }\n }\n satellite {\n data {\n attributes {\n catalogNumberNORAD\n name\n }\n }\n }\n createdAt\n updatedAt\n publishedAt\n }\n }\n }\n}\n\n": types.FeaturedImageDocument, - "query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n }\n }\n }\n }\n ": types.Get_Satellite_InfoDocument, + "query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n launchDate\n }\n }\n }\n }\n ": types.Get_Satellite_InfoDocument, }; /** @@ -68,7 +68,7 @@ export function gql(source: "\nquery FeaturedImage {\n featuredImage {\n /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n }\n }\n }\n }\n "): (typeof documents)["query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n }\n }\n }\n }\n "]; +export function gql(source: "query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n launchDate\n }\n }\n }\n }\n "): (typeof documents)["query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) {\n satellites(filters: $filters) {\n data {\n id\n attributes {\n celestrakURL\n catalogNumberNORAD\n content\n name\n projects {\n data {\n attributes {\n title\n previewImage {\n data {\n attributes {\n url\n }\n }\n }\n slug\n }\n id\n }\n }\n launchDate\n }\n }\n }\n }\n "]; export function gql(source: string) { return (documents as any)[source] ?? {}; diff --git a/frontend/src/__generated__/graphql.ts b/frontend/src/__generated__/graphql.ts index a79dfd0..baa5211 100644 --- a/frontend/src/__generated__/graphql.ts +++ b/frontend/src/__generated__/graphql.ts @@ -914,6 +914,7 @@ export type Satellite = { celestrakURL?: Maybe; content?: Maybe; createdAt?: Maybe; + launchDate?: Maybe; missionStatus?: Maybe; name: Scalars['String']['output']; previewImage?: Maybe; @@ -955,6 +956,7 @@ export type SatelliteFiltersInput = { content?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; + launchDate?: InputMaybe; missionStatus?: InputMaybe; name?: InputMaybe; not?: InputMaybe; @@ -969,6 +971,7 @@ export type SatelliteInput = { catalogNumberNORAD?: InputMaybe; celestrakURL?: InputMaybe; content?: InputMaybe; + launchDate?: InputMaybe; missionStatus?: InputMaybe; name?: InputMaybe; previewImage?: InputMaybe; @@ -1429,7 +1432,7 @@ export type Get_Satellite_InfoQueryVariables = Exact<{ }>; -export type Get_Satellite_InfoQuery = { __typename?: 'Query', satellites?: { __typename?: 'SatelliteEntityResponseCollection', data: Array<{ __typename?: 'SatelliteEntity', id?: string | null, attributes?: { __typename?: 'Satellite', celestrakURL?: string | null, catalogNumberNORAD?: string | null, content?: any | null, name: string, projects?: { __typename?: 'ProjectRelationResponseCollection', data: Array<{ __typename?: 'ProjectEntity', id?: string | null, attributes?: { __typename?: 'Project', title: string, slug: string, previewImage?: { __typename?: 'UploadFileEntityResponse', data?: { __typename?: 'UploadFileEntity', attributes?: { __typename?: 'UploadFile', url: string } | null } | null } | null } | null }> } | null } | null }> } | null }; +export type Get_Satellite_InfoQuery = { __typename?: 'Query', satellites?: { __typename?: 'SatelliteEntityResponseCollection', data: Array<{ __typename?: 'SatelliteEntity', id?: string | null, attributes?: { __typename?: 'Satellite', celestrakURL?: string | null, catalogNumberNORAD?: string | null, content?: any | null, name: string, launchDate?: any | null, projects?: { __typename?: 'ProjectRelationResponseCollection', data: Array<{ __typename?: 'ProjectEntity', id?: string | null, attributes?: { __typename?: 'Project', title: string, slug: string, previewImage?: { __typename?: 'UploadFileEntityResponse', data?: { __typename?: 'UploadFileEntity', attributes?: { __typename?: 'UploadFile', url: string } | null } | null } | null } | null }> } | null } | null }> } | null }; export const ArticleWithSlugDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ArticleWithSlug"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"articlesFilters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArticleFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"articles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"articlesFilters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"author"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"body"}},{"kind":"Field","name":{"kind":"Name","value":"coverImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"datePublished"}},{"kind":"Field","name":{"kind":"Name","value":"previewTitle"}}]}}]}}]}}]}}]} as unknown as DocumentNode; @@ -1439,4 +1442,4 @@ export const Get_SatellitesDocument = {"kind":"Document","definitions":[{"kind": export const QueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Query"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"publicationState"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"PublicationState"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"hero"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"publicationState"},"value":{"kind":"Variable","name":{"kind":"Name","value":"publicationState"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"image"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const Get_ArticlesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_ARTICLES"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"PaginationArg"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ArticleFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"articles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ListValue","values":[{"kind":"StringValue","value":"datePublished:desc","block":false}]}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"author"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"previewTitle"}},{"kind":"Field","name":{"kind":"Name","value":"datePublished"}},{"kind":"Field","name":{"kind":"Name","value":"body"}},{"kind":"Field","name":{"kind":"Name","value":"coverImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"publishedAt"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"Tag"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"meta"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"pagination"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const FeaturedImageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FeaturedImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"featuredImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"featuredImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"satellite"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"publishedAt"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const Get_Satellite_InfoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_SATELLITE_INFO"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SatelliteFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"satellites"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"celestrakURL"}},{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"previewImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const Get_Satellite_InfoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GET_SATELLITE_INFO"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SatelliteFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"satellites"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"celestrakURL"}},{"kind":"Field","name":{"kind":"Name","value":"catalogNumberNORAD"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"previewImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"attributes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"launchDate"}}]}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/frontend/src/app/satellites/[satelliteSlug]/page.tsx b/frontend/src/app/satellites/[satelliteSlug]/page.tsx index d77f3a7..63b197e 100644 --- a/frontend/src/app/satellites/[satelliteSlug]/page.tsx +++ b/frontend/src/app/satellites/[satelliteSlug]/page.tsx @@ -5,8 +5,10 @@ import { BlocksContent } from "@strapi/blocks-react-renderer"; import RelatedProjectsAndSatellites from "@/components/RelatedProjectsAndSatellites"; import Map2d from "@/components/2dmap/Map2d"; import SatelliteDataHome from "@/components/satelliteData/SatelliteDataHome"; +import LaunchDateCountDown from "@/components/ui/launchDateCountDown"; export interface SatelliteInfo { + launchDate: string | undefined; name: string; content: BlocksContent; relatedProjects?: ProjectOrSatellite[]; @@ -35,6 +37,11 @@ export default async function SatelliteInfoPage({ return ( <>
+
+ +

{satelliteInfo.name}

@@ -57,7 +64,7 @@ export default async function SatelliteInfoPage({ {/* Image container */}
-

Satellite Image

+

Satellite image

diff --git a/frontend/src/components/2dmap/Map2d.tsx b/frontend/src/components/2dmap/Map2d.tsx index 5171954..d8c0218 100644 --- a/frontend/src/components/2dmap/Map2d.tsx +++ b/frontend/src/components/2dmap/Map2d.tsx @@ -99,7 +99,7 @@ export default function Map2d({ satName }: { satName: string }) { return (
-
+

Current and Predicted Satellite Position

diff --git a/frontend/src/components/ui/launchDateCountDown.tsx b/frontend/src/components/ui/launchDateCountDown.tsx new file mode 100644 index 0000000..107855d --- /dev/null +++ b/frontend/src/components/ui/launchDateCountDown.tsx @@ -0,0 +1,93 @@ +"use client"; // This directive marks the component for client-side execution + +import React, { useState, useEffect } from "react"; + +type LaunchDateCountDownProps = { + launchDateString: string | undefined; +}; + +const LaunchDateCountDown: React.FC = ({ + launchDateString, +}) => { + const [displayTime, setDisplayTime] = useState([ + "0 days", + "0 hours", + "0 minutes", + "0 seconds", + ]); + const [hasLaunched, setHasLaunched] = useState(true); + const [columns, setColumns] = useState("grid grid-cols-4"); + + useEffect(() => { + if (!launchDateString) return; + + const launchDate = new Date(launchDateString); + + const intervalId = setInterval(() => { + const now = new Date(); + const differenceReal = launchDate.getTime() - now.getTime(); + const difference = Math.abs(differenceReal); + + const days = Math.floor(difference / (1000 * 60 * 60 * 24)); + const hours = Math.floor((difference / (1000 * 60 * 60)) % 24); + const minutes = Math.floor((difference / 1000 / 60) % 60); + const seconds = Math.floor((difference / 1000) % 60); + + let timeParts = []; + if (days > 0) timeParts.push(`${days} days`); + if (hours > 0 || timeParts.length > 0) + timeParts.push(`${hours} hours`); + if (minutes > 0 || timeParts.length > 0) + timeParts.push(`${minutes} minutes`); + timeParts.push(`${seconds} seconds`); + + setDisplayTime(timeParts); + setHasLaunched(differenceReal <= 0); + setColumns("grid " + "grid-cols-" + timeParts.length.toString()); + }, 1000); + + return () => clearInterval(intervalId); + }, [launchDateString]); + + if (hasLaunched == undefined) { + return <>; + } + return ( + <> +
+ {hasLaunched ? ( +

TIME SINCE LAUNCH

+ ) : ( +

TIME UNTIL LAUNCH

+ )} +
+ +
+
+
+ +
+
+ {displayTime.length > 0 && ( +
+
+ {displayTime.map((part, index) => ( +
+

{part.split(" ")[0]}

+

+ {part.split(" ")[1]} +

+
+ ))} +
+
+ )} +
+ +
+
+ + ); +}; + +export default LaunchDateCountDown; diff --git a/frontend/src/lib/data/fetchSatelliteInfo.ts b/frontend/src/lib/data/fetchSatelliteInfo.ts index 0626061..3a112f8 100644 --- a/frontend/src/lib/data/fetchSatelliteInfo.ts +++ b/frontend/src/lib/data/fetchSatelliteInfo.ts @@ -7,34 +7,35 @@ import { getClient } from "../ApolloClient"; const GET_SATELLITE_INFO = gql(`query GET_SATELLITE_INFO($filters: SatelliteFiltersInput) { - satellites(filters: $filters) { - data { - id - attributes { - celestrakURL - catalogNumberNORAD - content - name - projects { - data { - attributes { - title - previewImage { - data { - attributes { - url - } + satellites(filters: $filters) { + data { + id + attributes { + celestrakURL + catalogNumberNORAD + content + name + projects { + data { + attributes { + title + previewImage { + data { + attributes { + url } } - slug } - id + slug } + id } } - } + launchDate + } } } + } `); export default async function fetchSatelliteInfo({ @@ -80,6 +81,8 @@ export default async function fetchSatelliteInfo({ noradId: graphqlData?.data?.satellites?.data[0]?.attributes ?.catalogNumberNORAD ?? undefined, + launchDate: + graphqlData.data.satellites?.data[0]?.attributes?.launchDate ?? "", }; return satelliteInfo;