refactor: enhance event handling and layout in monsterBar components; add QuickViewRelic component
Gitea Auto Deploy / Deploy-Container (push) Successful in 37s
Gitea Auto Deploy / Deploy-Container (push) Successful in 37s
This commit is contained in:
+1
-1
@@ -77,7 +77,7 @@ export default async function RootLayout({
|
|||||||
<div className="min-h-screen w-full flex flex-col justify-between bg-ambient-mesh selection:bg-primary/20 selection:text-primary">
|
<div className="min-h-screen w-full flex flex-col justify-between bg-ambient-mesh selection:bg-primary/20 selection:text-primary">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="grid grid-cols-12 w-full flex-1">
|
<main className="grid grid-cols-12 w-full flex-1">
|
||||||
<aside className="hidden sm:block sm:col-span-4 md:col-span-4 lg:col-span-3 sticky top-16 self-start h-[calc(100vh-4rem)] overflow-hidden border-r border-base-content/10 bg-base-100/30 backdrop-blur-sm">
|
<aside className="hidden sm:block sm:col-span-4 md:col-span-4 lg:col-span-3 sticky top-14 self-start h-[calc(100vh-3.5rem)] overflow-hidden border-r border-base-content/10 bg-base-100/30 backdrop-blur-sm">
|
||||||
<AvatarBar />
|
<AvatarBar />
|
||||||
</aside>
|
</aside>
|
||||||
<section className="col-span-12 sm:col-span-8 md:col-span-8 lg:col-span-9 flex flex-col min-w-0">
|
<section className="col-span-12 sm:col-span-8 md:col-span-8 lg:col-span-9 flex flex-col min-w-0">
|
||||||
|
|||||||
@@ -113,15 +113,34 @@ export default function AsBar() {
|
|||||||
newBattleConfig.monsters = []
|
newBattleConfig.monsters = []
|
||||||
newBattleConfig.stage_id = 0
|
newBattleConfig.stage_id = 0
|
||||||
|
|
||||||
|
let currentSide = as_config.floor_side;
|
||||||
|
if (currentSide === "first_half" || currentSide === "firstHalf" || !currentSide) currentSide = "firstNode";
|
||||||
|
if (currentSide === "second_half" || currentSide === "secondHalf") currentSide = "secondNode";
|
||||||
|
|
||||||
let targetEventList: ASEvent[] = []
|
let targetEventList: ASEvent[] = []
|
||||||
if (as_config.floor_side === "firstNode" && challengeSelected.EventList1.length > 0) {
|
if (currentSide === "firstNode" && challengeSelected.EventList1?.length > 0) {
|
||||||
targetEventList = challengeSelected.EventList1
|
targetEventList = challengeSelected.EventList1
|
||||||
} else if (as_config.floor_side === "secondNode" && challengeSelected.EventList2.length > 0) {
|
} else if (currentSide === "secondNode" && challengeSelected.EventList2?.length > 0) {
|
||||||
targetEventList = challengeSelected.EventList2
|
targetEventList = challengeSelected.EventList2
|
||||||
} else if (as_config.floor_side === "thirdNode" && eventSelected?.Tierce && eventSelected.Tierce.EventList.length > 0) {
|
} else if (currentSide === "thirdNode" && eventSelected?.Tierce && eventSelected.Tierce.EventList?.length > 0) {
|
||||||
targetEventList = eventSelected.Tierce.EventList
|
targetEventList = eventSelected.Tierce.EventList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback to first available node if currentSide is invalid or has no events
|
||||||
|
if (targetEventList.length === 0) {
|
||||||
|
if (challengeSelected.EventList1?.length) {
|
||||||
|
targetEventList = challengeSelected.EventList1;
|
||||||
|
currentSide = "firstNode";
|
||||||
|
} else if (challengeSelected.EventList2?.length) {
|
||||||
|
targetEventList = challengeSelected.EventList2;
|
||||||
|
currentSide = "secondNode";
|
||||||
|
} else if (eventSelected?.Tierce?.EventList?.length) {
|
||||||
|
targetEventList = eventSelected.Tierce.EventList;
|
||||||
|
currentSide = "thirdNode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newBattleConfig.floor_side = currentSide;
|
||||||
|
|
||||||
if (targetEventList.length > 0) {
|
if (targetEventList.length > 0) {
|
||||||
newBattleConfig.stage_id = targetEventList[0].ID
|
newBattleConfig.stage_id = targetEventList[0].ID
|
||||||
if (targetEventList[0].Invasion) {
|
if (targetEventList[0].Invasion) {
|
||||||
@@ -176,6 +195,7 @@ export default function AsBar() {
|
|||||||
...as_config,
|
...as_config,
|
||||||
event_id: Number(id),
|
event_id: Number(id),
|
||||||
challenge_id: mapAS[Number(id)]?.Level.at(-1)?.ID || 0,
|
challenge_id: mapAS[Number(id)]?.Level.at(-1)?.ID || 0,
|
||||||
|
floor_side: "firstNode",
|
||||||
buff_id: 0
|
buff_id: 0
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -91,15 +91,34 @@ export default function MocBar() {
|
|||||||
newBattleConfig.monsters = []
|
newBattleConfig.monsters = []
|
||||||
newBattleConfig.stage_id = 0
|
newBattleConfig.stage_id = 0
|
||||||
|
|
||||||
|
let currentSide = moc_config.floor_side;
|
||||||
|
if (currentSide === "first_half" || currentSide === "firstHalf" || !currentSide) currentSide = "firstNode";
|
||||||
|
if (currentSide === "second_half" || currentSide === "secondHalf") currentSide = "secondNode";
|
||||||
|
|
||||||
let targetEventList: MoCEvent[] = []
|
let targetEventList: MoCEvent[] = []
|
||||||
if (moc_config.floor_side === "firstNode" && challengeSelected.EventList1.length > 0) {
|
if (currentSide === "firstNode" && challengeSelected.EventList1?.length > 0) {
|
||||||
targetEventList = challengeSelected.EventList1
|
targetEventList = challengeSelected.EventList1
|
||||||
} else if (moc_config.floor_side === "secondNode" && challengeSelected.EventList2.length > 0) {
|
} else if (currentSide === "secondNode" && challengeSelected.EventList2?.length > 0) {
|
||||||
targetEventList = challengeSelected.EventList2
|
targetEventList = challengeSelected.EventList2
|
||||||
} else if (moc_config.floor_side === "thirdNode" && eventSelected?.Tierce && eventSelected.Tierce.EventList.length > 0) {
|
} else if (currentSide === "thirdNode" && eventSelected?.Tierce && eventSelected.Tierce.EventList?.length > 0) {
|
||||||
targetEventList = eventSelected.Tierce.EventList
|
targetEventList = eventSelected.Tierce.EventList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback to first available node if currentSide is invalid or has no events
|
||||||
|
if (targetEventList.length === 0) {
|
||||||
|
if (challengeSelected.EventList1?.length) {
|
||||||
|
targetEventList = challengeSelected.EventList1;
|
||||||
|
currentSide = "firstNode";
|
||||||
|
} else if (challengeSelected.EventList2?.length) {
|
||||||
|
targetEventList = challengeSelected.EventList2;
|
||||||
|
currentSide = "secondNode";
|
||||||
|
} else if (eventSelected?.Tierce?.EventList?.length) {
|
||||||
|
targetEventList = eventSelected.Tierce.EventList;
|
||||||
|
currentSide = "thirdNode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newBattleConfig.floor_side = currentSide;
|
||||||
|
|
||||||
if (targetEventList.length > 0) {
|
if (targetEventList.length > 0) {
|
||||||
newBattleConfig.stage_id = targetEventList[0].ID
|
newBattleConfig.stage_id = targetEventList[0].ID
|
||||||
|
|
||||||
@@ -157,6 +176,7 @@ export default function MocBar() {
|
|||||||
...moc_config,
|
...moc_config,
|
||||||
event_id: Number(id),
|
event_id: Number(id),
|
||||||
challenge_id: mapMoc[Number(id)]?.Level.at(-1)?.ID || 0,
|
challenge_id: mapMoc[Number(id)]?.Level.at(-1)?.ID || 0,
|
||||||
|
floor_side: "firstNode",
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -141,14 +141,16 @@ export default function PeakBar() {
|
|||||||
excludeSet={[]}
|
excludeSet={[]}
|
||||||
selectedCustomSet={peak_config.event_id.toString()}
|
selectedCustomSet={peak_config.event_id.toString()}
|
||||||
placeholder={transI18n("selectPEAKEvent")}
|
placeholder={transI18n("selectPEAKEvent")}
|
||||||
setSelectedCustomSet={(id) =>
|
setSelectedCustomSet={(id) => {
|
||||||
|
const peakEvent = mapPeak?.[id];
|
||||||
|
const defaultFloor = peakEvent ? [...(peakEvent.PreLevel || []), peakEvent.BossLevel].filter(Boolean)[0]?.ID || 0 : 0;
|
||||||
setPeakConfig({
|
setPeakConfig({
|
||||||
...peak_config,
|
...peak_config,
|
||||||
event_id: Number(id),
|
event_id: Number(id),
|
||||||
challenge_id: 0,
|
challenge_id: defaultFloor,
|
||||||
buff_id: 0,
|
buff_id: 0,
|
||||||
})
|
});
|
||||||
}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* Settings */}
|
{/* Settings */}
|
||||||
|
|||||||
@@ -94,15 +94,34 @@ export default function PfBar() {
|
|||||||
newBattleConfig.monsters = []
|
newBattleConfig.monsters = []
|
||||||
newBattleConfig.stage_id = 0
|
newBattleConfig.stage_id = 0
|
||||||
|
|
||||||
|
let currentSide = pf_config.floor_side;
|
||||||
|
if (currentSide === "first_half" || currentSide === "firstHalf" || !currentSide) currentSide = "firstNode";
|
||||||
|
if (currentSide === "second_half" || currentSide === "secondHalf") currentSide = "secondNode";
|
||||||
|
|
||||||
let targetEventList: PFEvent[] = []
|
let targetEventList: PFEvent[] = []
|
||||||
if (pf_config.floor_side === "firstNode" && challengeSelected.EventList1.length > 0) {
|
if (currentSide === "firstNode" && challengeSelected.EventList1?.length > 0) {
|
||||||
targetEventList = challengeSelected.EventList1
|
targetEventList = challengeSelected.EventList1
|
||||||
} else if (pf_config.floor_side === "secondNode" && challengeSelected.EventList2.length > 0) {
|
} else if (currentSide === "secondNode" && challengeSelected.EventList2?.length > 0) {
|
||||||
targetEventList = challengeSelected.EventList2
|
targetEventList = challengeSelected.EventList2
|
||||||
} else if (pf_config.floor_side === "thirdNode" && eventSelected?.Tierce && eventSelected.Tierce.EventList.length > 0) {
|
} else if (currentSide === "thirdNode" && eventSelected?.Tierce && eventSelected.Tierce.EventList?.length > 0) {
|
||||||
targetEventList = eventSelected.Tierce.EventList
|
targetEventList = eventSelected.Tierce.EventList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback to first available node if currentSide is invalid or has no events
|
||||||
|
if (targetEventList.length === 0) {
|
||||||
|
if (challengeSelected.EventList1?.length) {
|
||||||
|
targetEventList = challengeSelected.EventList1;
|
||||||
|
currentSide = "firstNode";
|
||||||
|
} else if (challengeSelected.EventList2?.length) {
|
||||||
|
targetEventList = challengeSelected.EventList2;
|
||||||
|
currentSide = "secondNode";
|
||||||
|
} else if (eventSelected?.Tierce?.EventList?.length) {
|
||||||
|
targetEventList = eventSelected.Tierce.EventList;
|
||||||
|
currentSide = "thirdNode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newBattleConfig.floor_side = currentSide;
|
||||||
|
|
||||||
if (targetEventList.length > 0) {
|
if (targetEventList.length > 0) {
|
||||||
newBattleConfig.stage_id = targetEventList[0].ID
|
newBattleConfig.stage_id = targetEventList[0].ID
|
||||||
|
|
||||||
@@ -158,6 +177,7 @@ export default function PfBar() {
|
|||||||
...pf_config,
|
...pf_config,
|
||||||
event_id: Number(id),
|
event_id: Number(id),
|
||||||
challenge_id: mapPF[Number(id)]?.Level.slice(-1)[0]?.ID || 0,
|
challenge_id: mapPF[Number(id)]?.Level.slice(-1)[0]?.ID || 0,
|
||||||
|
floor_side: "firstNode",
|
||||||
buff_id: 0
|
buff_id: 0
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useTranslations } from "next-intl";
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { calcAffixBonus, calcBaseStatRaw, calcBonusStatRaw, calcMainAffixBonus, calcMainAffixBonusRaw, calcPromotion, calcSubAffixBonusRaw, getLocaleName, replaceByParam } from "@/helper";
|
import { calcAffixBonus, calcBaseStatRaw, calcBonusStatRaw, calcMainAffixBonus, calcMainAffixBonusRaw, calcPromotion, calcSubAffixBonusRaw, getLocaleName, replaceByParam } from "@/helper";
|
||||||
import { mappingStats } from "@/constant/constant";
|
import { mappingStats } from "@/constant/constant";
|
||||||
import RelicShowcase from "../showcaseCard/relicShowcase";
|
import QuickViewRelic from "./quickViewRelic";
|
||||||
import useLocaleStore from "@/stores/localeStore";
|
import useLocaleStore from "@/stores/localeStore";
|
||||||
import useDetailDataStore from "@/stores/detailDataStore";
|
import useDetailDataStore from "@/stores/detailDataStore";
|
||||||
import useCurrentDataStore from "@/stores/currentDataStore";
|
import useCurrentDataStore from "@/stores/currentDataStore";
|
||||||
@@ -491,7 +491,7 @@ export default function QuickView() {
|
|||||||
{relicStats?.map((relic, index) => {
|
{relicStats?.map((relic, index) => {
|
||||||
if (!relic || !avatarSelected) return null
|
if (!relic || !avatarSelected) return null
|
||||||
return (
|
return (
|
||||||
<RelicShowcase key={index} relic={relic} avatarInfo={avatarSelected} />
|
<QuickViewRelic key={index} relic={relic} avatarInfo={avatarSelected} />
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
"use client"
|
||||||
|
import NextImage from "next/image"
|
||||||
|
import { AvatarDetail, RelicShowcaseType } from "@/types";
|
||||||
|
|
||||||
|
export default function QuickViewRelic({
|
||||||
|
relic,
|
||||||
|
avatarInfo,
|
||||||
|
}: {
|
||||||
|
relic: RelicShowcaseType;
|
||||||
|
avatarInfo: AvatarDetail;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-3 py-2 px-1 border-b border-base-content/10 last:border-b-0">
|
||||||
|
{/* Relic Figure Icon */}
|
||||||
|
<div className="relative shrink-0 flex flex-col items-center">
|
||||||
|
<NextImage
|
||||||
|
src={relic?.img || ""}
|
||||||
|
unoptimized
|
||||||
|
crossOrigin="anonymous"
|
||||||
|
width={48}
|
||||||
|
height={48}
|
||||||
|
alt="Relic"
|
||||||
|
className="h-12 w-12 object-contain"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Main Affix - Clean Display */}
|
||||||
|
<div className="flex w-20 shrink-0 flex-col items-start justify-center">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
{relic?.mainAffix?.detail?.icon ? (
|
||||||
|
<NextImage
|
||||||
|
src={`${process.env.CDN_URL}/${relic.mainAffix.detail.icon}`}
|
||||||
|
unoptimized
|
||||||
|
crossOrigin="anonymous"
|
||||||
|
width={16}
|
||||||
|
height={16}
|
||||||
|
alt="Main Affix"
|
||||||
|
className="h-4 w-4 theme-stat-icon shrink-0 object-contain"
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
<span className="text-xs font-bold text-amber-600 dark:text-amber-400 font-mono">
|
||||||
|
{relic?.mainAffix?.valueAffix + (relic?.mainAffix?.detail?.unit || "")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-[10px] font-mono text-base-content/50 ml-0.5">
|
||||||
|
+{relic?.mainAffix?.level}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sub Affixes Grid - Clean Flat Typography */}
|
||||||
|
<div className="grid flex-1 grid-cols-2 gap-x-3 gap-y-1">
|
||||||
|
{relic?.subAffix?.map((subAffix, index) => {
|
||||||
|
if (!subAffix) return null
|
||||||
|
const isOptimalStat = avatarInfo?.Relics?.SubAffixPropertyList?.includes(subAffix?.property)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`flex items-center justify-between py-0.5 min-w-0 ${
|
||||||
|
isOptimalStat
|
||||||
|
? "text-amber-600 dark:text-amber-400 font-semibold"
|
||||||
|
: "text-base-content/75"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-1 min-w-0 flex-1">
|
||||||
|
{subAffix?.detail?.icon ? (
|
||||||
|
<NextImage
|
||||||
|
src={`${process.env.CDN_URL}/${subAffix.detail.icon}`}
|
||||||
|
unoptimized
|
||||||
|
crossOrigin="anonymous"
|
||||||
|
width={14}
|
||||||
|
height={14}
|
||||||
|
alt="Sub Affix"
|
||||||
|
className="h-3.5 w-3.5 theme-stat-icon shrink-0 object-contain"
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
<span className="text-xs font-mono truncate">
|
||||||
|
+{subAffix?.valueAffix + (subAffix?.detail?.unit || "")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isOptimalStat && subAffix?.count ? (
|
||||||
|
<span className="ml-1 text-[10px] font-bold text-amber-600/80 dark:text-amber-400/80 shrink-0 font-mono">
|
||||||
|
({subAffix?.count})
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -718,7 +718,7 @@ export default function ShowCaseInfo() {
|
|||||||
|
|
||||||
const sizeClass = isBigMemory ? "w-12 h-12 mx-1" : isBig ? "w-12 h-12 mx-1" : isMedium ? "w-10 h-10" : "w-8 h-8";
|
const sizeClass = isBigMemory ? "w-12 h-12 mx-1" : isBig ? "w-12 h-12 mx-1" : isMedium ? "w-10 h-10" : "w-8 h-8";
|
||||||
|
|
||||||
const imageSize = isBigMemory ? "w-10" : isBig ? "w-10" : isMedium ? "w-8" : "w-6";
|
const imageSize = isBigMemory ? "w-10 h-10" : isBig ? "w-10 h-10" : isMedium ? "w-8 h-8" : "w-6 h-6";
|
||||||
|
|
||||||
const bgColor = isBigMemory
|
const bgColor = isBigMemory
|
||||||
? "bg-[#2a1a39]/80"
|
? "bg-[#2a1a39]/80"
|
||||||
@@ -741,7 +741,7 @@ export default function ShowCaseInfo() {
|
|||||||
<div key={`item-${idx}`} className="relative flex flex-row items-center">
|
<div key={`item-${idx}`} className="relative flex flex-row items-center">
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
`relative flex items-center justify-center ${sizeClass}
|
`relative flex items-center justify-center shrink-0 ${sizeClass}
|
||||||
rounded-full ${bgColor} border-2 border-gray-500
|
rounded-full ${bgColor} border-2 border-gray-500
|
||||||
${avatarData.data.skills[avatarSkillTree?.[btn.id]?.["1"]?.PointID] ? "" : "opacity-50"}
|
${avatarData.data.skills[avatarSkillTree?.[btn.id]?.["1"]?.PointID] ? "" : "opacity-50"}
|
||||||
`}
|
`}
|
||||||
@@ -753,7 +753,7 @@ export default function ShowCaseInfo() {
|
|||||||
alt={btn.id}
|
alt={btn.id}
|
||||||
width={125}
|
width={125}
|
||||||
height={125}
|
height={125}
|
||||||
className={`h-full ${imageSize} ${filterClass}`}
|
className={`${imageSize} object-contain ${filterClass}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{(isBig || isBigMemory) && (
|
{(isBig || isBigMemory) && (
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import NextImage from "next/image"
|
import NextImage from "next/image"
|
||||||
import { AvatarDetail, RelicShowcaseType } from "@/types";
|
import { AvatarDetail, RelicShowcaseType } from "@/types";
|
||||||
|
|
||||||
@@ -11,80 +11,91 @@ export default function RelicShowcase({
|
|||||||
avatarInfo: AvatarDetail;
|
avatarInfo: AvatarDetail;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-3 py-2 px-1 border-b border-base-content/10 last:border-b-0">
|
<div
|
||||||
{/* Relic Figure Icon */}
|
className="relative w-full flex flex-row items-center rounded-s-lg border-l-2 p-1 border-yellow-600/60 bg-linear-to-r from-yellow-600/20 to-transparent"
|
||||||
<div className="relative shrink-0 flex flex-col items-center">
|
>
|
||||||
|
{/* Subtle glow overlay */}
|
||||||
|
<div className="absolute inset-0 rounded-s-lg pointer-events-none"></div>
|
||||||
|
|
||||||
|
<div className="flex relative">
|
||||||
|
<div className="absolute inset-0 rounded-lg blur-lg -z-10"></div>
|
||||||
<NextImage
|
<NextImage
|
||||||
src={relic?.img || ""}
|
src={relic?.img || ""}
|
||||||
unoptimized
|
unoptimized
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
width={48}
|
width={78}
|
||||||
height={48}
|
height={78}
|
||||||
alt="Relic"
|
alt="Relic Icon"
|
||||||
className="h-12 w-12 object-contain"
|
className="h-19.5 w-19.5 rounded-lg"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="absolute text-yellow-400 font-bold z-10 drop-shadow-[0_0_6px_rgba(251,191,36,0.8)]"
|
||||||
|
style={{
|
||||||
|
left: '0.65rem',
|
||||||
|
bottom: '-0.45rem',
|
||||||
|
fontSize: '1.05rem',
|
||||||
|
letterSpacing: '-0.1em',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
✦✦✦✦✦
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main Affix - Clean Display */}
|
<div className="flex w-1/6 flex-col items-center justify-center">
|
||||||
<div className="flex w-20 shrink-0 flex-col items-start justify-center">
|
<div className="relative">
|
||||||
<div className="flex items-center gap-1">
|
<div className="absolute inset-0 bg-yellow-500/15 rounded-full blur-md -z-10"></div>
|
||||||
{relic?.mainAffix?.detail?.icon ? (
|
|
||||||
<NextImage
|
<NextImage
|
||||||
src={`${process.env.CDN_URL}/${relic.mainAffix.detail.icon}`}
|
src={`${process.env.CDN_URL}/${relic?.mainAffix?.detail?.icon}` || ""}
|
||||||
unoptimized
|
unoptimized
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
width={16}
|
width={35}
|
||||||
height={16}
|
height={35}
|
||||||
alt="Main Affix"
|
alt="Main Affix Icon"
|
||||||
className="h-4 w-4 theme-stat-icon shrink-0 object-contain"
|
className="h-8.75 w-8.75"
|
||||||
/>
|
/>
|
||||||
) : null}
|
</div>
|
||||||
<span className="text-xs font-bold text-amber-600 dark:text-amber-400 font-mono">
|
<span className="text-base text-yellow-400 font-semibold drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]">
|
||||||
{relic?.mainAffix?.valueAffix + (relic?.mainAffix?.detail?.unit || "")}
|
{relic?.mainAffix?.valueAffix + (relic?.mainAffix?.detail?.unit || "")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
<span className="bg-black/20 backdrop-blur-sm rounded px-1.5 py-0.5 text-xs border border-white/10">
|
||||||
<span className="text-[10px] font-mono text-base-content/50 ml-0.5">
|
|
||||||
+{relic?.mainAffix?.level}
|
+{relic?.mainAffix?.level}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Sub Affixes Grid - Clean Flat Typography */}
|
<div style={{ opacity: 0.3, height: '78px', borderLeftWidth: '1px' }}></div>
|
||||||
<div className="grid flex-1 grid-cols-2 gap-x-3 gap-y-1">
|
|
||||||
|
<div className="grid w-[65%] m-2 grid-cols-2 gap-1">
|
||||||
{relic?.subAffix?.map((subAffix, index) => {
|
{relic?.subAffix?.map((subAffix, index) => {
|
||||||
if (!subAffix) return null
|
if (!subAffix) return null
|
||||||
const isOptimalStat = avatarInfo?.Relics?.SubAffixPropertyList?.includes(subAffix?.property)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={index} className="flex flex-col">
|
||||||
key={index}
|
<div className="relative flex flex-row items-center bg-black/20 backdrop-blur-sm rounded-md p-1 border border-white/5 min-w-0">
|
||||||
className={`flex items-center justify-between py-0.5 min-w-0 ${
|
|
||||||
isOptimalStat
|
|
||||||
? "text-amber-600 dark:text-amber-400 font-semibold"
|
|
||||||
: "text-base-content/75"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-1 min-w-0 flex-1">
|
|
||||||
{subAffix?.detail?.icon ? (
|
{subAffix?.detail?.icon ? (
|
||||||
<NextImage
|
<NextImage
|
||||||
src={`${process.env.CDN_URL}/${subAffix.detail.icon}`}
|
src={`${process.env.CDN_URL}/${subAffix?.detail?.icon}` || ""}
|
||||||
unoptimized
|
unoptimized
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
width={14}
|
width={32}
|
||||||
height={14}
|
height={32}
|
||||||
alt="Sub Affix"
|
alt="Sub Affix Icon"
|
||||||
className="h-3.5 w-3.5 theme-stat-icon shrink-0 object-contain"
|
className="h-6 w-6 shrink-0"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : (
|
||||||
<span className="text-xs font-mono truncate">
|
<div className="h-6 w-6 bg-black/60 rounded flex items-center justify-center border border-white/10 shrink-0">
|
||||||
|
<span className="text-xs text-white/50">?</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<span className="text-xs text-gray-200 ml-0.5 truncate flex-1 min-w-0">
|
||||||
+{subAffix?.valueAffix + (subAffix?.detail?.unit || "")}
|
+{subAffix?.valueAffix + (subAffix?.detail?.unit || "")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
{
|
||||||
|
(avatarInfo?.Relics?.SubAffixPropertyList?.findIndex((item) => item === subAffix?.property) !== -1) && (
|
||||||
{isOptimalStat && subAffix?.count ? (
|
<span className="ml-1 bg-yellow-600/20 text-yellow-400 rounded-full px-1 py-0.5 text-[10px] font-semibold border border-yellow-600/30 shrink-0 leading-none">
|
||||||
<span className="ml-1 text-[10px] font-bold text-amber-600/80 dark:text-amber-400/80 shrink-0 font-mono">
|
{subAffix?.count}
|
||||||
({subAffix?.count})
|
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user