1
1
import { useState } from "react" ;
2
- import { Button } from "@/components/ui/button" ;
3
- import { Card , CardContent } from "@/components/ui/card" ;
2
+ import { Button } from "@/components/ui/button" ;
4
3
import { motion } from "framer-motion" ;
5
- import { AnimatePresence } from "framer-motion" ;
4
+ import { AnimatePresence } from "framer-motion" ;
6
5
7
6
interface MissionConfig {
8
7
id : number ;
@@ -17,87 +16,94 @@ interface MissionConfig {
17
16
}
18
17
19
18
interface MissionShellProps {
20
- missions : MissionConfig [ ] ;
21
- experiencePoints : number ;
22
- level : number ;
23
- currentChapter : number ;
19
+ missions : MissionConfig [ ] ;
20
+ experiencePoints : number ;
21
+ level : number ;
22
+ currentChapter : number ;
24
23
}
25
24
26
25
const MissionShell = ( { missions, experiencePoints, level, currentChapter } : MissionShellProps ) => {
27
- const [ selectedMission , setSelectedMission ] = useState < MissionConfig | null > ( null ) ;
28
-
29
- const renderMission = ( mission : MissionConfig ) => {
30
- const completedCount = mission . completedCount ?? 0 ;
31
-
32
- return (
33
- < div
34
- key = { mission . id }
35
- className = { `flex items-center p-6 rounded-2xl cursor-pointer${
36
- mission . id > 2 ? "bg-[#74859A]" : mission . id < 3 ? "bg-gray-000" : completedCount > 0 ? "bg-gray-700" : ""
37
- } `}
38
- onClick = { ( ) => setSelectedMission ( mission ) }
39
- >
40
- < mission . icon className = { `w-10 h-10 ${ mission . color } ` } />
41
- < div className = "ml-4" >
42
- < h2 className = { `text-lg font-bold ${ mission . color } ` } > { mission . title } </ h2 >
43
- < p className = { `text-sm ${ mission . color } ` } > { mission . description } </ p >
44
- < p className = { `text-sm ${ mission . color } ` } > Points: { mission . points } </ p >
45
- </ div >
46
- < div className = "ml-auto text-right" >
47
- < p className = "text-xs" > Completed: { completedCount } </ p >
48
- < p className = "text-xl font-bold" > { completedCount } </ p >
49
- </ div >
50
- </ div >
51
- ) ;
52
- } ;
53
-
26
+ const [ selectedMission , setSelectedMission ] = useState < MissionConfig | null > ( null ) ;
27
+
28
+ const renderMission = ( mission : MissionConfig ) => {
29
+ const completedCount = mission . completedCount ?? 0 ;
30
+
54
31
return (
55
- < div className = "flex flex-col items-center bg-[#1D2833] text-white rounded-2xl shadow-lg p-6 w-full max-w-4xl mx-auto" >
56
- < div className = "flex justify-between w-full mb-6" >
57
- < h1 className = "text-xl font-bold" > Chapter { currentChapter } </ h1 >
58
- </ div >
59
- < div className = "flex-1 overflow-y-auto w-full" >
60
- < div className = "w-full bg-gray-700 rounded-full h-4 mb-6" >
61
- < div
62
- className = "bg-[#5FCBC3] h-4 rounded-full"
63
- style = { { width : `${ ( experiencePoints % 9 ) * 10.5 } %` } }
64
- > </ div >
65
- </ div >
32
+ < div
33
+ key = { mission . id }
34
+ className = { `flex items-center p-6 rounded-2xl cursor-pointer${
35
+ mission . id > 2
36
+ ? "bg-[#74859A]"
37
+ : mission . id < 3
38
+ ? "bg-gray-000"
39
+ : completedCount > 0
40
+ ? "bg-gray-700"
41
+ : ""
42
+ } `}
43
+ onClick = { ( ) => setSelectedMission ( mission ) }
44
+ >
45
+ < mission . icon className = { `w-10 h-10 ${ mission . color } ` } />
46
+ < div className = "ml-4" >
47
+ < h2 className = { `text-lg font-bold ${ mission . color } ` } > { mission . title } </ h2 >
48
+ < p className = { `text-sm ${ mission . color } ` } > { mission . description } </ p >
49
+ < p className = { `text-sm ${ mission . color } ` } > Points: { mission . points } </ p >
66
50
</ div >
67
- < p className = "text-sm text-center mb-6" >
68
- Level { level } ({ experiencePoints } points)
69
- </ p >
70
- < div className = "bg-gray-700 p-6 rounded-2xl w-full mb-6" >
71
- < div className = "grid grid-cols-2 gap-4 w-full" >
72
- { missions . slice ( 0 , 2 ) . map ( ( mission ) => renderMission ( mission ) ) }
73
- </ div >
51
+ < div className = "ml-auto text-right" >
52
+ < p className = "text-xs" > Completed: { completedCount } </ p >
53
+ < p className = "text-xl font-bold" > { completedCount } </ p >
74
54
</ div >
75
- < div className = "grid gap-4 w-full mt-6" >
76
- { missions . slice ( 2 ) . map ( ( mission ) => renderMission ( mission ) ) }
77
- </ div >
78
- < AnimatePresence >
79
- { selectedMission && (
80
- < motion . div
81
- className = "fixed inset-0 flex justify-center items-center bg-black bg-opacity-50"
82
- initial = { { opacity : 0 , y : - 10 } }
83
- animate = { { opacity : 1 , y : 0 } }
84
- exit = { { opacity : 0 , y : - 10 } }
85
- >
86
- < div className = "bg-[#2C4F64] p-6 rounded-lg max-w-md w-full" >
87
- < h3 className = "text-xl font-semibold mb-2" > { selectedMission . title } </ h3 >
88
- < p > { selectedMission . description } </ p >
89
- < div className = "mt-4" >
90
- { selectedMission . internalComponent && < selectedMission . internalComponent /> }
91
- </ div >
92
- < Button onClick = { ( ) => setSelectedMission ( null ) } className = "mt-4" >
93
- Close
94
- </ Button >
95
- </ div >
96
- </ motion . div >
97
- ) }
98
- </ AnimatePresence >
99
55
</ div >
100
56
) ;
57
+ } ;
58
+
59
+ return (
60
+ < div className = "flex flex-col items-center bg-[#1D2833] text-white rounded-2xl shadow-lg p-6 w-full max-w-4xl mx-auto" >
61
+ { ! selectedMission && (
62
+ < >
63
+ < div className = "flex justify-between w-full mb-6" >
64
+ < h1 className = "text-xl font-bold" > Chapter { currentChapter } </ h1 >
65
+ </ div >
66
+ < div className = "flex-1 overflow-y-auto w-full" >
67
+ < div className = "w-full bg-gray-700 rounded-full h-4 mb-6" >
68
+ < div
69
+ className = "bg-[#5FCBC3] h-4 rounded-full"
70
+ style = { { width : `${ ( experiencePoints % 9 ) * 10.5 } %` } }
71
+ > </ div >
72
+ </ div >
73
+ </ div >
74
+ < p className = "text-sm text-center mb-6" >
75
+ Level { level } ({ experiencePoints } points)
76
+ </ p >
77
+ < div className = "bg-gray-700 p-6 rounded-2xl w-full mb-6" >
78
+ < div className = "grid grid-cols-2 gap-4 w-full" >
79
+ { missions . slice ( 0 , 2 ) . map ( ( mission ) => renderMission ( mission ) ) }
80
+ </ div >
81
+ </ div >
82
+ < div className = "grid gap-4 w-full mt-6" >
83
+ { missions . slice ( 2 ) . map ( ( mission ) => renderMission ( mission ) ) }
84
+ </ div >
85
+ </ >
86
+ ) }
87
+ < AnimatePresence >
88
+ { selectedMission && (
89
+ < motion . div
90
+ className = "flex flex-col bg-[#1D2833]"
91
+ initial = { { opacity : 0 } }
92
+ animate = { { opacity : 1 } }
93
+ exit = { { opacity : 0 } }
94
+ >
95
+ < div className = "flex justify-between items-center p-4" >
96
+ < h3 className = "text-xl font-semibold" > { selectedMission . title } </ h3 >
97
+ < Button onClick = { ( ) => setSelectedMission ( null ) } > Back</ Button >
98
+ </ div >
99
+ < div className = "flex-1 overflow-auto" >
100
+ { selectedMission . internalComponent && < selectedMission . internalComponent /> }
101
+ </ div >
102
+ </ motion . div >
103
+ ) }
104
+ </ AnimatePresence >
105
+ </ div >
106
+ ) ;
101
107
} ;
102
-
108
+
103
109
export default MissionShell ;
0 commit comments