-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
️🦋🏛️️ ↝ [SSG-111 SSG-112 SSG-109 SSG-107]: New modal flow for greenho…
…use/biodome 3104, and exporting of post cards now works
- Loading branch information
1 parent
870e0b8
commit b3dc425
Showing
13 changed files
with
764 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
components/Structures/Missions/Biologists/BiomePattern.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Biome } from "@/types/station" | ||
|
||
interface BiomePatternProps { | ||
biome: Biome | ||
className?: string | ||
} | ||
|
||
export function BiomePattern({ biome, className = "" }: BiomePatternProps) { | ||
// Generate a hex-like pattern | ||
const generateHexPattern = () => { | ||
const pattern = [] | ||
const rows = 3 | ||
const cols = 6 | ||
|
||
for (let i = 0; i < rows; i++) { | ||
for (let j = 0; j < cols; j++) { | ||
const isOffset = i % 2 === 0 | ||
const colorIndex = (i * j + j) % 3 | ||
const color = colorIndex === 0 ? biome.accentColor : colorIndex === 1 ? biome.color : biome.darkColor | ||
|
||
pattern.push( | ||
<div | ||
key={`${i}-${j}`} | ||
className={`relative h-8 w-8 ${isOffset ? "translate-x-4" : ""}`} | ||
style={{ | ||
clipPath: "polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)", | ||
backgroundColor: color, | ||
opacity: Math.random() * 0.5 + 0.5, // Random opacity for more variety | ||
transform: `rotate(${Math.random() * 30}deg)`, // Slight random rotation | ||
}} | ||
> | ||
{/* Add subtle inner glow */} | ||
<div | ||
className="absolute inset-0 opacity-50" | ||
style={{ | ||
background: `radial-gradient(circle at center, ${biome.accentColor}22 0%, transparent 70%)`, | ||
}} | ||
/> | ||
</div>, | ||
) | ||
} | ||
} | ||
return pattern | ||
} | ||
|
||
return ( | ||
<div className={`relative overflow-hidden rounded-lg ${className}`}> | ||
{/* Background gradient */} | ||
<div | ||
className="absolute inset-0 opacity-30" | ||
style={{ | ||
background: `linear-gradient(45deg, ${biome.darkColor}, ${biome.color})`, | ||
}} | ||
/> | ||
|
||
{/* Animated scan line */} | ||
<div | ||
className="absolute inset-0 animate-scan" | ||
style={{ | ||
background: "linear-gradient(transparent 0%, rgba(255,255,255,0.1) 50%, transparent 100%)", | ||
backgroundSize: "100% 200%", | ||
animation: "scan 4s linear infinite", | ||
}} | ||
/> | ||
|
||
{/* Hex pattern container */} | ||
<div className="relative flex flex-wrap justify-center gap-0 py-2">{generateHexPattern()}</div> | ||
|
||
{/* Grid overlay */} | ||
<div | ||
className="absolute inset-0" | ||
style={{ | ||
backgroundImage: ` | ||
linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px), | ||
linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px) | ||
`, | ||
backgroundSize: "20px 20px", | ||
}} | ||
/> | ||
</div> | ||
) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" | ||
import { Progress } from "./Progress" | ||
import type { Milestone } from "@/types/milestone" | ||
import { Trophy, Target, Globe } from "lucide-react" | ||
|
||
const iconMap = { | ||
animals: Trophy, | ||
stations: Target, | ||
biomes: Globe, | ||
} | ||
|
||
interface MilestonesProps { | ||
milestones: Milestone[] | ||
} | ||
|
||
export function Milestones({ milestones }: MilestonesProps) { | ||
return ( | ||
<div className="space-y-4"> | ||
<h2 className="text-2xl font-semibold text-blue-400">Research Milestones</h2> | ||
<div className="grid gap-4"> | ||
{milestones.map((milestone) => { | ||
const Icon = iconMap[milestone.type] | ||
|
||
return ( | ||
<Card key={milestone.id} className="bg-black/40 border-gray-800"> | ||
<CardHeader className="pb-2"> | ||
<CardTitle className="flex items-center gap-2 text-lg text-white"> | ||
<Icon className="w-5 h-5 text-blue-400" /> | ||
{milestone.title} | ||
</CardTitle> | ||
</CardHeader> | ||
<CardContent> | ||
<p className="text-sm text-gray-400 mb-2">{milestone.description}</p> | ||
<div className="space-y-1"> | ||
<Progress value={milestone.current} max={milestone.target} /> | ||
<p className="text-sm text-blue-400"> | ||
Progress: {milestone.current} / {milestone.target} | ||
</p> | ||
</div> | ||
</CardContent> | ||
</Card> | ||
) | ||
})} | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
interface ProgressProps { | ||
value: number | ||
max: number | ||
} | ||
|
||
export function Progress({ value, max }: ProgressProps) { | ||
const percentage = (value / max) * 100 | ||
|
||
return ( | ||
<div className="relative w-full h-2 bg-gray-800 rounded-full overflow-hidden"> | ||
<div | ||
className="absolute left-0 top-0 h-full bg-gradient-to-r from-blue-500 to-blue-400" | ||
style={{ width: `${percentage}%` }} | ||
> | ||
<div className="absolute inset-0 bg-[linear-gradient(90deg,transparent_0%,rgba(255,255,255,0.2)_50%,transparent_100%)] animate-shimmer" /> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
172 changes: 172 additions & 0 deletions
172
components/Structures/Missions/Biologists/ResearchStations.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { useState } from "react"; | ||
import { StationCard } from "./StationCard"; | ||
import { Milestones } from "./Milestones"; | ||
import type { Station } from "@/types/station"; | ||
import type { Milestone } from "@/types/milestone"; | ||
|
||
const initialStations: Station[] = [ | ||
{ | ||
id: "1", | ||
name: "Coral Reef Observatory", | ||
icon: "Anchor", | ||
biome: { | ||
name: "Marine", | ||
color: "rgb(37, 99, 235)", | ||
accentColor: "rgb(59, 130, 246)", | ||
darkColor: "rgb(30, 58, 138)", | ||
}, | ||
animals: [ | ||
{ name: "Clownfish", icon: "Fish" }, | ||
{ name: "Sea Turtle", icon: "Turtle" }, | ||
{ name: "Coral", icon: "Flower2" }, | ||
], | ||
location: { | ||
coordinates: "23.4162° N, 75.2397° W", | ||
depth: "-45m", | ||
}, | ||
built: false, | ||
}, | ||
{ | ||
id: "2", | ||
name: "Rainforest Canopy Station", | ||
icon: "Trees", | ||
biome: { | ||
name: "Tropical", | ||
color: "rgb(22, 163, 74)", | ||
accentColor: "rgb(34, 197, 94)", | ||
darkColor: "rgb(20, 83, 45)", | ||
}, | ||
animals: [ | ||
{ name: "Toucan", icon: "Bird" }, | ||
{ name: "Monkey", icon: "Monkey" }, | ||
{ name: "Butterfly", icon: "Bug" }, | ||
], | ||
location: { | ||
coordinates: "2.4162° S, 54.2397° W", | ||
altitude: "40m", | ||
}, | ||
built: false, | ||
}, | ||
{ | ||
id: "3", | ||
name: "Arctic Research Base", | ||
icon: "Snowflake", | ||
biome: { | ||
name: "Polar", | ||
color: "rgb(148, 163, 184)", | ||
accentColor: "rgb(226, 232, 240)", | ||
darkColor: "rgb(51, 65, 85)", | ||
}, | ||
animals: [ | ||
{ name: "Polar Bear", icon: "Bear" }, | ||
{ name: "Penguin", icon: "Bird" }, | ||
{ name: "Seal", icon: "Fish" }, | ||
], | ||
location: { | ||
coordinates: "78.4162° N, 15.2397° E", | ||
}, | ||
built: false, | ||
}, | ||
{ | ||
id: "4", | ||
name: "Deep Sea Laboratory", | ||
icon: "Waves", | ||
biome: { | ||
name: "Abyssal", | ||
color: "rgb(30, 58, 138)", | ||
accentColor: "rgb(37, 99, 235)", | ||
darkColor: "rgb(30, 27, 75)", | ||
}, | ||
animals: [ | ||
{ name: "Anglerfish", icon: "Fish" }, | ||
{ name: "Giant Squid", icon: "Bug" }, | ||
{ name: "Tube Worm", icon: "Wand2" }, | ||
], | ||
location: { | ||
coordinates: "31.4162° N, 159.2397° W", | ||
depth: "-2500m", | ||
}, | ||
built: false, | ||
}, | ||
]; | ||
|
||
const initialMilestones: Milestone[] = [ | ||
{ | ||
id: "1", | ||
title: "Wildlife Observer", | ||
description: "Discover and document different animal species", | ||
current: 3, | ||
target: 10, | ||
type: "animals", | ||
}, | ||
{ | ||
id: "2", | ||
title: "Global Network", | ||
description: "Establish research stations worldwide", | ||
current: 1, | ||
target: 5, | ||
type: "stations", | ||
}, | ||
{ | ||
id: "3", | ||
title: "Biome Explorer", | ||
description: "Research different environmental biomes", | ||
current: 1, | ||
target: 4, | ||
type: "biomes", | ||
}, | ||
]; | ||
|
||
export function GreenhouseResearchStations() { | ||
const [stations, setStations] = useState<Station[]>(initialStations) | ||
const [milestones, setMilestones] = useState<Milestone[]>(initialMilestones) | ||
|
||
const handleBuild = (id: string) => { | ||
setStations(stations.map((station) => (station.id === id ? { ...station, built: true } : station))) | ||
// Update station milestone | ||
setMilestones( | ||
milestones.map((milestone) => | ||
milestone.type === "stations" ? { ...milestone, current: milestone.current + 1 } : milestone, | ||
), | ||
); | ||
}; | ||
|
||
const buildableStations = stations.filter((station) => !station.built) | ||
const builtStations = stations.filter((station) => station.built) | ||
|
||
return ( | ||
<div className="min-h-screen bg-gray-900 bg-[linear-gradient(rgba(0,0,0,0.7),rgba(0,0,0,0.7)),repeating-linear-gradient(0deg,transparent,transparent_40px,rgba(71,85,105,0.1)_40px,rgba(71,85,105,0.1)_80px)]"> | ||
<div className="container mx-auto px-4 py-8"> | ||
<h1 className="text-4xl font-bold mb-8 text-white tracking-tight">Research Stations</h1> | ||
|
||
<div className="grid lg:grid-cols-[2fr,1fr] gap-8"> | ||
<div className="space-y-8"> | ||
<section> | ||
<h2 className="text-2xl font-semibold mb-4 text-blue-400">Available Stations</h2> | ||
<div className="grid gap-6"> | ||
{buildableStations.map((station) => ( | ||
<StationCard key={station.id} station={station} onBuild={handleBuild} /> | ||
))} | ||
</div> | ||
</section> | ||
|
||
{builtStations.length > 0 && ( | ||
<section> | ||
<h2 className="text-2xl font-semibold mb-4 text-blue-400">Built Stations</h2> | ||
<div className="grid gap-6"> | ||
{builtStations.map((station) => ( | ||
<StationCard key={station.id} station={station} onBuild={handleBuild} /> | ||
))} | ||
</div> | ||
</section> | ||
)} | ||
</div> | ||
|
||
<div className="lg:border-l lg:border-gray-800 lg:pl-8"> | ||
<Milestones milestones={milestones} /> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.