UPDATE: Responsive for mobile
All checks were successful
Gitea Auto Deploy / Deploy-Container (push) Successful in 1m54s
All checks were successful
Gitea Auto Deploy / Deploy-Container (push) Successful in 1m54s
This commit is contained in:
@@ -197,6 +197,7 @@
|
|||||||
"selectPFEvent": "Chọn sự kiện PF",
|
"selectPFEvent": "Chọn sự kiện PF",
|
||||||
"selectASEvent": "Chọn sự kiện AS",
|
"selectASEvent": "Chọn sự kiện AS",
|
||||||
"selectCEEvent": "Chọn sự kiện CE",
|
"selectCEEvent": "Chọn sự kiện CE",
|
||||||
|
"selectPEAKEvent": "Chọn sự kiện PEAK",
|
||||||
"selectEvent": "Chọn sự kiện",
|
"selectEvent": "Chọn sự kiện",
|
||||||
"selectFloor": "Chọn tầng",
|
"selectFloor": "Chọn tầng",
|
||||||
"selectSide": "Chọn nửa trận",
|
"selectSide": "Chọn nửa trận",
|
||||||
@@ -237,10 +238,9 @@
|
|||||||
"maxAllSuccess": "Đã thiết lập cấp độ kỹ năng tối đa thành công.",
|
"maxAllSuccess": "Đã thiết lập cấp độ kỹ năng tối đa thành công.",
|
||||||
"maxAllFailed": "Thiết lập cấp độ kỹ năng tối đa thất bại.",
|
"maxAllFailed": "Thiết lập cấp độ kỹ năng tối đa thất bại.",
|
||||||
"noRelicEquipped": "Không có di vật",
|
"noRelicEquipped": "Không có di vật",
|
||||||
"anomalyArbitration": "Phán Quyết Dị Thường",
|
"anomalyArbitration": "Trọng tài dị tướng",
|
||||||
"normalMode": "Chế độ thường",
|
"normalMode": "Chế độ thường",
|
||||||
"hardMode": "Chế độ khó",
|
"hardMode": "Chế độ khó",
|
||||||
"selectPEAKEvent": "Chọn sự kiện",
|
|
||||||
"mode": "Chế độ",
|
"mode": "Chế độ",
|
||||||
"selectMode": "Chọn chế độ",
|
"selectMode": "Chọn chế độ",
|
||||||
"rollBack": "Quay lại bước trước",
|
"rollBack": "Quay lại bước trước",
|
||||||
|
|||||||
BIN
public/icon/ChallengePeakIcon.webp
Normal file
BIN
public/icon/ChallengePeakIcon.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
@@ -146,7 +146,7 @@ export default function AsBar() {
|
|||||||
|
|
||||||
if (!ASEvent) return null
|
if (!ASEvent) return null
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto px-4 py-8 relative">
|
<div className="py-8 relative">
|
||||||
|
|
||||||
{/* Title Card */}
|
{/* Title Card */}
|
||||||
<div className="rounded-xl p-4 mb-2 border border-warning">
|
<div className="rounded-xl p-4 mb-2 border border-warning">
|
||||||
@@ -243,106 +243,109 @@ export default function AsBar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Enemy Waves */}
|
{/* Enemy Waves */}
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
{(as_config?.challenge_id ?? 0) !== 0 && (
|
||||||
{/* First Half */}
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
{/* First Half */}
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
|
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
|
||||||
|
|
||||||
{challengeSelected && challengeSelected?.EventIDList1?.length > 0 && challengeSelected?.EventIDList1[0].MonsterList.map((wave, waveIndex) => (
|
{challengeSelected && challengeSelected?.EventIDList1?.length > 0 && challengeSelected?.EventIDList1[0].MonsterList.map((wave, waveIndex) => (
|
||||||
<div key={waveIndex} className="mb-6">
|
<div key={waveIndex} className="mb-6">
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{Object.values(wave).map((waveValue, enemyIndex) => (
|
{Object.values(wave).map((waveValue, enemyIndex) => (
|
||||||
<div
|
<div
|
||||||
key={enemyIndex}
|
key={enemyIndex}
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
>
|
>
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
alt="Enemy Icon"
|
alt="Enemy Icon"
|
||||||
width={376}
|
width={376}
|
||||||
height={512}
|
height={512}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
{listMonster
|
{listMonster
|
||||||
.find((monster) => monster.child.includes(waveValue))
|
.find((monster) => monster.child.includes(waveValue))
|
||||||
?.weak?.map((icon, iconIndex) => (
|
?.weak?.map((icon, iconIndex) => (
|
||||||
<Image
|
<Image
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
alt={icon}
|
alt={icon}
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
key={iconIndex}
|
key={iconIndex}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Second Half */}
|
{/* Second Half */}
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
|
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
|
||||||
|
|
||||||
{challengeSelected && challengeSelected?.EventIDList2?.length > 0 && challengeSelected?.EventIDList2[0].MonsterList.map((wave, waveIndex) => (
|
{challengeSelected && challengeSelected?.EventIDList2?.length > 0 && challengeSelected?.EventIDList2[0].MonsterList.map((wave, waveIndex) => (
|
||||||
<div key={waveIndex} className="mb-6">
|
<div key={waveIndex} className="mb-6">
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{Object.values(wave).map((waveValue, enemyIndex) => (
|
{Object.values(wave).map((waveValue, enemyIndex) => (
|
||||||
<div
|
<div
|
||||||
key={enemyIndex}
|
key={enemyIndex}
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
alt="Enemy Icon"
|
alt="Enemy Icon"
|
||||||
width={376}
|
width={376}
|
||||||
height={512}
|
height={512}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
{listMonster
|
{listMonster
|
||||||
.find((monster) => monster.child.includes(waveValue))
|
.find((monster) => monster.child.includes(waveValue))
|
||||||
?.weak?.map((icon, iconIndex) => (
|
?.weak?.map((icon, iconIndex) => (
|
||||||
<Image
|
<Image
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
alt={icon}
|
alt={icon}
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
key={iconIndex}
|
key={iconIndex}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ export default function CeBar() {
|
|||||||
}, [stageSearchTerm])
|
}, [stageSearchTerm])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-6 z-4 h-full w-full" onClick={() => {
|
<div className="z-4 py-8 h-full w-full" onClick={() => {
|
||||||
|
|
||||||
setShowSearchWaveId(null)
|
setShowSearchWaveId(null)
|
||||||
setShowSearchStage(false)
|
setShowSearchStage(false)
|
||||||
@@ -217,7 +217,7 @@ export default function CeBar() {
|
|||||||
{ce_config.monsters.map((wave, waveIndex) => (
|
{ce_config.monsters.map((wave, waveIndex) => (
|
||||||
<div key={waveIndex} className="card border border-slate-700/50 ">
|
<div key={waveIndex} className="card border border-slate-700/50 ">
|
||||||
<div className="card-body p-6">
|
<div className="card-body p-6">
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center flex-wrap justify-between mb-4">
|
||||||
<h2 className="text-xl font-bold text-white">{transI18n("wave")} {waveIndex + 1}</h2>
|
<h2 className="text-xl font-bold text-white">{transI18n("wave")} {waveIndex + 1}</h2>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
@@ -286,7 +286,7 @@ export default function CeBar() {
|
|||||||
<div className="card border hover:border-slate-500 transition-colors w-full h-full">
|
<div className="card border hover:border-slate-500 transition-colors w-full h-full">
|
||||||
<div className="card-body p-4">
|
<div className="card-body p-4">
|
||||||
<button
|
<button
|
||||||
className="btn btn-xs btn-success absolute -top-2 right-5 opacity-50 group-hover:opacity-100 transition-opacity"
|
className="btn btn-xs btn-success absolute -top-2 right-12 opacity-50 group-hover:opacity-100 transition-opacity"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const newCeConfig = cloneDeep(ce_config)
|
const newCeConfig = cloneDeep(ce_config)
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ export default function CeBar() {
|
|||||||
<CopyPlus className="w-3 h-3" />
|
<CopyPlus className="w-3 h-3" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-xs btn-error absolute -top-2 -right-4 opacity-50 group-hover:opacity-100 transition-opacity"
|
className="btn btn-xs btn-error absolute -top-2 right-2 opacity-50 group-hover:opacity-100 transition-opacity"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const newCeConfig = cloneDeep(ce_config)
|
const newCeConfig = cloneDeep(ce_config)
|
||||||
newCeConfig.monsters[waveIndex].splice(memberIndex, 1)
|
newCeConfig.monsters[waveIndex].splice(memberIndex, 1)
|
||||||
|
|||||||
@@ -15,56 +15,64 @@ export default function MonsterBar() {
|
|||||||
{ name: transI18n("memoryOfChaos"), icon: 'AbyssIcon01', value: 'MOC' },
|
{ name: transI18n("memoryOfChaos"), icon: 'AbyssIcon01', value: 'MOC' },
|
||||||
{ name: transI18n("pureFiction"), icon: 'ChallengeStory', value: 'PF' },
|
{ name: transI18n("pureFiction"), icon: 'ChallengeStory', value: 'PF' },
|
||||||
{ name: transI18n("apocalypticShadow"), icon: 'ChallengeBoss', value: 'AS' },
|
{ name: transI18n("apocalypticShadow"), icon: 'ChallengeBoss', value: 'AS' },
|
||||||
{ name: transI18n("anomalyArbitration"), icon: 'AbyssIcon02', value: 'PEAK' },
|
{ name: transI18n("anomalyArbitration"), icon: 'ChallengePeakIcon', value: 'PEAK' },
|
||||||
{ name: transI18n("customEnemy"), icon: 'MonsterIcon', value: 'CE' },
|
{ name: transI18n("customEnemy"), icon: 'MonsterIcon', value: 'CE' },
|
||||||
{ name: transI18n("simulatedUniverse"), icon: 'SimulatedUniverse', value: 'SU' },
|
{ name: transI18n("simulatedUniverse"), icon: 'SimulatedUniverse', value: 'SU' },
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen">
|
<div className="min-h-screen">
|
||||||
{/* Header Navigation */}
|
{/* Header Navigation */}
|
||||||
<nav className="border-b border-warning/30 relative">
|
<nav className="border-b border-warning/30 relative pb-2">
|
||||||
<div className="container mx-auto px-4">
|
<div className="flex items-center justify-center">
|
||||||
<div className="flex items-center justify-center">
|
{/* Mobile Select */}
|
||||||
{/* Navigation Tabs */}
|
<div className="block md:hidden w-full">
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-1">
|
<select
|
||||||
|
className="select select-bordered w-full"
|
||||||
|
value={battle_type.toUpperCase()}
|
||||||
|
onChange={(e) => setBattleType(e.target.value.toUpperCase())}
|
||||||
|
>
|
||||||
{navItems.map((item) => (
|
{navItems.map((item) => (
|
||||||
<button
|
<option key={item.name} value={item.value.toUpperCase()}>
|
||||||
key={item.name}
|
{item.name}
|
||||||
onClick={() => setBattleType(item.value.toUpperCase())}
|
</option>
|
||||||
className={`px-4 py-2 rounded-lg transition-all cursor-pointer duration-300 flex items-center space-x-2 ${battle_type.toUpperCase() === item.value.toUpperCase()
|
|
||||||
? 'bg-success/30 shadow-lg'
|
|
||||||
: 'bg-base-200/20 hover:bg-base-200/40 '
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={
|
|
||||||
battle_type.toUpperCase() === item.value.toUpperCase()
|
|
||||||
? {
|
|
||||||
filter:
|
|
||||||
'brightness(0) saturate(100%) invert(63%) sepia(78%) saturate(643%) hue-rotate(1deg) brightness(93%) contrast(89%)',
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Image src={`/icon/${item.icon}.webp`} alt={item.name} width={24} height={24} />
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={
|
|
||||||
battle_type.toUpperCase() === item.value.toUpperCase()
|
|
||||||
? {
|
|
||||||
filter:
|
|
||||||
'brightness(0) saturate(100%) invert(63%) sepia(78%) saturate(643%) hue-rotate(1deg) brightness(93%) contrast(89%)',
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span className="font-medium">{item.name}</span>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Desktop Tabs */}
|
||||||
|
<div className="hidden md:grid grid-cols-3 lg:grid-cols-6 gap-1">
|
||||||
|
{navItems.map((item) => (
|
||||||
|
<button
|
||||||
|
key={item.name}
|
||||||
|
onClick={() => setBattleType(item.value.toUpperCase())}
|
||||||
|
className={`px-4 py-2 rounded-lg transition-all cursor-pointer duration-300 flex items-center space-x-2 ${battle_type.toUpperCase() === item.value.toUpperCase()
|
||||||
|
? 'bg-success/30 shadow-lg'
|
||||||
|
: 'bg-base-200/20 hover:bg-base-200/40 '
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
style={
|
||||||
|
battle_type.toUpperCase() === item.value.toUpperCase()
|
||||||
|
? {
|
||||||
|
filter:
|
||||||
|
'brightness(0) saturate(100%) invert(63%) sepia(78%) saturate(643%) hue-rotate(1deg) brightness(93%) contrast(89%)',
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={`/icon/${item.icon}.webp`}
|
||||||
|
alt={item.name}
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>{item.name}</span>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -81,7 +89,7 @@ export default function MonsterBar() {
|
|||||||
{battle_type.toUpperCase() === 'PEAK' && <PeakBar />}
|
{battle_type.toUpperCase() === 'PEAK' && <PeakBar />}
|
||||||
{battle_type.toUpperCase() === 'SU' && (
|
{battle_type.toUpperCase() === 'SU' && (
|
||||||
<div className="container mx-auto px-4 py-8 text-center font-bold text-3xl">
|
<div className="container mx-auto px-4 py-8 text-center font-bold text-3xl">
|
||||||
{transI18n("comingSoon")}
|
{transI18n("comingSoon")}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export default function MocBar() {
|
|||||||
])
|
])
|
||||||
if (!MOCEvent) return null
|
if (!MOCEvent) return null
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto px-4 py-8 relative">
|
<div className="py-8 relative">
|
||||||
|
|
||||||
{/* Title Card */}
|
{/* Title Card */}
|
||||||
<div className="rounded-xl p-4 mb-2 border border-warning">
|
<div className="rounded-xl p-4 mb-2 border border-warning">
|
||||||
@@ -223,106 +223,109 @@ export default function MocBar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Enemy Waves */}
|
{/* Enemy Waves */}
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
{(moc_config?.challenge_id ?? 0) !== 0 && (
|
||||||
{/* First Half */}
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
{/* First Half */}
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
|
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
|
||||||
|
|
||||||
{challengeSelected && challengeSelected?.EventIDList1?.length > 0 && challengeSelected?.EventIDList1[0].MonsterList.map((wave, waveIndex) => (
|
{challengeSelected && challengeSelected?.EventIDList1?.length > 0 && challengeSelected?.EventIDList1[0].MonsterList.map((wave, waveIndex) => (
|
||||||
<div key={waveIndex} className="mb-6">
|
<div key={waveIndex} className="mb-6">
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{Object.values(wave).map((waveValue, enemyIndex) => (
|
{Object.values(wave).map((waveValue, enemyIndex) => (
|
||||||
<div
|
<div
|
||||||
key={enemyIndex}
|
key={enemyIndex}
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
>
|
>
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
alt="Enemy Icon"
|
alt="Enemy Icon"
|
||||||
width={376}
|
width={376}
|
||||||
height={512}
|
height={512}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
{listMonster
|
{listMonster
|
||||||
.find((monster) => monster.child.includes(waveValue))
|
.find((monster) => monster.child.includes(waveValue))
|
||||||
?.weak?.map((icon, iconIndex) => (
|
?.weak?.map((icon, iconIndex) => (
|
||||||
<Image
|
<Image
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
alt={icon}
|
alt={icon}
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
key={iconIndex}
|
key={iconIndex}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Second Half */}
|
{/* Second Half */}
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
|
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
|
||||||
|
|
||||||
{challengeSelected && challengeSelected?.EventIDList2?.length > 0 && challengeSelected?.EventIDList2[0].MonsterList.map((wave, waveIndex) => (
|
{challengeSelected && challengeSelected?.EventIDList2?.length > 0 && challengeSelected?.EventIDList2[0].MonsterList.map((wave, waveIndex) => (
|
||||||
<div key={waveIndex} className="mb-6">
|
<div key={waveIndex} className="mb-6">
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{Object.values(wave).map((waveValue, enemyIndex) => (
|
{Object.values(wave).map((waveValue, enemyIndex) => (
|
||||||
<div
|
<div
|
||||||
key={enemyIndex}
|
key={enemyIndex}
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
{listMonster.find((monster) => monster.child.includes(waveValue))?.icon && <Image
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(waveValue))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
alt="Enemy Icon"
|
alt="Enemy Icon"
|
||||||
width={376}
|
width={376}
|
||||||
height={512}
|
height={512}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
{listMonster
|
{listMonster
|
||||||
.find((monster) => monster.child.includes(waveValue))
|
.find((monster) => monster.child.includes(waveValue))
|
||||||
?.weak?.map((icon, iconIndex) => (
|
?.weak?.map((icon, iconIndex) => (
|
||||||
<Image
|
<Image
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
alt={icon}
|
alt={icon}
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
key={iconIndex}
|
key={iconIndex}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -55,53 +55,53 @@ export default function PeakBar() {
|
|||||||
}, [peak_config, listFloor, mapPEAKInfo, bossConfig])
|
}, [peak_config, listFloor, mapPEAKInfo, bossConfig])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!challengeSelected) return
|
if (!challengeSelected) return
|
||||||
if (peak_config.event_id !== 0 && peak_config.challenge_id !== 0 && challengeSelected) {
|
if (peak_config.event_id !== 0 && peak_config.challenge_id !== 0 && challengeSelected) {
|
||||||
const newBattleConfig = cloneDeep(peak_config)
|
const newBattleConfig = cloneDeep(peak_config)
|
||||||
newBattleConfig.cycle_count = 6
|
newBattleConfig.cycle_count = 6
|
||||||
newBattleConfig.blessings = []
|
newBattleConfig.blessings = []
|
||||||
for (const value of challengeSelected.TagList) {
|
for (const value of challengeSelected.TagList) {
|
||||||
newBattleConfig.blessings.push({
|
newBattleConfig.blessings.push({
|
||||||
id: Number(value.Id),
|
id: Number(value.Id),
|
||||||
level: 1
|
level: 1
|
||||||
})
|
})
|
||||||
}
|
|
||||||
if (peak_config.buff_id !== 0) {
|
|
||||||
newBattleConfig.blessings.push({
|
|
||||||
id: peak_config.buff_id,
|
|
||||||
level: 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
newBattleConfig.monsters = []
|
|
||||||
newBattleConfig.stage_id = challengeSelected.EventIDList[0].StageID
|
|
||||||
for (const wave of challengeSelected.EventIDList[0].MonsterList) {
|
|
||||||
if (!wave) continue
|
|
||||||
const newWave: MonsterStore[] = []
|
|
||||||
for (const value of Object.values(wave)) {
|
|
||||||
if (!value) continue
|
|
||||||
newWave.push({
|
|
||||||
monster_id: Number(value),
|
|
||||||
level: challengeSelected.EventIDList[0].Level,
|
|
||||||
amount: 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
newBattleConfig.monsters.push(newWave)
|
|
||||||
}
|
|
||||||
|
|
||||||
setPeakConfig(newBattleConfig)
|
|
||||||
}
|
}
|
||||||
|
if (peak_config.buff_id !== 0) {
|
||||||
|
newBattleConfig.blessings.push({
|
||||||
|
id: peak_config.buff_id,
|
||||||
|
level: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
newBattleConfig.monsters = []
|
||||||
|
newBattleConfig.stage_id = challengeSelected.EventIDList[0].StageID
|
||||||
|
for (const wave of challengeSelected.EventIDList[0].MonsterList) {
|
||||||
|
if (!wave) continue
|
||||||
|
const newWave: MonsterStore[] = []
|
||||||
|
for (const value of Object.values(wave)) {
|
||||||
|
if (!value) continue
|
||||||
|
newWave.push({
|
||||||
|
monster_id: Number(value),
|
||||||
|
level: challengeSelected.EventIDList[0].Level,
|
||||||
|
amount: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
newBattleConfig.monsters.push(newWave)
|
||||||
|
}
|
||||||
|
|
||||||
|
setPeakConfig(newBattleConfig)
|
||||||
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [
|
}, [
|
||||||
peak_config.event_id,
|
peak_config.event_id,
|
||||||
peak_config.challenge_id,
|
peak_config.challenge_id,
|
||||||
peak_config.buff_id,
|
peak_config.buff_id,
|
||||||
mapPEAKInfo,
|
mapPEAKInfo,
|
||||||
])
|
])
|
||||||
|
|
||||||
if (!PEAKEvent) return null
|
if (!PEAKEvent) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto px-4 py-8 relative">
|
<div className="py-8 relative">
|
||||||
|
|
||||||
{/* Title Card */}
|
{/* Title Card */}
|
||||||
<div className="rounded-xl p-4 mb-2 border border-warning">
|
<div className="rounded-xl p-4 mb-2 border border-warning">
|
||||||
@@ -113,7 +113,7 @@ export default function PeakBar() {
|
|||||||
}))}
|
}))}
|
||||||
excludeSet={[]}
|
excludeSet={[]}
|
||||||
selectedCustomSet={peak_config.event_id.toString()}
|
selectedCustomSet={peak_config.event_id.toString()}
|
||||||
placeholder={transI18n("selectASEvent")}
|
placeholder={transI18n("selectPEAKEvent")}
|
||||||
setSelectedCustomSet={(id) => setPeakConfig({ ...peak_config, event_id: Number(id), challenge_id: 0, buff_id: 0 })}
|
setSelectedCustomSet={(id) => setPeakConfig({ ...peak_config, event_id: Number(id), challenge_id: 0, buff_id: 0 })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -216,57 +216,61 @@ export default function PeakBar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Enemy Waves */}
|
{/* Enemy Waves */}
|
||||||
<div className="grid grid-cols-1 gap-4">
|
|
||||||
|
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
{(peak_config?.challenge_id ?? 0) !== 0 && (
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{challengeSelected?.Name}</h2>
|
<div className="grid grid-cols-1 gap-4">
|
||||||
|
|
||||||
{challengeSelected && Object.values(challengeSelected.InfiniteList).map((waveValue, waveIndex) => (
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
<div key={waveIndex} className="mb-6">
|
<h2 className="text-2xl font-bold mb-6 text-info">{challengeSelected?.Name}</h2>
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
||||||
{Array.from(new Set(waveValue.MonsterGroupIDList)).map((monsterId, enemyIndex) => (
|
|
||||||
<div
|
|
||||||
key={enemyIndex}
|
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
|
||||||
>
|
|
||||||
|
|
||||||
<div className="flex items-center space-x-3">
|
{challengeSelected && Object.values(challengeSelected.InfiniteList).map((waveValue, waveIndex) => (
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
<div key={waveIndex} className="mb-6">
|
||||||
{listMonster.find((monster) => monster.child.includes(monsterId))?.icon && <Image
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(monsterId))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
alt="Enemy Icon"
|
{Array.from(new Set(waveValue.MonsterGroupIDList)).map((monsterId, enemyIndex) => (
|
||||||
width={376}
|
<div
|
||||||
height={512}
|
key={enemyIndex}
|
||||||
className="w-full h-full object-cover"
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
/>}
|
>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList[0].Level}</div>
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
{listMonster.find((monster) => monster.child.includes(monsterId))?.icon && <Image
|
||||||
{listMonster
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(monsterId))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
.find((monster) => monster.child.includes(monsterId))
|
alt="Enemy Icon"
|
||||||
?.weak?.map((icon, iconIndex) => (
|
width={376}
|
||||||
<Image
|
height={512}
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
className="w-full h-full object-cover"
|
||||||
alt={icon}
|
/>}
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
</div>
|
||||||
width={200}
|
|
||||||
height={200}
|
<div className="flex flex-col">
|
||||||
key={iconIndex}
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList[0].Level}</div>
|
||||||
/>
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
))}
|
{listMonster
|
||||||
|
.find((monster) => monster.child.includes(monsterId))
|
||||||
|
?.weak?.map((icon, iconIndex) => (
|
||||||
|
<Image
|
||||||
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
|
alt={icon}
|
||||||
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
|
width={200}
|
||||||
|
height={200}
|
||||||
|
key={iconIndex}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ export default function PfBar() {
|
|||||||
if (!PFEvent) return null
|
if (!PFEvent) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto px-4 py-8 relative">
|
<div className="py-8 relative">
|
||||||
|
|
||||||
{/* Title Card */}
|
{/* Title Card */}
|
||||||
<div className="rounded-xl p-4 mb-2 border border-warning">
|
<div className="rounded-xl p-4 mb-2 border border-warning">
|
||||||
@@ -138,7 +138,8 @@ export default function PfBar() {
|
|||||||
...pf_config,
|
...pf_config,
|
||||||
event_id: Number(id),
|
event_id: Number(id),
|
||||||
challenge_id: mapPFInfo[Number(id)]?.Level.slice(-1)[0]?.Id || 0,
|
challenge_id: mapPFInfo[Number(id)]?.Level.slice(-1)[0]?.Id || 0,
|
||||||
buff_id: 0 })}
|
buff_id: 0
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* Settings */}
|
{/* Settings */}
|
||||||
@@ -229,107 +230,111 @@ export default function PfBar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Enemy Waves */}
|
{/* Enemy Waves */}
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
||||||
{/* First Half */}
|
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
|
|
||||||
|
|
||||||
{challengeSelected && Object.values(challengeSelected.InfiniteList1).map((waveValue, waveIndex) => (
|
{(pf_config?.challenge_id ?? 0) !== 0 && (
|
||||||
<div key={waveIndex} className="mb-6">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
{/* First Half */}
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
{Array.from(new Set(waveValue.MonsterGroupIDList)).map((monsterId, enemyIndex) => (
|
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("firstHalfEnemies")}</h2>
|
||||||
|
|
||||||
<div
|
{challengeSelected && Object.values(challengeSelected.InfiniteList1).map((waveValue, waveIndex) => (
|
||||||
key={enemyIndex}
|
<div key={waveIndex} className="mb-6">
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
>
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
<div className="flex items-center space-x-3">
|
{Array.from(new Set(waveValue.MonsterGroupIDList)).map((monsterId, enemyIndex) => (
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
|
||||||
{listMonster.find((monster) => monster.child.includes(monsterId))?.icon && <Image
|
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(monsterId))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
|
||||||
alt="Enemy Icon"
|
|
||||||
width={376}
|
|
||||||
height={512}
|
|
||||||
className="w-full h-full object-cover"
|
|
||||||
/>}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
key={enemyIndex}
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
{listMonster
|
>
|
||||||
.find((monster) => monster.child.includes(monsterId))
|
<div className="flex items-center space-x-3">
|
||||||
?.weak?.map((icon, iconIndex) => (
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
<Image
|
{listMonster.find((monster) => monster.child.includes(monsterId))?.icon && <Image
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(monsterId))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
alt={icon}
|
alt="Enemy Icon"
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
width={376}
|
||||||
width={200}
|
height={512}
|
||||||
height={200}
|
className="w-full h-full object-cover"
|
||||||
key={iconIndex}
|
/>}
|
||||||
/>
|
</div>
|
||||||
))}
|
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
||||||
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
|
{listMonster
|
||||||
|
.find((monster) => monster.child.includes(monsterId))
|
||||||
|
?.weak?.map((icon, iconIndex) => (
|
||||||
|
<Image
|
||||||
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
|
alt={icon}
|
||||||
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
|
width={200}
|
||||||
|
height={200}
|
||||||
|
key={iconIndex}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Second Half */}
|
{/* Second Half */}
|
||||||
<div className="rounded-xl p-4 mt-2 border border-warning">
|
<div className="rounded-xl p-4 mt-2 border border-warning">
|
||||||
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
|
<h2 className="text-2xl font-bold mb-6 text-info">{transI18n("secondHalfEnemies")}</h2>
|
||||||
|
|
||||||
{challengeSelected && Object.values(challengeSelected?.InfiniteList2).map((waveValue, waveIndex) => (
|
{challengeSelected && Object.values(challengeSelected?.InfiniteList2).map((waveValue, waveIndex) => (
|
||||||
<div key={waveIndex} className="mb-6">
|
<div key={waveIndex} className="mb-6">
|
||||||
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
<h3 className="text-lg font-semibold mb-t">{transI18n("wave")} {waveIndex + 1}</h3>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{Array.from(new Set(waveValue.MonsterGroupIDList)).map((monsterId, enemyIndex) => (
|
{Array.from(new Set(waveValue.MonsterGroupIDList)).map((monsterId, enemyIndex) => (
|
||||||
<div
|
<div
|
||||||
key={enemyIndex}
|
key={enemyIndex}
|
||||||
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
className="rounded-xl p-2 border border-white/10 shadow-md hover:border-white/20 hover:shadow-lg transition"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
<div className="relative w-20 h-20 rounded-full overflow-hidden flex-shrink-0 border border-white/10 shadow-sm">
|
||||||
{listMonster.find((monster) => monster.child.includes(monsterId))?.icon && <Image
|
{listMonster.find((monster) => monster.child.includes(monsterId))?.icon && <Image
|
||||||
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(monsterId))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
src={`https://api.hakush.in/hsr/UI/monstermiddleicon/${listMonster.find((monster) => monster.child.includes(monsterId))?.icon?.split("/")?.pop()?.replace(".png", "")}.webp`}
|
||||||
alt="Enemy Icon"
|
alt="Enemy Icon"
|
||||||
width={376}
|
width={376}
|
||||||
height={512}
|
height={512}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
<div className="text-sm font-semibold">Lv. {challengeSelected?.EventIDList1[0].Level}</div>
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
{listMonster
|
{listMonster
|
||||||
.find((monster) => monster.child.includes(monsterId))
|
.find((monster) => monster.child.includes(monsterId))
|
||||||
?.weak?.map((icon, iconIndex) => (
|
?.weak?.map((icon, iconIndex) => (
|
||||||
<Image
|
<Image
|
||||||
src={`/icon/${icon.toLowerCase()}.webp`}
|
src={`/icon/${icon.toLowerCase()}.webp`}
|
||||||
alt={icon}
|
alt={icon}
|
||||||
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
className="h-[28px] w-[28px] 2xl:h-[40px] 2xl:w-[40px] object-contain rounded-md border border-white/20 shadow-sm"
|
||||||
width={200}
|
width={200}
|
||||||
height={200}
|
height={200}
|
||||||
key={iconIndex}
|
key={iconIndex}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -174,6 +174,7 @@ export default function RelicsInfo() {
|
|||||||
} else {
|
} else {
|
||||||
setSelectedRelicSlot(item)
|
setSelectedRelicSlot(item)
|
||||||
}
|
}
|
||||||
|
handlerChangeRelic(item)
|
||||||
}}
|
}}
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -189,9 +189,10 @@ export default function SkillsInfo() {
|
|||||||
setSkillSelected(btn.id === skillSelected ? null : btn.id)
|
setSkillSelected(btn.id === skillSelected ? null : btn.id)
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
left: `calc(${btn.left} - var(--size-${btn.size}) / 2)`,
|
left: btn.left,
|
||||||
top: `calc(${btn.top} - var(--size-${btn.size}) / 2)`,
|
top: btn.top,
|
||||||
}}
|
transform: "translate(-50%, -50%)",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={getImageSkill(avatarInfo?.SkillTrees?.[btn.id]?.["1"]?.Icon, avatarSkillTree?.[btn.id]?.["1"]?.StatusAddList[0]) || ""}
|
src={getImageSkill(avatarInfo?.SkillTrees?.[btn.id]?.["1"]?.Icon, avatarSkillTree?.[btn.id]?.["1"]?.StatusAddList[0]) || ""}
|
||||||
|
|||||||
Reference in New Issue
Block a user