diff --git a/.DS_Store b/.DS_Store index 3e2f9366..74e3a94f 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..cf5b614b --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +up: + docker-compose up + +build: + docker-compose build && yarn build + +up-full: + yarn && yarn build && supabase start && docker-compose up --build + +down: + docker-compose down + +down-full: + docker-compose build && yarn build && docker-compose down && supabase stop \ No newline at end of file diff --git a/app/api/gameplay/inventory/route.ts b/app/api/gameplay/inventory/route.ts index eef5e5fc..30da3551 100644 --- a/app/api/gameplay/inventory/route.ts +++ b/app/api/gameplay/inventory/route.ts @@ -57,6 +57,33 @@ const inventoryItems: InventoryItem[] = [ ItemCategory: "Structure", locationType: 'Surface', }, + { + id: 3107, + name: "Launchpad", + description: "Launch rockets and satellites", + icon_url: "/assets/Items/Launchpad.jpg", + ItemCategory: "Structure", + locationType: 'Surface', + }, + { + id: 3108, + name: "First rocket", + description: "Travel the solar-system", + icon_url: "/assets/Items/Rocket.png", + ItemCategory: "Structure", + locationType: 'Atmosphere', + }, + + + // Classification structures introduced in C2 + { + id: 31010, + name: "Physics Lab", + description: "Catalogue results from different particle experiments across the universe", + icon_url: "/assets/Items/PhysicsLab.png", + ItemCategory: "Structure", + locationType: 'Surface', + }, // Tests { diff --git a/app/api/gameplay/missions/planets/initialisation/route.ts b/app/api/gameplay/missions/planets/initialisation/route.ts index 3cd19a4b..098ea6df 100644 --- a/app/api/gameplay/missions/planets/initialisation/route.ts +++ b/app/api/gameplay/missions/planets/initialisation/route.ts @@ -1,5 +1,4 @@ import { NextRequest, NextResponse } from "next/server"; -// import { Mission } from "@/types/Missions"; export interface Mission { id: number; @@ -14,7 +13,7 @@ const planetInitialisationMissions: Mission[] = [ id: 100001, name: "Initialise Mercury", anomaly: 10, - }, + }, { id: 200001, name: "Initialise Venus", @@ -35,6 +34,16 @@ const planetInitialisationMissions: Mission[] = [ name: "Initialise Mars", anomaly: 40, }, + { + id: 400011, + name: "Initialise Phobos", + anomaly: 41, + }, + { + id: 400021, + name: "Initialise Deimos", + anomaly: 42, + }, { id: 500001, name: "Initialise Jupiter", @@ -70,6 +79,16 @@ const planetInitialisationMissions: Mission[] = [ name: "Initialise Saturn", anomaly: 60, }, + { + id: 600011, + name: "Initialise Enceladus", + anomaly: 61, + }, + { + id: 600021, + name: "Initialise Titan", + anomaly: 62, + }, { id: 700001, name: "Initialise Uranus", diff --git a/app/api/gameplay/missions/route.ts b/app/api/gameplay/missions/route.ts index 04f403b8..dcf55e71 100644 --- a/app/api/gameplay/missions/route.ts +++ b/app/api/gameplay/missions/route.ts @@ -164,9 +164,84 @@ const missions: Mission[] = [ { id: 100000005, name: "Pick new planet and travel", - }, + }, // Plus planet initialisation missions // Any resource collection missions... + + + // Citizen science missions introduced in #Chapter-2 + { + id: 20000001, + name: "Complete Count That Neutrino tutorial", + }, + { + id: 200000012, + name: "Make your first CTN classification", + }, + { + id: 20000002, + name: 'Complete Cosmic Muon tutorial', + }, + { + id: 200000022, + name: 'Make your first CM classification', + }, + { + id: 20000003, + name: 'Complete Minor Planet tutorial' + }, + { + id: 200000032, + name: 'Make your first MP classification', + }, + { + id: 20000004, + name: 'Complete the DMP tutorial', + }, + { + id: 200000042, + name: 'Make your first DMP classification', + }, + { + id: 20000005, + name: 'Complete the Planet Four tutorial', + }, + { + id: 200000052, + name: 'Make your first P4 classification', + }, + { + id: 20000006, + name: 'Complete the AI for Mars tutorial', + }, + { + id: 200000062, + name: 'Make your first AI4M classification', + }, + { + id: 20000007, + name: 'Complete the JVH tutorial', + }, + { + id: 200000072, + name: 'Make your first JVH classification', + }, + { + id: 20000008, + name: 'Complete the SFNZ tutorial', + }, + { + id: 200000082, + name: 'Make your first SFNZ classification', + }, + { + id: 20000009, + name: 'Complete Solar Storm Watch tutorial', + }, + { + id: 200000092, + name: 'Make your first SSW classification', + }, ]; export async function GET(req: NextRequest) { diff --git a/app/api/gameplay/research/structures/route.ts b/app/api/gameplay/research/structures/route.ts index ba09e25f..3e66d3ad 100644 --- a/app/api/gameplay/research/structures/route.ts +++ b/app/api/gameplay/research/structures/route.ts @@ -30,7 +30,7 @@ const ResearchedStructures: ResearchedStructureItem[] = [ name: "Rover camera receiver", description: 'Used to decode messages from your rover and learn more about the terrain of your planet', icon_url: '/assets/Items/CameraReceiver.png', - requiresMission: 1370203, + // requiresMission: 1370203, usedFor: 13714101, classificationType: 'roverImg', item: 3102, @@ -41,7 +41,7 @@ const ResearchedStructures: ResearchedStructureItem[] = [ name: "Lidar module", description: 'Collect and study weather events and entitie', icon_url: '/assets/Items/Scoper.png', - requiresMission: 1370203, + // requiresMission: 1370203, usedFor: 137121301, classificationType: 'clouds', item: 3105, @@ -52,12 +52,30 @@ const ResearchedStructures: ResearchedStructureItem[] = [ name: "Zoodex", description: "Used to discover and collate animal & plant data", icon_url: '/assets/Items/Pokedex.png', - requiresMission: 1370203, + // requiresMission: 1370203, usedFor: 137121301, classificationType: 'zoodex', item: 3104, chapter: 1, }, + { + id: 5, + name: "Launchpad", + description: "Launch rockets and satellites using your launchpad", + icon_url: '/assets/Items/Launchpad.jpg', + requiresMission: 10000004, + usedFor: 100000042, + item: 3107, + chapter: 1, + }, + { + id: 6, + name: "Physics Lab", + description: 'Catalogue results from different particle experiments across the universe', + icon_url: '/assets/Items/PhysicsLab.png', + item: 31010, + chapter: 2, + } ]; export async function GET(req: NextRequest) { diff --git a/app/api/gameplay/research/travel/route.ts b/app/api/gameplay/research/travel/route.ts new file mode 100644 index 00000000..0499209b --- /dev/null +++ b/app/api/gameplay/research/travel/route.ts @@ -0,0 +1,30 @@ +import { NextRequest, NextResponse } from "next/server"; + +interface ResearchedTravelMethod { + id: number; + name: string; + description?: string; + icon_url: string; + requires?: number; // Does it require a research ticket previously? + requiresMission?: number; + // usedFor?: number; // Mission +}; + +const ResearchedTravelMethods: ResearchedTravelMethod[] = [ + { + id: 94, + name: "Intra-Solar System Travel", + description: 'Travel to planets & moons within the solar system', + icon_url: '/assets/Items/Rocket.png', + }, + { + id: 95, + name: "Unmanned Probe Deployments", + description: 'Deploy probes to planets & moons within the solar system', + icon_url: '/assets/Items/Probe.png', + }, +]; + +export async function GET(req: NextRequest) { + return NextResponse.json(ResearchedTravelMethods); +}; \ No newline at end of file diff --git a/app/auth/UserProfileFields.tsx b/app/auth/UserProfileFields.tsx index 7665b163..97e6a643 100644 --- a/app/auth/UserProfileFields.tsx +++ b/app/auth/UserProfileFields.tsx @@ -50,14 +50,7 @@ export function ProfileCard() { } }; - const fetchMissions = async () => { - const res = await fetch('/api/gameplay/missions'); - const data = await res.json(); - setMissions(data); - }; - fetchProfile(); - fetchMissions(); }, [session]); const handleFieldChange = (e: { target: { name: any; value: any; }; }) => { diff --git a/app/components/(create)/(classifications)/PostForm.tsx b/app/components/(create)/(classifications)/PostForm.tsx index 4c570153..4f2994f8 100644 --- a/app/components/(create)/(classifications)/PostForm.tsx +++ b/app/components/(create)/(classifications)/PostForm.tsx @@ -14,6 +14,101 @@ interface ClassificationOption { subOptions?: ClassificationOption[]; }; +const zoodexSouthCoastFaunaRecovery: ClassificationOption[] = [ + { id: 1, text: "Australian raven" }, + { id: 2, text: "Red-winged fairy-wren" }, + { id: 3, text: "Cat" }, + { id: 4, text: "Brown falcon" }, + { id: 5, text: "Silvereye" }, + { id: 6, text: "Echidna" }, + { id: 7, text: "Brown quail" }, + { id: 8, text: "Southern emu-wren" }, + { id: 9, text: "Fox" }, + { id: 10, text: "Brush bronzewing" }, + { id: 11, text: "Splendid fairy-wren" }, + { id: 12, text: "Mouse or smaller?" }, + { id: 13, text: "Carnaby's black cockatoo" }, + { id: 14, text: "Spotted nightjar" }, + { id: 15, text: "Quenda" }, + { id: 16, text: "Common bronzewing" }, + { id: 17, text: "Tawny frogmouth" }, + { id: 18, text: "Quokka" }, + { id: 19, text: "Emu" }, + { id: 20, text: "Tawny-crowned honeyeater" }, + { id: 21, text: "Rabbit" }, + { id: 22, text: "Galah" }, + { id: 23, text: "Wedge-tailed eagle" }, + { id: 24, text: "Western brush wallaby" }, + { id: 25, text: "Grey butcherbird" }, + { id: 26, text: "Welcome swallow" }, + { id: 27, text: "Western grey kangaroo" }, + { id: 28, text: "Grey currawong" }, + { id: 29, text: "Western bristlebird" }, + { id: 30, text: "Western ringtail possum" }, + { id: 31, text: "Grey fantail" }, + { id: 32, text: "Western fieldwren" }, + { id: 33, text: "Faulty" }, + { id: 34, text: "Laughing kookaburra" }, + { id: 35, text: "Human" }, + { id: 36, text: "Magpie" }, + { id: 37, text: "Western rosella" }, + { id: 38, text: "Nothing" }, + { id: 39, text: "Malleefowl" }, + { id: 40, text: "Western spinebill" }, + { id: 41, text: "Small mammal" }, + { id: 42, text: "Nankeen kestrel" }, + { id: 43, text: "Western wattlebird" }, + { id: 44, text: "Bird" }, + { id: 45, text: "New holland honeyeater" }, + { id: 46, text: "Western whipbird" }, + { id: 47, text: "Mammal" }, + { id: 48, text: "Noisy scrub-bird" }, + { id: 49, text: "Western whistler" }, + { id: 50, text: "Reptile" }, + { id: 51, text: "Painted button-quail" }, + { id: 52, text: "White-browed scrubwren" }, + { id: 53, text: "Bobtail skink" }, + { id: 54, text: "Purple swamphen" }, + { id: 55, text: "White-cheeked honeyeater" }, + { id: 56, text: "Heath monitor" }, + { id: 57, text: "Red wattlebird" }, + { id: 58, text: "Willie wagtail" }, + { id: 59, text: "King skink" }, + { id: 60, text: "Red-capped parrot" }, + { id: 61, text: "Brushtail possum" }, + { id: 62, text: "Western blue-tongued skink" }, + { id: 63, text: "Red-eared firetail" }, + { id: 64, text: "Bush rat" }, +]; + +const cloudClassificationOptions: ClassificationOption[] = [ + { + id: 1, + text: "Colour", + subOptions: [ + { id: 1, text: "White colour" }, + { id: 2, text: "Blue colour" }, + ], + }, + { + id: 2, + text: "Intensity", + subOptions: [ + { id: 1, text: "Bright clouds" }, + { id: 2, text: "Faint clouds" }, + { id: 3, text: "Medium clouds" }, + ], + }, + { + id: 3, + text: "Coverage", + subOptions: [ + { id: 1, text: "Clouds cover most of the height" }, + { id: 2, text: "Clouds are smaller" }, + ], + }, +]; + const planetClassificationOptions: ClassificationOption[] = [ { id: 1, text: 'No dips at all' }, { id: 2, text: 'Repeating dips' }, @@ -57,52 +152,6 @@ const roverImgClassificationOptions: ClassificationOption[] = [ { id: 6, text: 'Sandy/rocky terrain' }, ]; -const cloudClassificationOptions: ClassificationOption[] = [ - { - id: 1, - text: "Colour", - subOptions: [ - { id: 1, text: "White colour" }, - { id: 2, text: "Blue colour" }, - ], - }, - { - id: 2, - text: "Intensity", - subOptions: [ - { id: 1, text: "Bright clouds" }, - { id: 2, text: "Faint clouds" }, - { id: 3, text: "Medium clouds" }, - ], - }, - { - id: 3, - text: "Coverage", - subOptions: [ - { id: 1, text: "Clouds cover most of the height" }, - { id: 2, text: "Clouds are smaller" }, - ], - }, -]; - -// const initialCloudClassificationOptions: ClassificationOption[] = [ -// { -// id: 1, -// text: "White colour", -// }, -// { -// id: 2, -// text: "Blue colour", -// }, -// { -// id: 3, -// text: "Bright clouds", -// }, -// { -// id: 4, text: "Large clouds", -// }, -// ]; - const initialCloudClassificationOptions: ClassificationOption[] = [ { id: 1, @@ -194,74 +243,7 @@ const sunspotsConfigurationTemporary: ClassificationOption[] = [ id: 3, text: "Multiple sunspots", }, -]; - -const zoodexSouthCoastFaunaRecovery: ClassificationOption[] = [ - { id: 1, text: "Australian raven" }, - { id: 2, text: "Red-winged fairy-wren" }, - { id: 3, text: "Cat" }, - { id: 4, text: "Brown falcon" }, - { id: 5, text: "Silvereye" }, - { id: 6, text: "Echidna" }, - { id: 7, text: "Brown quail" }, - { id: 8, text: "Southern emu-wren" }, - { id: 9, text: "Fox" }, - { id: 10, text: "Brush bronzewing" }, - { id: 11, text: "Splendid fairy-wren" }, - { id: 12, text: "Mouse or smaller?" }, - { id: 13, text: "Carnaby's black cockatoo" }, - { id: 14, text: "Spotted nightjar" }, - { id: 15, text: "Quenda" }, - { id: 16, text: "Common bronzewing" }, - { id: 17, text: "Tawny frogmouth" }, - { id: 18, text: "Quokka" }, - { id: 19, text: "Emu" }, - { id: 20, text: "Tawny-crowned honeyeater" }, - { id: 21, text: "Rabbit" }, - { id: 22, text: "Galah" }, - { id: 23, text: "Wedge-tailed eagle" }, - { id: 24, text: "Western brush wallaby" }, - { id: 25, text: "Grey butcherbird" }, - { id: 26, text: "Welcome swallow" }, - { id: 27, text: "Western grey kangaroo" }, - { id: 28, text: "Grey currawong" }, - { id: 29, text: "Western bristlebird" }, - { id: 30, text: "Western ringtail possum" }, - { id: 31, text: "Grey fantail" }, - { id: 32, text: "Western fieldwren" }, - { id: 33, text: "Faulty" }, - { id: 34, text: "Laughing kookaburra" }, - { id: 35, text: "Human" }, - { id: 36, text: "Magpie" }, - { id: 37, text: "Western rosella" }, - { id: 38, text: "Nothing" }, - { id: 39, text: "Malleefowl" }, - { id: 40, text: "Western spinebill" }, - { id: 41, text: "Small mammal" }, - { id: 42, text: "Nankeen kestrel" }, - { id: 43, text: "Western wattlebird" }, - { id: 44, text: "Bird" }, - { id: 45, text: "New holland honeyeater" }, - { id: 46, text: "Western whipbird" }, - { id: 47, text: "Mammal" }, - { id: 48, text: "Noisy scrub-bird" }, - { id: 49, text: "Western whistler" }, - { id: 50, text: "Reptile" }, - { id: 51, text: "Painted button-quail" }, - { id: 52, text: "White-browed scrubwren" }, - { id: 53, text: "Bobtail skink" }, - { id: 54, text: "Purple swamphen" }, - { id: 55, text: "White-cheeked honeyeater" }, - { id: 56, text: "Heath monitor" }, - { id: 57, text: "Red wattlebird" }, - { id: 58, text: "Willie wagtail" }, - { id: 59, text: "King skink" }, - { id: 60, text: "Red-capped parrot" }, - { id: 61, text: "Brushtail possum" }, - { id: 62, text: "Western blue-tongued skink" }, - { id: 63, text: "Red-eared firetail" }, - { id: 64, text: "Bush rat" }, -]; +]; // text-only? interface ClassificationFormProps { anomalyType: string; @@ -306,7 +288,7 @@ const ClassificationForm: React.FC = ({ anomalyType, an case 'DiskDetective': return "Describe the object seen in the disk..."; case 'sunspot': - return "Describe the sunspots you see..."; + return "Describe the sunspots you see and how many..."; default: return "Enter your classification details..."; }; @@ -329,12 +311,17 @@ const ClassificationForm: React.FC = ({ anomalyType, an case 'DiskDetective': return diskDetectorClassificationOptions; case 'sunspot': - return sunspotsConfigurationTemporary; + // return sunspotsConfigurationTemporary; + return []; + case 'zoodex-nestQuestGo': + return []; default: return []; }; })(); + const showTextArea = classificationOptions.length === 0; + const [hasClassified, setHasClassified] = useState(false); const [showResearch, setShowResearch] = useState(false); @@ -370,6 +357,7 @@ const ClassificationForm: React.FC = ({ anomalyType, an .select("username, avatar_url") .eq("id", session?.user?.id) .single(); + if (data) { setAvatarUrl(data.avatar_url); }; @@ -467,21 +455,21 @@ const ClassificationForm: React.FC = ({ anomalyType, an currentConfig = inventoryData?.configuration || {}; if (currentConfig.Uses) { - currentConfig.Uses = Math.max(0, currentConfig.Uses - 1); // Decrement "Uses" value - } - } + currentConfig.Uses = Math.max(0, currentConfig.Uses - 1); + }; + }; - // Update the inventory item with the new configuration if (inventoryItemId) { const { error: updateError } = await supabase .from('inventory') .update({ configuration: currentConfig }) .eq('id', inventoryItemId); - if (updateError) throw updateError; - } + if (updateError) { + throw updateError; + }; + }; - // Create classification post const { data: classificationData, error: classificationError } = await supabase .from("classifications") .insert({ @@ -495,7 +483,7 @@ const ClassificationForm: React.FC = ({ anomalyType, an .single(); if (classificationError) { - console.error("Error creating classification:", classificationError.message); + console.error("Error creating classification: ", classificationError.message); alert("Failed to create classification. Please try again."); return; } else { @@ -510,7 +498,6 @@ const ClassificationForm: React.FC = ({ anomalyType, an }, 1200); }; - // Update user's classification points const { data: profileData, error: profileError } = await supabase .from('profiles') .select('classificationPoints') @@ -528,18 +515,8 @@ const ClassificationForm: React.FC = ({ anomalyType, an if (updatePointsError) throw updatePointsError; - // Reset user's active mission to null after classification is created - const { error: resetMissionError } = await supabase - .from('profiles') - .update({ activemission: null }) - .eq('id', session?.user?.id); - - if (resetMissionError) { - console.error("Error resetting active mission:", resetMissionError.message); - }; - await handleMissionComplete(); - } catch (error) { + } catch (error: any) { console.error("Unexpected error:", error); }; }; @@ -591,26 +568,26 @@ const ClassificationForm: React.FC = ({ anomalyType, an return (
- {/* Conditional rendering for "Uses" value */} {uses !== null && uses <= 0 ? (
You need to repair the structure's durability before you can use it.
) : ( -
-
- {classificationOptions.map(option => ( - - ))} -
-
- <> +
+ {classificationOptions.length > 0 ? ( +
+
+ {classificationOptions.map(option => ( + + ))} +
+
= ({ anomalyType, an value={content} onChange={e => setContent(e.target.value)} className="flex-grow p-3 h-24 text-white rounded-xl border border-[#3B4252] bg-[#3B4252] focus:border-[#88C0D0] focus:ring focus:ring-[#88C0D0] outline-none" - // placeholder={`What do you think about this ${anomalyType === "planet" ? "planet" : "rover image"}?`} placeholder={placeholder} />
@@ -643,12 +619,47 @@ const ClassificationForm: React.FC = ({ anomalyType, an > Submit - -
+
+
+ ) : ( +
+
+ { + setAvatarUrl(filePath); + }} + /> +