diff --git a/src/components/extraSettingBar/index.tsx b/src/components/extraSettingBar/index.tsx index 2d5cde1..ef63d8f 100644 --- a/src/components/extraSettingBar/index.tsx +++ b/src/components/extraSettingBar/index.tsx @@ -1,5 +1,5 @@ 'use client' -import { EyeOff, Eye, Hammer, RefreshCw, ShieldBan, User, Swords, SkipForward, BowArrow, Info, RouteIcon, Search, CupSoda, UsersIcon } from "lucide-react" +import { EyeOff, Eye, Hammer, RefreshCw, ShieldBan, User, Swords, SkipForward, BowArrow, Info, RouteIcon, Search, CupSoda, UsersIcon, X, Check, Code, Plus } from "lucide-react" import useGlobalStore from '@/stores/globalStore' import { useTranslations } from "next-intl" import { getLocaleName, getNameChar } from "@/helper" @@ -39,19 +39,19 @@ export default function ExtraSettingBar() { ) const [showSearchStage, setShowSearchStage] = useState(false) const [showSearchLineup, setShowSearchLineup] = useState(false) - const [isChildClick, setIsChildClick] = useState(false) const [stageSearchTerm, setStageSearchTerm] = useState("") + const [lineupSearchTerm, setLineupSearchTerm] = useState("") const [stagePage, setStagePage] = useState(1) const pageSize = 30 const stageList = useMemo(() => Object.values(stage), [stage]) - const term = stageSearchTerm.toLowerCase() + const stageTerm = stageSearchTerm.toLowerCase() const filteredStages = useMemo(() => stageList.filter((s) => - getLocaleName(locale, s.Name).toLowerCase().includes(term) || - String(s.ID).toLowerCase().includes(term) - ), [stageList, term, locale]) + getLocaleName(locale, s.Name).toLowerCase().includes(stageTerm) || + String(s.ID).toLowerCase().includes(stageTerm) + ), [stageList, stageTerm, locale]) const paginatedStages = useMemo(() => filteredStages.slice( (stagePage - 1) * pageSize, @@ -60,164 +60,201 @@ export default function ExtraSettingBar() { const hasMorePages = useMemo(() => stagePage * pageSize < filteredStages.length, [stagePage, filteredStages]) - const onChangeSearch = (v: string) => { + const onChangeStageSearch = (v: string) => { setStageSearchTerm(v) setStagePage(1) } + // Filter avatars for lineup selector + const avatarList = useMemo(() => Object.values(mapAvatar), [mapAvatar]) + const filteredAvatars = useMemo(() => { + if (!lineupSearchTerm.trim()) return avatarList + const term = lineupSearchTerm.toLowerCase() + return avatarList.filter(a => { + const charName = getNameChar(locale, transI18n, a).toLowerCase() + return charName.includes(term) || a.ID.toString().includes(term) + }) + }, [avatarList, lineupSearchTerm, locale, transI18n]) + + const currentLineup = extraData?.theory_craft?.custom_lineup || [] + return ( -
+
{/* THEORY CRAFT */} {extraData?.theory_craft && ( -
-
-

- - {transI18n("theoryCraft")} -

-
- +
+ {/* Section Header */} +
+
+
+ +
+
+
+

+ {transI18n("theoryCraft")} +

+
+ +
+
+

+ {transI18n("detailTheoryCraft")} +

+
+
+ +
+ + { + setExtraData({ + ...extraData, + theory_craft: { + hp: extraData?.theory_craft?.hp || {}, + cycle_count: extraData?.theory_craft?.cycle_count || 1, + mode: e.target.checked, + stage_id: extraData?.theory_craft?.stage_id || 0, + custom_lineup: extraData?.theory_craft?.custom_lineup || [] + } + }) + }} + />
-
- - { - setExtraData({ - ...extraData, - theory_craft: { - hp: extraData?.theory_craft?.hp || {}, - cycle_count: extraData?.theory_craft?.cycle_count || 1, - mode: e.target.checked, - stage_id: extraData?.theory_craft?.stage_id || 0 - } - }) - }} - /> -
- + {/* Theorycraft Expanded Content */} {extraData?.theory_craft?.mode && ( -
- {/* Cycle Count */} -
-
- - {transI18n("cycleCount")} -
- - setExtraData({ - ...extraData, - theory_craft: { - hp: extraData?.theory_craft?.hp || {}, - cycle_count: Number(e.target.value) || 1, - mode: extraData?.theory_craft?.mode || false, - stage_id: extraData?.theory_craft?.stage_id || 0 +
+ {/* Simulation Settings Grid */} +
+ {/* Cycle Count */} +
+ +
+ + setExtraData({ + ...extraData, + theory_craft: { + hp: extraData?.theory_craft?.hp || {}, + cycle_count: Number(e.target.value) || 1, + mode: extraData?.theory_craft?.mode || false, + stage_id: extraData?.theory_craft?.stage_id || 0, + custom_lineup: extraData?.theory_craft?.custom_lineup || [] + } + }) } - }) - } - min="1" - /> -
+ min="1" + /> +
+
- {/* Stage Selection */} -
-
- - {transI18n("stage")} -
-
+ {/* Stage Selection */} +
+ + {/* Stage Search Popover */} {showSearchStage && ( -
e.stopPropagation()} className="absolute top-full mt-2 w-full z-50 bg-base-100 border border-base-content/15 rounded-2xl p-3.5 shadow-2xl space-y-3"> - onChangeSearch(e.target.value)} - autoFocus - /> +
e.stopPropagation()} + className="absolute top-full mt-2 left-0 right-0 z-50 bg-base-100 border border-white/15 rounded-2xl p-3 shadow-2xl space-y-2.5" + > +
+ onChangeStageSearch(e.target.value)} + autoFocus + /> + {stageSearchTerm && ( + + )} +
-
+
{paginatedStages.length > 0 ? ( - paginatedStages.map((stage) => ( -
{ - e.stopPropagation() - setIsChildClick(true) - - if (extraData?.theory_craft?.stage_id !== Number(stage.ID)) { - setExtraData({ - ...extraData, - theory_craft: { - stage_id: Number(stage.ID), - cycle_count: extraData?.theory_craft?.cycle_count ?? 1, - mode: extraData?.theory_craft?.mode ?? false, - hp: extraData?.theory_craft?.hp ?? {}, - custom_lineup: extraData?.theory_craft?.custom_lineup ?? [] - } - }) - } - setShowSearchStage(pre => !pre) - onChangeSearch("") - }} - > - {getLocaleName(locale, stage.Name)} -
- )) + paginatedStages.map((stg) => { + const isSelected = extraData?.theory_craft?.stage_id === Number(stg.ID) + return ( +
{ + if (extraData?.theory_craft?.stage_id !== Number(stg.ID)) { + setExtraData({ + ...extraData, + theory_craft: { + stage_id: Number(stg.ID), + cycle_count: extraData?.theory_craft?.cycle_count ?? 1, + mode: extraData?.theory_craft?.mode ?? false, + hp: extraData?.theory_craft?.hp ?? {}, + custom_lineup: extraData?.theory_craft?.custom_lineup ?? [] + } + }) + } + setShowSearchStage(false) + onChangeStageSearch("") + }} + > + {getLocaleName(locale, stg.Name)} + {isSelected && } +
+ ) + }) ) : (
{transI18n("noStageFound")}
)}
{paginatedStages.length > 0 && ( -
+
- Page {stagePage} + Page {stagePage} @@ -229,23 +266,47 @@ export default function ExtraSettingBar() {
{/* Custom Lineup */} -
-
- - {transI18n("customLineup")} +
+
+ + +
-
- {(extraData?.theory_craft?.custom_lineup || []).map((avatarId) => { - const avatarData = mapAvatar[avatarId]; - if (!avatarData) return null; + {/* Selected Avatars Strip */} +
+ {currentLineup.map((avatarId) => { + const avatarData = mapAvatar[avatarId] + if (!avatarData) return null return ( { - const newLineup = (extraData?.theory_craft?.custom_lineup || []).filter(id => id !== avatarId); + const newLineup = currentLineup.filter(id => id !== avatarId) setExtraData({ ...extraData, theory_craft: { @@ -255,51 +316,56 @@ export default function ExtraSettingBar() { hp: extraData?.theory_craft?.hp ?? {}, custom_lineup: newLineup } - }); + }) }} /> - ); + ) })} - + {!showSearchLineup && ( + + )}
+ {/* Inline Character Selection Pool */} {showSearchLineup && ( -
e.stopPropagation()} - className="mt-2 w-full z-50 bg-base-100 border border-base-content/15 rounded-2xl p-4 shadow-2xl space-y-3" - > -
- {transI18n("selectedCharacters")} - +
+
+ + setLineupSearchTerm(e.target.value)} + autoFocus + />
-
- {Object.values(mapAvatar).map((avatar) => { - const currentLineup = extraData?.theory_craft?.custom_lineup || []; - const isSelected = currentLineup.includes(avatar.ID.toString()); - +
+ {filteredAvatars.map((avatar) => { + const isSelected = currentLineup.includes(avatar.ID.toString()) return ( { - const idStr = avatar.ID.toString(); - let newLineup = [...currentLineup]; + const idStr = avatar.ID.toString() + let newLineup = [...currentLineup] if (isSelected) { - newLineup = newLineup.filter(id => id !== idStr); + newLineup = newLineup.filter(id => id !== idStr) } else { - newLineup.push(idStr); + newLineup.push(idStr) } setExtraData({ @@ -311,10 +377,10 @@ export default function ExtraSettingBar() { hp: extraData?.theory_craft?.hp ?? {}, custom_lineup: newLineup } - }); + }) }} /> - ); + ) })}
@@ -322,187 +388,237 @@ export default function ExtraSettingBar() {
)} -
+
)} - {/* MULTIPATH CHAR */} -
-
-
-

- {transI18n("multipathCharacter")} -

-
- + {/* MULTIPATH CHARACTER */} +
+
+
+
+ +
+
+
+

+ {transI18n("multipathCharacter")} +

+
+ +
+
+

+ {transI18n("detailMultipathCharacter")} +

- setIsEnableChangePath(e.target.checked)} - /> + +
+ + setIsEnableChangePath(e.target.checked)} + /> +
{isEnableChangePath && ( -
-
-
- - {transI18n("mainPath")} +
+
+ {/* Main Character Path */} +
+ + extraData?.multi_path?.multi_path_main?.includes(Number(it.ID))).map((it) => ({ + value: it.ID.toString(), + label: getNameChar(locale, transI18n, it), + imageUrl: `${process.env.CDN_URL}/${baseType?.[it.BaseType]?.Icon}` + }))} + excludeSet={[]} + selectedCustomSet={extraData?.multi_path?.main?.toString() || ""} + placeholder={transI18n("selectAMainStat")} + setSelectedCustomSet={(it) => { + if (!it) return + setExtraData({ + ...extraData, + multi_path: { + march_7: extraData?.multi_path?.march_7 || 1001, + main: Number(it) || 8001, + multi_path_main: extraData?.multi_path?.multi_path_main || [], + multi_path_march_7: extraData?.multi_path?.multi_path_march_7 || [] + }, + lua: extraData?.lua || null + }) + }} + />
- extraData?.multi_path?.multi_path_main?.includes(Number(it.ID))).map((it) => ({ - value: it.ID.toString(), - label: getNameChar(locale, transI18n, it), - imageUrl: `${process.env.CDN_URL}/${baseType?.[it.BaseType]?.Icon}` - }))} - excludeSet={[]} - selectedCustomSet={extraData?.multi_path?.main?.toString() || ""} - placeholder={transI18n("selectAMainStat")} - setSelectedCustomSet={(it) => { - if (!it) return - setExtraData({ - ...extraData, - multi_path: { - march_7: extraData?.multi_path?.march_7 || 1001, - main: Number(it) || 8001, - multi_path_main: extraData?.multi_path?.multi_path_main || [], - multi_path_march_7: extraData?.multi_path?.multi_path_march_7 || [] - }, - lua: extraData?.lua || null - }) - }} - /> -
-
-
- - {transI18n("march7Path")} + {/* March 7th Path */} +
+ + extraData?.multi_path?.multi_path_march_7?.includes(Number(it.ID))).map((it) => ({ + value: it.ID.toString(), + label: getNameChar(locale, transI18n, it), + imageUrl: `${process.env.CDN_URL}/${baseType?.[it.BaseType]?.Icon}` + }))} + excludeSet={[]} + selectedCustomSet={extraData?.multi_path?.march_7?.toString() || ""} + placeholder={transI18n("selectAMainStat")} + setSelectedCustomSet={(it) => { + if (!it) return + setExtraData({ + ...extraData, + multi_path: { + march_7: Number(it) || 1001, + main: extraData?.multi_path?.main || 8001, + multi_path_main: extraData?.multi_path?.multi_path_main || [], + multi_path_march_7: extraData?.multi_path?.multi_path_march_7 || [] + }, + lua: extraData?.lua || null + }) + }} + />
- extraData?.multi_path?.multi_path_march_7?.includes(Number(it.ID))).map((it) => ({ - value: it.ID.toString(), - label: getNameChar(locale, transI18n, it), - imageUrl: `${process.env.CDN_URL}/${baseType?.[it.BaseType]?.Icon}` - }))} - excludeSet={[]} - selectedCustomSet={extraData?.multi_path?.march_7?.toString() || ""} - placeholder={transI18n("selectAMainStat")} - setSelectedCustomSet={(it) => { - if (!it) return - setExtraData({ - ...extraData, - multi_path: { - march_7: Number(it) || 1001, - main: extraData?.multi_path?.main || 8001, - multi_path_main: extraData?.multi_path?.multi_path_main || [], - multi_path_march_7: extraData?.multi_path?.multi_path_march_7 || [] - }, - lua: extraData?.lua || null - }) - }} - />
)} -
+
- {/* CHALLENGE */} -
-
-

- {transI18n("challenge")} -

-
- -
-
-
-
- - {transI18n("anomalyArbitration")} -
-
- -
-
- + {/* CHALLENGE SETTINGS */} +
+
+
+
- -
-
-
- - {transI18n("skipNode")} -
-
- -
-
- +
+

+ {transI18n("challenge")} +

+

+ Configure anomaly peak mode and node skip settings +

-
+ +
+
+ {/* Anomaly Arbitration */} +
+
+ +
+ +
+
+ +
+ + {/* Skip Node */} +
+
+ +
+ +
+
+ +
+
+
+
{/* EXTRA FEATURES */} -
-
-

- {transI18n("extraFeatures")} -

+
+
+
+ +
+
+

+ {transI18n("extraFeatures")} +

+

+ UI display overrides and visual preferences +

+
-
+
+ {/* Hide UI Row */} {extraData?.setting?.hide_ui !== undefined && ( -
-
- {extraData?.setting?.hide_ui - ? - : - } - {transI18n("hideUI")} -
- +
+
+
+ {extraData?.setting?.hide_ui + ? + : + } +
+
+
+ {transI18n("hideUI")} +
+ +
+
+

+ {transI18n("detailHiddenUi")} +

@@ -525,13 +641,23 @@ export default function ExtraSettingBar() {
)} + {/* Disable Censorship Row */} {extraData?.setting?.censorship !== undefined && ( -
-
- - {transI18n("disableCensorship")} -
- +
+
+
+ +
+
+
+ {transI18n("disableCensorship")} +
+ +
+
+

+ {transI18n("detailDisableCensorship")} +

@@ -554,25 +680,60 @@ export default function ExtraSettingBar() {
)}
-
+
- {/* LUA EDITOR */} -
-
-
- -

Lua Scripting

+ {/* LUA SCRIPTING */} +
+
+
+
+ +
+
+

+ Lua Scripting +

+

+ Inject custom Lua runtime scripts and behaviors +

+
+
+ +
+ + setIsEnableLua(e.target.checked)} + />
- setIsEnableLua(e.target.checked)} - />
{isEnableLua && ( -
+
+ {/* Terminal Window Header Bar */} +
+
+
+
+
+
+
+
+
+ + script.lua +
+
+ + LUA 5.4 + +
+ + {/* Code Editor */} @@ -584,15 +745,15 @@ export default function ExtraSettingBar() { highlight={(code) => Prism.highlight(code, Prism.languages.lua, "lua")} padding={16} textareaClassName="outline-none font-mono" - className="text-xs font-mono min-h-60 bg-[#161822] text-white" + className="text-xs font-mono min-h-60 text-slate-100 bg-[#0d0e15]" style={{ - background: "#161822", + background: "#0d0e15", color: "#e2e8f0", }} />
)} -
+
) } diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx index bbcdc97..b9babab 100644 --- a/src/components/header/index.tsx +++ b/src/components/header/index.tsx @@ -636,7 +636,15 @@ export default function Header() { {/* Modals */} {modalConfigs?.map(({ id, title, onClose, content }) => ( -
+
{/* Modal Header */}