feat: enhance layout and styling across components for improved responsiveness and user experience
Gitea Auto Deploy / Deploy-Container (push) Successful in 35s
Gitea Auto Deploy / Deploy-Container (push) Successful in 35s
This commit is contained in:
+7
-4
@@ -11,10 +11,13 @@
|
|||||||
nocompatible: true;
|
nocompatible: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
html, body {
|
||||||
--size-big: 4vw;
|
height: 100%;
|
||||||
--size-medium: 3vw;
|
height: 100dvh;
|
||||||
--size-small: 2vw;
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
overscroll-behavior: none;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth Modern Ultra-Sleek Scrollbars */
|
/* Smooth Modern Ultra-Sleek Scrollbars */
|
||||||
|
|||||||
+4
-4
@@ -64,9 +64,9 @@ export default async function RootLayout({
|
|||||||
const locale = await getLocale()
|
const locale = await getLocale()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={locale} suppressHydrationWarning className="h-full overflow-hidden">
|
<html lang={locale} suppressHydrationWarning className="h-full w-full overflow-hidden overscroll-none fixed inset-0">
|
||||||
<body
|
<body
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased h-full overflow-hidden max-w-full`}
|
className={`${geistSans.variable} ${geistMono.variable} antialiased h-full w-full overflow-hidden overscroll-none fixed inset-0 max-w-full`}
|
||||||
suppressHydrationWarning
|
suppressHydrationWarning
|
||||||
>
|
>
|
||||||
<NextIntlClientProvider messages={messages}>
|
<NextIntlClientProvider messages={messages}>
|
||||||
@@ -74,7 +74,7 @@ export default async function RootLayout({
|
|||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<ClientThemeWrapper>
|
<ClientThemeWrapper>
|
||||||
<ClientDataFetcher >
|
<ClientDataFetcher >
|
||||||
<div className="h-screen w-full flex flex-col overflow-hidden bg-ambient-mesh selection:bg-primary/20 selection:text-primary">
|
<div className="h-dvh w-full flex flex-col overflow-hidden bg-ambient-mesh selection:bg-primary/20 selection:text-primary">
|
||||||
<Header />
|
<Header />
|
||||||
<main className="grid grid-cols-12 w-full flex-1 min-h-0 overflow-hidden">
|
<main className="grid grid-cols-12 w-full flex-1 min-h-0 overflow-hidden">
|
||||||
<aside className="hidden sm:block sm:col-span-4 md:col-span-4 lg:col-span-3 h-full 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 h-full overflow-hidden border-r border-base-content/10 bg-base-100/30 backdrop-blur-sm">
|
||||||
@@ -84,7 +84,7 @@ export default async function RootLayout({
|
|||||||
<div className="shrink-0">
|
<div className="shrink-0">
|
||||||
<ActionBar />
|
<ActionBar />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 overflow-y-auto min-h-0 p-2 sm:p-3 sm:pt-1 flex flex-col justify-between">
|
<div className="flex-1 overflow-y-auto min-h-0 px-3 sm:px-4 pt-1 pb-3 flex flex-col justify-between">
|
||||||
<div>
|
<div>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -122,8 +122,18 @@ export default function ActionBar() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const actionMove = (path: string) => {
|
const actionMove = (path: string) => {
|
||||||
router.push(`/${path}`)
|
if (typeof document !== "undefined" && document.activeElement instanceof HTMLElement) {
|
||||||
}
|
document.activeElement.blur();
|
||||||
|
}
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
const scrollContainer = document.querySelector('section > div.flex-1.overflow-y-auto');
|
||||||
|
if (scrollContainer) {
|
||||||
|
scrollContainer.scrollTo({ top: 0, behavior: 'instant' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
router.push(`/${path}`, { scroll: false });
|
||||||
|
};
|
||||||
|
|
||||||
const handleProfileSelect = (profileId: number) => {
|
const handleProfileSelect = (profileId: number) => {
|
||||||
if (!avatarSelected || !avatars[avatarSelected.ID]) return;
|
if (!avatarSelected || !avatars[avatarSelected.ID]) return;
|
||||||
@@ -267,7 +277,7 @@ export default function ActionBar() {
|
|||||||
const currentActivePath = pathname?.replace(/^\//, '') || "";
|
const currentActivePath = pathname?.replace(/^\//, '') || "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full bg-transparent px-3 sm:px-4 py-2 space-y-2">
|
<div className="w-full bg-transparent px-3 sm:px-4 pt-2.5 sm:pt-3 pb-1 space-y-2">
|
||||||
{/* Top Row: Character Identity + Profile Selector + Connect PS */}
|
{/* Top Row: Character Identity + Profile Selector + Connect PS */}
|
||||||
<div className="flex flex-wrap items-center justify-between gap-2.5">
|
<div className="flex flex-wrap items-center justify-between gap-2.5">
|
||||||
{/* Character Identity */}
|
{/* Character Identity */}
|
||||||
@@ -436,9 +446,9 @@ export default function ActionBar() {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div className="dropdown dropdown-end w-full">
|
<div className="dropdown dropdown-end w-full">
|
||||||
<label tabIndex={0} className="btn btn-info btn-sm w-full font-bold shadow-xs">
|
<div tabIndex={0} role="button" className="btn btn-info btn-sm w-full font-bold shadow-xs">
|
||||||
{transI18n("actions")}
|
{transI18n("actions")}
|
||||||
</label>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
className="dropdown-content z-50 menu p-2 shadow-2xl bg-base-100 rounded-2xl w-56 mt-2 border border-base-300 space-y-1"
|
className="dropdown-content z-50 menu p-2 shadow-2xl bg-base-100 rounded-2xl w-56 mt-2 border border-base-300 space-y-1"
|
||||||
@@ -554,7 +564,7 @@ export default function ActionBar() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleConfirmDeleteProfile}
|
onClick={handleConfirmDeleteProfile}
|
||||||
className="flex-1 h-10 px-4 rounded-xl font-bold text-xs sm:text-sm bg-gradient-to-r from-rose-500 to-red-600 hover:from-rose-400 hover:to-red-500 text-white shadow-md shadow-rose-500/25 hover:shadow-rose-500/40 transition-all flex items-center justify-center gap-1.5 cursor-pointer"
|
className="flex-1 h-10 px-4 rounded-xl font-bold text-xs sm:text-sm bg-linear-to-r from-rose-500 to-red-600 hover:from-rose-400 hover:to-red-500 text-white shadow-md shadow-rose-500/25 hover:shadow-rose-500/40 transition-all flex items-center justify-center gap-1.5 cursor-pointer"
|
||||||
>
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-4 h-4" />
|
||||||
<span>{transI18n("confirmDelete")}</span>
|
<span>{transI18n("confirmDelete")}</span>
|
||||||
|
|||||||
@@ -456,7 +456,7 @@ export default function AvatarInfo() {
|
|||||||
<dialog id="action_detail_modal" className="modal">
|
<dialog id="action_detail_modal" className="modal">
|
||||||
<div className="modal-box w-11/12 max-w-[92vw] sm:max-w-[88vw] max-h-[90vh] flex flex-col bg-base-100 text-base-content border border-white/10 shadow-2xl rounded-2xl p-0 overflow-hidden">
|
<div className="modal-box w-11/12 max-w-[92vw] sm:max-w-[88vw] max-h-[90vh] flex flex-col bg-base-100 text-base-content border border-white/10 shadow-2xl rounded-2xl p-0 overflow-hidden">
|
||||||
<div className="sticky top-0 z-20 flex items-center justify-between px-6 py-4 border-b border-base-content/10 bg-base-100 shrink-0">
|
<div className="sticky top-0 z-20 flex items-center justify-between px-6 py-4 border-b border-base-content/10 bg-base-100 shrink-0">
|
||||||
<h3 className="font-bold text-xl tracking-tight bg-clip-text text-transparent bg-linear-to-r from-primary via-accent to-secondary">
|
<h3 className="font-bold text-xl tracking-tight text-base-content">
|
||||||
{transI18n("lightconeEquipment")}
|
{transI18n("lightconeEquipment")}
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function LightconeCard({ data }: LightconeCardProps) {
|
|||||||
const is4Star = data.Rarity === "CombatPowerLightconeRarity4";
|
const is4Star = data.Rarity === "CombatPowerLightconeRarity4";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="group relative flex flex-col items-center rounded-xl overflow-hidden bg-base-100 border border-base-content/10 shadow-sm hover:shadow-md cursor-pointer select-none h-full">
|
<li className="group relative flex flex-col items-center rounded-xl overflow-hidden bg-base-100 border border-base-content/10 shadow-xs hover:shadow-md hover:border-primary/50 transition-all duration-200 cursor-pointer select-none w-full list-none">
|
||||||
{/* Artwork container with vibrant rarity background */}
|
{/* Artwork container with vibrant rarity background */}
|
||||||
<div
|
<div
|
||||||
className={`w-full relative aspect-3/4 flex items-center justify-center overflow-hidden bg-linear-to-b ${
|
className={`w-full relative aspect-3/4 flex items-center justify-center overflow-hidden bg-linear-to-b ${
|
||||||
@@ -42,12 +42,12 @@ export default function LightconeCard({ data }: LightconeCardProps) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Name Label - Uniform Fixed-Height Footer */}
|
{/* Name Label - Uniform Fixed-Height Footer with larger text */}
|
||||||
<div className="w-full h-11 px-1 py-0.5 text-center flex items-center justify-center bg-base-100">
|
<div className="w-full min-h-12 px-1.5 py-1 text-center flex items-center justify-center bg-base-100 shrink-0">
|
||||||
<ParseText
|
<ParseText
|
||||||
locale={locale}
|
locale={locale}
|
||||||
text={text}
|
text={text}
|
||||||
className="font-bold text-xs leading-tight line-clamp-2 text-base-content group-hover:text-primary transition-colors text-center"
|
className="font-bold text-xs sm:text-[13px] leading-snug line-clamp-2 text-base-content group-hover:text-primary transition-colors text-center"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const getRarityColor = (rarity: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const slotIconMap: Record<string, { icon: string; key: string }> = {
|
export const slotIconMap: Record<string, { icon: string; key: string }> = {
|
||||||
'1': { icon: '/relics/HEAD.png', key: 'HEAD' },
|
'1': { icon: '/relics/HEAD.png', key: 'HEAD' },
|
||||||
'2': { icon: '/relics/HAND.png', key: 'HAND' },
|
'2': { icon: '/relics/HAND.png', key: 'HAND' },
|
||||||
'3': { icon: '/relics/BODY.png', key: 'BODY' },
|
'3': { icon: '/relics/BODY.png', key: 'BODY' },
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export default function Header() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-40 w-full bg-base-100 border-b border-base-300 shadow-xs">
|
<header className="sticky top-0 z-40 w-full shrink-0 bg-base-100 border-b border-base-300 shadow-xs">
|
||||||
<div className="navbar max-w-[1920px] mx-auto px-2 sm:px-4 py-1.5 min-h-14">
|
<div className="navbar max-w-[1920px] mx-auto px-2 sm:px-4 py-1.5 min-h-14">
|
||||||
<div className="navbar-start gap-2">
|
<div className="navbar-start gap-2">
|
||||||
{/* Mobile menu dropdown */}
|
{/* Mobile menu dropdown */}
|
||||||
@@ -638,7 +638,7 @@ export default function Header() {
|
|||||||
<dialog key={id} id={id} className="modal">
|
<dialog key={id} id={id} className="modal">
|
||||||
<div className={`modal-box w-11/12 ${
|
<div className={`modal-box w-11/12 ${
|
||||||
id === 'monster_modal' || id === 'import_modal' || id === 'extra_modal'
|
id === 'monster_modal' || id === 'import_modal' || id === 'extra_modal'
|
||||||
? 'max-w-[95vw] sm:max-w-[90vw] lg:max-w-[85vw] 2xl:max-w-[1500px] h-[88vh]'
|
? 'max-w-[95vw] sm:max-w-[90vw] lg:max-w-[85vw] 2xl:max-w-375 h-[88vh]'
|
||||||
: id === 'connect_modal'
|
: id === 'connect_modal'
|
||||||
? 'max-w-[95vw] sm:max-w-2xl md:max-w-3xl lg:max-w-4xl max-h-[88vh]'
|
? 'max-w-[95vw] sm:max-w-2xl md:max-w-3xl lg:max-w-4xl max-h-[88vh]'
|
||||||
: id === 'changelog_modal'
|
: id === 'changelog_modal'
|
||||||
|
|||||||
@@ -170,12 +170,12 @@ export default function LightconeBar() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Results Grid */}
|
{/* Results Grid - Compact multi-column layout */}
|
||||||
<div className="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-7 gap-3 auto-rows-fr max-h-[58vh] overflow-y-auto pr-1">
|
<div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-7 2xl:grid-cols-8 gap-2.5 sm:gap-3 pr-1">
|
||||||
{listLightcone.map((item) => (
|
{listLightcone.map((item) => (
|
||||||
<div
|
<div
|
||||||
key={item.ID}
|
key={item.ID}
|
||||||
className="h-full flex flex-col"
|
className="flex flex-col"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (avatarSelected) {
|
if (avatarSelected) {
|
||||||
const avatar = avatars[avatarSelected.ID.toString()]
|
const avatar = avatars[avatarSelected.ID.toString()]
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import useDetailDataStore from "@/stores/detailDataStore";
|
|||||||
import { getLocaleName } from '@/helper';
|
import { getLocaleName } from '@/helper';
|
||||||
import useLocaleStore from "@/stores/localeStore";
|
import useLocaleStore from "@/stores/localeStore";
|
||||||
import { useShallow } from 'zustand/react/shallow';
|
import { useShallow } from 'zustand/react/shallow';
|
||||||
import { Trash2 } from "lucide-react";
|
import { Trash2, SlidersHorizontal } from "lucide-react";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
export default function RelicsInfo() {
|
export default function RelicsInfo() {
|
||||||
@@ -249,6 +249,15 @@ export default function RelicsInfo() {
|
|||||||
return () => window.removeEventListener('keydown', handleEscKey);
|
return () => window.removeEventListener('keydown', handleEscKey);
|
||||||
}, [isOpenRelic]);
|
}, [isOpenRelic]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!selectedRelicSlot) {
|
||||||
|
setSelectedRelicSlot("1");
|
||||||
|
}
|
||||||
|
}, [selectedRelicSlot, setSelectedRelicSlot]);
|
||||||
|
|
||||||
|
const selectedRelic = selectedRelicSlot ? getRelic(selectedRelicSlot) : null;
|
||||||
|
const isSelectedRelicEquipped = Boolean(selectedRelic);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full space-y-4">
|
<div className="w-full space-y-4">
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6">
|
||||||
@@ -274,7 +283,7 @@ export default function RelicsInfo() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 6-Slot Grid completely free of box-in-box */}
|
{/* 6-Slot Grid */}
|
||||||
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3 sm:gap-4">
|
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3 sm:gap-4">
|
||||||
{["1", "2", "3", "4", "5", "6"].map((item, index) => (
|
{["1", "2", "3", "4", "5", "6"].map((item, index) => (
|
||||||
<div
|
<div
|
||||||
@@ -291,34 +300,30 @@ export default function RelicsInfo() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Micro Actions */}
|
{/* Micro Actions */}
|
||||||
<div className="absolute top-0 right-0 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex gap-1">
|
<div className="absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-all duration-200 flex gap-1 z-20">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation();
|
||||||
handlerChangeRelic(item)
|
handlerChangeRelic(item);
|
||||||
}}
|
}}
|
||||||
className="btn btn-xs btn-circle btn-primary shadow-xs"
|
className="w-6 h-6 rounded-lg bg-primary text-primary-content shadow-xs hover:scale-110 active:scale-95 transition-all flex items-center justify-center border border-white/20 cursor-pointer"
|
||||||
title={transI18n("changeRelic")}
|
title={transI18n("changeRelic")}
|
||||||
>
|
>
|
||||||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<SlidersHorizontal className="w-3 h-3 stroke-[2.2]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536M4 20h4l10.293-10.293a1 1 0 000-1.414l-2.586-2.586a1 1 0 00-1.414 0L4 16v4z" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{getRelic(item) && (
|
{getRelic(item) && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation();
|
||||||
requestDeleteRelic(item)
|
requestDeleteRelic(item);
|
||||||
}}
|
}}
|
||||||
className="btn btn-xs btn-circle btn-error shadow-xs"
|
className="w-6 h-6 rounded-lg bg-rose-500 text-white shadow-xs hover:scale-110 active:scale-95 transition-all flex items-center justify-center border border-white/20 cursor-pointer"
|
||||||
title={transI18n("deleteRelic")}
|
title={transI18n("deleteRelic")}
|
||||||
>
|
>
|
||||||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<Trash2 className="w-3 h-3 stroke-[2.2]" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6M9 7V4h6v3m5 0H4" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -332,22 +337,25 @@ export default function RelicsInfo() {
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={!selectedRelicSlot}
|
disabled={!selectedRelicSlot}
|
||||||
onClick={() => handlerChangeRelic(selectedRelicSlot)}
|
onClick={() => handlerChangeRelic(selectedRelicSlot)}
|
||||||
className="btn btn-primary btn-sm rounded-xl font-bold shadow-xs"
|
className="btn btn-primary btn-sm rounded-xl font-bold gap-2 shadow-xs transition-all active:scale-[0.98] cursor-pointer"
|
||||||
>
|
>
|
||||||
{transI18n("changeRelic")}
|
<SlidersHorizontal className="w-4 h-4" />
|
||||||
|
<span>{transI18n("changeRelic")}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!selectedRelicSlot || !getRelic(selectedRelicSlot)}
|
disabled={!selectedRelicSlot || !isSelectedRelicEquipped}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation();
|
||||||
if (selectedRelicSlot) {
|
if (selectedRelicSlot) {
|
||||||
requestDeleteRelic(selectedRelicSlot)
|
requestDeleteRelic(selectedRelicSlot);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="btn btn-ghost btn-sm text-error hover:bg-error/20 rounded-xl disabled:opacity-40 disabled:pointer-events-none"
|
className="btn btn-outline btn-error hover:btn-error btn-sm rounded-xl font-bold gap-2 transition-all active:scale-[0.98] cursor-pointer disabled:opacity-40 disabled:pointer-events-none"
|
||||||
>
|
>
|
||||||
{transI18n("deleteRelic")}
|
<Trash2 className="w-4 h-4" />
|
||||||
|
<span>{transI18n("deleteRelic")}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -513,7 +521,7 @@ export default function RelicsInfo() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleConfirmDelete}
|
onClick={handleConfirmDelete}
|
||||||
className="flex-1 h-10 px-4 rounded-xl font-bold text-xs sm:text-sm bg-gradient-to-r from-rose-500 to-red-600 hover:from-rose-400 hover:to-red-500 text-white shadow-md shadow-rose-500/25 hover:shadow-rose-500/40 transition-all flex items-center justify-center gap-1.5 cursor-pointer"
|
className="flex-1 h-10 px-4 rounded-xl font-bold text-xs sm:text-sm bg-linear-to-r from-rose-500 to-red-600 hover:from-rose-400 hover:to-red-500 text-white shadow-md shadow-rose-500/25 hover:shadow-rose-500/40 transition-all flex items-center justify-center gap-1.5 cursor-pointer"
|
||||||
>
|
>
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-4 h-4" />
|
||||||
<span>{transI18n("confirmDelete")}</span>
|
<span>{transI18n("confirmDelete")}</span>
|
||||||
|
|||||||
@@ -702,9 +702,9 @@ export default function ShowCaseInfo() {
|
|||||||
<div className="bg-base-100 rounded-2xl p-4 sm:p-6 border border-base-300 shadow-sm space-y-6">
|
<div className="bg-base-100 rounded-2xl p-4 sm:p-6 border border-base-300 shadow-sm space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-between pb-3 border-b border-base-content/10 flex-wrap gap-3">
|
<div className="flex items-center justify-between pb-3 border-b border-base-content/10 flex-wrap gap-3">
|
||||||
<h2 className="text-xl sm:text-2xl font-extrabold flex items-center gap-2.5">
|
<h2 className="text-lg sm:text-xl font-bold flex items-center gap-2.5">
|
||||||
<div className="w-2 h-6 bg-linear-to-b from-primary to-accent rounded-full"></div>
|
<div className="w-1.5 h-5 bg-linear-to-b from-primary to-accent rounded-full"></div>
|
||||||
<span className="bg-clip-text text-transparent bg-linear-to-r from-primary to-accent">
|
<span className="bg-clip-text text-transparent bg-linear-to-r from-primary to-accent font-bold tracking-tight">
|
||||||
{transI18n("showcaseCard")}
|
{transI18n("showcaseCard")}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export default function SkillsInfo() {
|
|||||||
{/* Visual Skill Tree Container */}
|
{/* Visual Skill Tree Container */}
|
||||||
<div className="flex justify-center items-center py-2">
|
<div className="flex justify-center items-center py-2">
|
||||||
{traceButtons && avatarSelected && (
|
{traceButtons && avatarSelected && (
|
||||||
<div className="relative w-full max-w-md aspect-square">
|
<div className="relative w-full max-w-155 aspect-square select-none">
|
||||||
<Image
|
<Image
|
||||||
unoptimized
|
unoptimized
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
@@ -164,7 +164,7 @@ export default function SkillsInfo() {
|
|||||||
style={{
|
style={{
|
||||||
filter: (theme === "winter" || theme === "cupcake") ? "invert(1)" : "none"
|
filter: (theme === "winter" || theme === "cupcake") ? "invert(1)" : "none"
|
||||||
}}
|
}}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-contain pointer-events-none"
|
||||||
/>
|
/>
|
||||||
{traceButtons.map((btn, index) => {
|
{traceButtons.map((btn, index) => {
|
||||||
if (!avatarSelected?.SkillTrees?.[btn.id]) {
|
if (!avatarSelected?.SkillTrees?.[btn.id]) {
|
||||||
@@ -181,12 +181,12 @@ export default function SkillsInfo() {
|
|||||||
id={btn.id}
|
id={btn.id}
|
||||||
className={`
|
className={`
|
||||||
absolute rounded-full border border-black/70 cursor-pointer transition-all duration-150 ease-out flex justify-center items-center select-none overflow-visible
|
absolute rounded-full border border-black/70 cursor-pointer transition-all duration-150 ease-out flex justify-center items-center select-none overflow-visible
|
||||||
${btn.size === "small" ? "w-[6.5vw] h-[6.5vw] md:w-[2.2vw] md:h-[2.2vw] bg-white" : ""}
|
${btn.size === "small" ? "w-[7%] h-[7%] bg-white" : ""}
|
||||||
${btn.size === "medium" ? "w-[8.5vw] h-[8.5vw] md:w-[3vw] md:h-[3vw] bg-white" : ""}
|
${btn.size === "medium" ? "w-[9.6%] h-[9.6%] bg-white" : ""}
|
||||||
${btn.size === "big" ? "w-[9.5vw] h-[9.5vw] md:w-[3.5vw] md:h-[3.5vw] bg-black" : ""}
|
${btn.size === "big" ? "w-[10%] h-[10%] bg-black" : ""}
|
||||||
${btn.size === "special" ? "w-[9.5vw] h-[9.5vw] md:w-[3.5vw] md:h-[3.5vw] bg-white" : ""}
|
${btn.size === "special" ? "w-[10%] h-[10%] bg-white" : ""}
|
||||||
${btn.size === "memory" ? "w-[9.5vw] h-[9.5vw] md:w-[3.5vw] md:h-[3.5vw] bg-black" : ""}
|
${btn.size === "memory" ? "w-[10%] h-[10%] bg-black" : ""}
|
||||||
${btn.size === "elation" ? "w-[9.5vw] h-[9.5vw] md:w-[3.5vw] md:h-[3.5vw] bg-black" : ""}
|
${btn.size === "elation" ? "w-[10%] h-[10%] bg-black" : ""}
|
||||||
${isSelected ? "ring-3 ring-cyan-400 ring-offset-2 ring-offset-base-100 shadow-[0_0_12px_rgba(34,211,238,0.8)] z-20" : "hover:ring-2 hover:ring-primary/40 z-10"}
|
${isSelected ? "ring-3 ring-cyan-400 ring-offset-2 ring-offset-base-100 shadow-[0_0_12px_rgba(34,211,238,0.8)] z-20" : "hover:ring-2 hover:ring-primary/40 z-10"}
|
||||||
${!isLearned ? "opacity-40 grayscale" : "shadow-[0_0_6px_rgba(255,255,255,0.4)]"}
|
${!isLearned ? "opacity-40 grayscale" : "shadow-[0_0_6px_rgba(255,255,255,0.4)]"}
|
||||||
`}
|
`}
|
||||||
@@ -257,7 +257,7 @@ export default function SkillsInfo() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{isMajor && (
|
{isMajor && (
|
||||||
<p className="z-12 text-[10px] sm:text-xs font-mono font-bold text-center rounded-full absolute translate-y-full mt-0.5 bg-black/80 text-white px-1.5 py-0.2 border border-white/20 left-1/2 -translate-x-1/2 shadow-xs whitespace-nowrap">
|
<p className="z-12 text-[9px] sm:text-[10px] md:text-xs font-mono font-bold text-center rounded-full absolute -bottom-1.5 bg-black/85 text-white px-1.5 py-0.2 border border-white/20 left-1/2 -translate-x-1/2 shadow-xs whitespace-nowrap pointer-events-none">
|
||||||
{`${avatarData?.data.skills?.[avatarSkillTree?.[btn.id]?.["1"]?.PointID] || 0}/${avatarSkillTree?.[btn.id]?.["1"]?.MaxLevel}`}
|
{`${avatarData?.data.skills?.[avatarSkillTree?.[btn.id]?.["1"]?.PointID] || 0}/${avatarSkillTree?.[btn.id]?.["1"]?.MaxLevel}`}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user