Skip to content

Commit 456666e

Browse files
committed
🚵🏻‍♀️🌈 ↝ [SSP-39 SSP-42]: Generators can now show in missions inside alternate post card views
1 parent 0f6b300 commit 456666e

File tree

7 files changed

+373
-9
lines changed

7 files changed

+373
-9
lines changed

components/Structures/Missions/Astronomers/PlanetHunters/PlanetHunters.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useEffect, useState } from "react";
22
import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react";
3-
import { TelescopeIcon, RadioIcon, SpeakerIcon, DiscAlbum, PersonStandingIcon } from "lucide-react";
3+
import { TelescopeIcon, RadioIcon, SpeakerIcon, DiscAlbum, PersonStandingIcon, Paintbrush2 } from "lucide-react";
44
import PlanetTypeCommentForm from "./PlanetType";
55
import { StarterTelescopeTess } from "@/components/Projects/Telescopes/Transiting";
66
import VotePlanetClassifictions from "./PHVote";
7+
import PHClassificationGenerator from "./PlanetMaker";
78

89
interface MissionStep {
910
id: number;
@@ -155,9 +156,9 @@ const PlanetHuntersSteps = () => {
155156
},
156157
{
157158
id: 5,
158-
title: "Demo Mission for Chapter 3",
159-
description: "This is a demo mission to simulate progress in chapter 3.",
160-
icon: PersonStandingIcon,
159+
title: "Make your own planet design",
160+
description: "You're now able to start creating visual representations of your discoveries. These will become more advanced and accurate the more data you discover",
161+
icon: Paintbrush2,
161162
action: () => {},
162163
completedCount: 0,
163164
color: "text-yellow-500",
@@ -193,7 +194,7 @@ const PlanetHuntersSteps = () => {
193194
{selectedMission.id === 2 && <StarterTelescopeTess />}
194195
{selectedMission.id === 3 && <PlanetTypeCommentForm />}
195196
{selectedMission.id === 4 && <VotePlanetClassifictions />}
196-
{selectedMission.id === 5 && <div>Demo Mission for Chapter 3</div>}
197+
{selectedMission.id === 5 && <PHClassificationGenerator />}
197198
</center>
198199
</div>
199200
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"use client";
2+
3+
import React, { useEffect, useState } from "react";
4+
import { PostCardSingleWithGenerator } from "@/content/Posts/PostWithGen";
5+
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
6+
7+
interface Classification {
8+
id: number;
9+
created_at: string;
10+
content: string | null;
11+
author: string | null;
12+
anomaly: number | null;
13+
media: any | null;
14+
classificationtype: string | null;
15+
classificationConfiguration: any | null;
16+
};
17+
18+
export default function PHClassificationGenerator() {
19+
const supabase = useSupabaseClient();
20+
const session = useSession();
21+
22+
const [classifications, setClassifications] = useState<any[]>([]);
23+
const [loading, setLoading] = useState<boolean>(true);
24+
const [error, setError] = useState<string | null>(null);
25+
26+
const fetchClassifications = async () => {
27+
if (!session?.user) {
28+
setError("User session not found.");
29+
setLoading(false);
30+
return;
31+
};
32+
33+
setLoading(true);
34+
setError(null);
35+
try {
36+
const { data, error } = await supabase
37+
.from('classifications')
38+
.select('*')
39+
.eq("author", session.user.id)
40+
.eq('classificationtype', 'planet')
41+
.order('created_at', { ascending: false }) as { data: Classification[]; error: any };
42+
43+
if (error) throw error;
44+
45+
const processedData = data.map((classification) => {
46+
const media = classification.media;
47+
let images: string[] = [];
48+
49+
if (Array.isArray(media) && media.length === 2 && typeof media[1] === "string") {
50+
images.push(media[1]);
51+
} else if (media && media.uploadUrl) {
52+
images.push(media.uploadUrl);
53+
};
54+
55+
const votes = classification.classificationConfiguration?.votes || 0;
56+
57+
return { ...classification, images, votes };
58+
});
59+
60+
setClassifications(processedData);
61+
} catch (error) {
62+
console.error("Error fetching classifications:", error);
63+
setError("Failed to load classifications.");
64+
} finally {
65+
setLoading(false);
66+
};
67+
};
68+
69+
useEffect(() => {
70+
fetchClassifications();
71+
}, [session]);
72+
73+
return (
74+
<div className="space-y-8">
75+
{loading ? (
76+
<p>Loading classifications</p>
77+
) : error ? (
78+
<p>{error}</p>
79+
) : (
80+
classifications.map((classification) => (
81+
<PostCardSingleWithGenerator
82+
key={classification.id}
83+
classificationId={classification.id}
84+
title={classification.title}
85+
author={classification.author}
86+
content={classification.content}
87+
votes={classification.votes || 0}
88+
category={classification.category}
89+
tags={classification.tags || []}
90+
images={classification.images || []}
91+
anomalyId={classification.anomaly}
92+
classificationConfig={classification.classificationConfiguration}
93+
classificationType={classification.classificationtype}
94+
/>
95+
))
96+
)}
97+
</div>
98+
);
99+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"use client";
2+
3+
import React, { useEffect, useState } from "react";
4+
import { PostCardSingleWithGenerator } from "@/content/Posts/PostWithGen";
5+
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react";
6+
7+
interface Classification {
8+
id: number;
9+
created_at: string;
10+
content: string | null;
11+
author: string | null;
12+
anomaly: number | null;
13+
media: any | null;
14+
classificationtype: string | null;
15+
classificationConfiguration: any | null;
16+
};
17+
18+
export default function CloudClassificationGenerator() {
19+
const supabase = useSupabaseClient();
20+
const session = useSession();
21+
22+
const [classifications, setClassifications] = useState<any[]>([]);
23+
const [loading, setLoading] = useState<boolean>(true);
24+
const [error, setError] = useState<string | null>(null);
25+
26+
const fetchClassifications = async () => {
27+
if (!session?.user) {
28+
setError("User session not found.");
29+
setLoading(false);
30+
return;
31+
};
32+
33+
setLoading(true);
34+
setError(null);
35+
try {
36+
const { data, error } = await supabase
37+
.from('classifications')
38+
.select('*')
39+
.eq("author", session.user.id)
40+
.eq('classificationtype', 'cloud')
41+
.order('created_at', { ascending: false }) as { data: Classification[]; error: any };
42+
43+
if (error) throw error;
44+
45+
const processedData = data.map((classification) => {
46+
const media = classification.media;
47+
let images: string[] = [];
48+
49+
if (Array.isArray(media) && media.length === 2 && typeof media[1] === "string") {
50+
images.push(media[1]);
51+
} else if (media && media.uploadUrl) {
52+
images.push(media.uploadUrl);
53+
}
54+
55+
const votes = classification.classificationConfiguration?.votes || 0;
56+
57+
return { ...classification, images, votes };
58+
});
59+
60+
setClassifications(processedData);
61+
} catch (error) {
62+
console.error("Error fetching classifications:", error);
63+
setError("Failed to load classifications.");
64+
} finally {
65+
setLoading(false);
66+
};
67+
};
68+
69+
useEffect(() => {
70+
fetchClassifications();
71+
}, [session]);
72+
73+
return (
74+
<div className="space-y-8">
75+
{loading ? (
76+
<p>Loading classifications</p>
77+
) : error ? (
78+
<p>{error}</p>
79+
) : (
80+
classifications.map((classification) => (
81+
<PostCardSingleWithGenerator
82+
key={classification.id}
83+
classificationId={classification.id}
84+
title={classification.title}
85+
author={classification.author}
86+
content={classification.content}
87+
votes={classification.votes || 0}
88+
category={classification.category}
89+
tags={classification.tags || []}
90+
images={classification.images || []}
91+
anomalyId={classification.anomaly}
92+
classificationConfig={classification.classificationConfiguration}
93+
classificationType={classification.classificationtype}
94+
/>
95+
))
96+
)}
97+
</div>
98+
);
99+
};

components/Structures/Missions/Meteorologists/Cloudspotting/CloudSignal.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export default function CloudSignal() {
322322
onClick={() => removeCloud(cloud.id)}
323323
>
324324
<Trash2 className="w-4 h-4" />
325-
</Button>
325+
</Button>
326326
</div>
327327
))}
328328
</div>

components/Structures/Missions/Meteorologists/Cloudspotting/CloudspottingOnMars.tsx

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useEffect, useState } from "react";
22
import { useSupabaseClient, useSession } from "@supabase/auth-helpers-react";
33
import MissionShell from "../../BasePlate";
4-
import { CloudCogIcon, FolderCog, Vote } from "lucide-react";
4+
import { CloudCogIcon, FolderCog, PaintBucket, Vote } from "lucide-react";
55
import { StarterLidar } from "@/components/Projects/Lidar/Clouds";
66
import VoteCoMClassifications from "./CoMVote";
7+
import CloudClassificationGenerator from "./CloudMaker";
78

89
interface Mission {
910
id: number;
@@ -75,13 +76,27 @@ const CloudspottingOnMars = () => {
7576
shadow: false,
7677
action: () => [],
7778
},
79+
{
80+
id: 4,
81+
chapter: 2,
82+
title: "Create a cloud representation",
83+
description:
84+
"You can now add a visual representation of the cloud to your original classification",
85+
icon: PaintBucket,
86+
points: 1,
87+
completedCount: 0,
88+
internalComponent: () => <CloudClassificationGenerator />,
89+
color: 'text-green-300',
90+
shadow: false,
91+
action: () => [],
92+
},
7893
];
7994
};
8095

8196
useEffect(() => {
8297
if (!session) {
8398
return;
84-
}
99+
};
85100

86101
const fetchMissionPoints = async (
87102
session: any,

components/Structures/Missions/Meteorologists/Cloudspotting/CoMVote.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default function VotePlanetClassifictions() {
6868

6969
useEffect(() => {
7070
fetchClassifications();
71-
}, [session])
71+
}, [session]);
7272

7373
const handleVote = async (classificationId: number, currentConfig: any) => {
7474
try {

0 commit comments

Comments
 (0)