11import { useState } from "react" ;
22import { useStore } from "../state/store" ;
3- import type { SkillDetail } from "../transport/protocol" ;
3+ import type { SkillCard , SkillDetail } from "../transport/protocol" ;
44import { SkillIcon } from "../icons" ;
55
66interface Props {
77 detail : SkillDetail ;
88 owned : boolean ;
99 onBack : ( ) => void ;
10+ onOpenSkill ?: ( card : SkillCard ) => void ;
1011}
1112
12- export function SkillDetailView ( { detail, owned, onBack } : Props ) {
13- const { send } = useStore ( ) ;
13+ export function SkillDetailView ( { detail, owned, onBack, onOpenSkill } : Props ) {
14+ const { state , send } = useStore ( ) ;
1415 const [ buying , setBuying ] = useState ( false ) ;
1516 const [ noteText , setNoteText ] = useState ( "" ) ;
1617 const [ noteGitLink , setNoteGitLink ] = useState ( "" ) ;
1718 const { card, skillText, notes } = detail ;
1819 const priceSol = card . price ? ( Number ( card . price ) / 1_000_000_000 ) . toFixed ( 3 ) : null ;
20+ const disposed = Object . values ( state . marketDisposed ) . includes ( card . id ) ;
1921
2022 function handleBuy ( ) {
2123 setBuying ( true ) ;
@@ -40,6 +42,11 @@ export function SkillDetailView({ detail, owned, onBack }: Props) {
4042 owned
4143 </ span >
4244 ) }
45+ { disposed && (
46+ < span className = "ml-auto shrink-0 rounded px-1.5 py-0.5 text-[10px] font-semibold bg-zinc-800 text-zinc-500" >
47+ un-equipped
48+ </ span >
49+ ) }
4350 </ header >
4451
4552 < div className = "flex-1 overflow-y-auto p-3 space-y-4" >
@@ -68,6 +75,25 @@ export function SkillDetailView({ detail, owned, onBack }: Props) {
6875 </ div >
6976 ) }
7077
78+ { Array . isArray ( detail . requiredCards ) && detail . requiredCards . length > 0 && (
79+ < div className = "space-y-2" >
80+ < p className = "text-[11px] text-zinc-500 uppercase tracking-wide" > Required skills</ p >
81+ < div className = "space-y-2" >
82+ { detail . requiredCards . map ( ( req ) => (
83+ < button
84+ key = { req . id }
85+ type = "button"
86+ onClick = { ( ) => onOpenSkill ?.( req ) }
87+ className = "w-full rounded-lg bg-zinc-900 border border-zinc-800 p-2.5 text-left active:bg-zinc-800"
88+ >
89+ < p className = "text-xs font-medium text-zinc-200" > { req . name } </ p >
90+ < p className = "mt-0.5 line-clamp-2 text-[11px] text-zinc-500" > { req . description } </ p >
91+ </ button >
92+ ) ) }
93+ </ div >
94+ </ div >
95+ ) }
96+
7197 { Array . isArray ( notes ) && notes . length > 0 && (
7298 < div className = "space-y-2" >
7399 < p className = "text-[11px] text-zinc-500 uppercase tracking-wide" > Comments</ p >
@@ -107,7 +133,29 @@ export function SkillDetailView({ detail, owned, onBack }: Props) {
107133 ) }
108134 </ div >
109135
110- { ! owned && (
136+ { owned && (
137+ < div className = "shrink-0 border-t border-red-900/40 bg-gradient-to-t from-red-950/30 to-transparent p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]" >
138+ < button
139+ onClick = { ( ) => send ( { type : "disposeSkill" , skillId : card . id } ) }
140+ className = "w-full rounded-xl border border-red-500/30 bg-red-950/20 py-3 text-sm font-semibold text-red-400 active:bg-red-900/30"
141+ >
142+ Remove Skill
143+ </ button >
144+ </ div >
145+ ) }
146+
147+ { ! owned && disposed && (
148+ < div className = "shrink-0 border-t border-green-800/40 bg-gradient-to-t from-green-900/30 to-transparent p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]" >
149+ < button
150+ onClick = { ( ) => send ( { type : "reEquipSkill" , skillId : card . id } ) }
151+ className = "w-full rounded-xl bg-green-600 py-3 text-sm font-semibold text-white active:bg-green-500"
152+ >
153+ Re-equip Skill
154+ </ button >
155+ </ div >
156+ ) }
157+
158+ { ! owned && ! disposed && (
111159 < div className = "shrink-0 border-t border-amber-700/40 bg-gradient-to-t from-amber-900/30 to-transparent p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]" >
112160 < button
113161 onClick = { handleBuy }
0 commit comments