From a6f4659ec9bef4e759fd9ab4089f36a5785e6a14 Mon Sep 17 00:00:00 2001 From: AzenKain Date: Sat, 27 Sep 2025 17:14:07 +0700 Subject: [PATCH] UPDATE: responsive ui, optimaze ux --- bun.lock | 6 - messages/cn.json | 7 +- messages/en.json | 6 +- messages/ja.json | 83 +++-- messages/ko.json | 15 +- messages/vi.json | 5 +- messages/zh.json | 5 +- package.json | 2 - src/app/layout.tsx | 18 +- src/components/actionBar/index.tsx | 188 +++++++--- src/components/avatarBar/index.tsx | 17 +- src/components/eidolonsInfo/index.tsx | 9 + src/components/importBar/copy.tsx | 2 +- src/components/monsterBar/as.tsx | 7 +- src/components/monsterBar/moc.tsx | 11 +- src/components/monsterBar/pf.tsx | 6 +- src/components/quickView/index.tsx | 504 ++++++++++++++++++++++++++ src/components/relicsInfo/index.tsx | 59 ++- src/components/showcaseCard/index.tsx | 5 +- src/components/skillsInfo/index.tsx | 6 +- src/stores/modelStore.ts | 8 + 21 files changed, 833 insertions(+), 136 deletions(-) create mode 100644 src/components/quickView/index.tsx diff --git a/bun.lock b/bun.lock index d5d666f..0f6933d 100644 --- a/bun.lock +++ b/bun.lock @@ -6,8 +6,6 @@ "dependencies": { "@next/bundle-analyzer": "^15.5.4", "@tanstack/react-query": "^5.83.0", - "@vercel/analytics": "^1.5.0", - "@vercel/speed-insights": "^1.2.0", "axios": "^1.10.0", "fast-average-color": "^9.5.0", "framer-motion": "^12.12.1", @@ -384,10 +382,6 @@ "@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="], - "@vercel/analytics": ["@vercel/analytics@1.5.0", "", { "peerDependencies": { "@remix-run/react": "^2", "@sveltejs/kit": "^1 || ^2", "next": ">= 13", "react": "^18 || ^19 || ^19.0.0-rc", "svelte": ">= 4", "vue": "^3", "vue-router": "^4" }, "optionalPeers": ["@remix-run/react", "@sveltejs/kit", "next", "react", "svelte", "vue", "vue-router"] }, "sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g=="], - - "@vercel/speed-insights": ["@vercel/speed-insights@1.2.0", "", { "peerDependencies": { "@sveltejs/kit": "^1 || ^2", "next": ">= 13", "react": "^18 || ^19 || ^19.0.0-rc", "svelte": ">= 4", "vue": "^3", "vue-router": "^4" }, "optionalPeers": ["@sveltejs/kit", "next", "react", "svelte", "vue", "vue-router"] }, "sha512-y9GVzrUJ2xmgtQlzFP2KhVRoCglwfRQgjyfY607aU0hh0Un6d0OUyrJkjuAlsV18qR4zfoFPs/BiIj9YDS6Wzw=="], - "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], diff --git a/messages/cn.json b/messages/cn.json index 3c6643b..715c49f 100644 --- a/messages/cn.json +++ b/messages/cn.json @@ -242,9 +242,12 @@ "hardMode": "困难模式", "selectPEAKEvent": "选择 PEAK 事件", "mode": "模式", - "selectMode": "选择模式", + "selectMode": "选择模式", "rollBack": "回到之前的状态", "upRoll": "增加副属性", - "downRoll": "减少副属性" + "downRoll": "减少副属性", + "actions": "操作", + "avatars": "头像", + "quickView": "快速预览" } } \ No newline at end of file diff --git a/messages/en.json b/messages/en.json index 07eb385..69357f1 100644 --- a/messages/en.json +++ b/messages/en.json @@ -246,7 +246,9 @@ "selectMode": "Select a mode", "rollBack": "Roll Back", "upRoll": "Up Roll", - "downRoll": "Down Roll" - + "downRoll": "Down Roll", + "actions": "Actions", + "avatars": "Avatars", + "quickView": "Quick View" } } \ No newline at end of file diff --git a/messages/ja.json b/messages/ja.json index 78f32a0..d403ac9 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -11,7 +11,7 @@ "path": "運命", "rarity": "レアリティ", "element": "属性", - "technique": "秘術", + "technique": "秘技", "talent": "天賦", "basic": "通常攻撃", "skill": "スキル", @@ -19,17 +19,17 @@ "servant": "サーバント", "damage": "ダメージ", "type": "タイプ", - "warrior": "破壊", - "knight": "保護", - "mage": "博識", + "warrior": "壊滅", + "knight": "存護", + "mage": "知恵", "priest": "豊穣", - "rogue": "狩猟", + "rogue": "巡狩", "shaman": "調和", "warlock": "虚無", "memory": "記憶", "fire": "火", "ice": "氷", - "imaginary": "幻影", + "imaginary": "虚数", "physical": "物理", "quantum": "量子", "thunder": "雷", @@ -39,9 +39,9 @@ "speed": "速度", "critRate": "会心率", "critDmg": "会心ダメージ", - "breakEffect": "破甲ダメージ", + "breakEffect": "撃破特効", "effectRes": "効果抵抗", - "energyRegenerationRate": "エネルギー回復速度", + "energyRegenerationRate": "EP回復効率", "effectHitRate": "効果命中率", "outgoingHealingBoost": "回復増加", "fireDmgBoost": "火属性ダメージ強化", @@ -52,15 +52,15 @@ "thunderDmgBoost": "雷属性ダメージ強化", "windDmgBoost": "風属性ダメージ強化", "pursued": "追加ダメージ", - "true damage": "真のダメージ", + "true damage": "確定ダメージ", "follow-up": "追撃ダメージ", - "elemental damage": "破甲および超破甲ダメージ", + "elemental damage": "属性ダメージ", "dot": "継続ダメージ", "qte": "QTEスキル", "level": "レベル", "relics": "遺物", "eidolons": "エイドロン", - "lightcones": "ライトコーン", + "lightcones": "光円錐", "loadData": "データ読み込み", "exportData": "データ出力", "connectSetting": "接続設定", @@ -114,32 +114,32 @@ "currentEnergy": "現在のエネルギー", "setTo50": "50%に設定", "battleConfiguration": "バトル構成", - "useTechnique": "秘術を使用", - "techniqueNote": "バトル前に秘術効果を有効化", + "useTechnique": "秘技を使用", + "techniqueNote": "バトル前に秘技効果を有効化", "enhancement": "強化", "enhancementLevel": "強化レベル", "origin": "由来", - "enhancedNote": "強化レベルが高いほど追加スキル解放", - "lightconeEquipment": "ライトコーン装備", - "lightconeSettings": "ライトコーン設定", + "enhancedNote": "強化レベルに応じて追加スキル解放", + "lightconeEquipment": "光円錐装備", + "lightconeSettings": "光円錐の設定", "placeholderLevel": "レベルを入力", "superimpositionRank": "重ねランク", - "ranksNote": "ランクが高いほど効果強い", - "changeLightcone": "ライトコーン変更", - "removeLightcone": "ライトコーン解除", - "equipLightcone": "ライトコーン装備", - "noLightconeEquipped": "ライトコーン未装備", - "equipLightconeNote": "キャラクター強化のため装備してください", + "ranksNote": "ランクが高いほど効果強化", + "changeLightcone": "光円錐を変更", + "removeLightcone": "光円錐を外す", + "equipLightcone": "光円錐を装備", + "noLightconeEquipped": "光円錐が装備されていません", + "equipLightconeNote": "強化のため光円錐を装備してください", "filter": "フィルター", - "selectedCharacters": "選択されたキャラクター", - "selectedProfiles": "選択されたプロファイル", - "clearAll": "すべてクリア", - "selectAll": "すべて選択", + "selectedCharacters": "選択中のキャラクター", + "selectedProfiles": "選択中のプロファイル", + "clearAll": "全てクリア", + "selectAll": "全て選択", "copy": "コピー", "copied": "コピー済み", - "noAvatarSelected": "キャラクター未選択", - "noAvatarToCopySelected": "コピーするキャラクター未選択", - "pleaseSelectAtLeastOneProfile": "プロファイルを最低1つ選択してください", + "noAvatarSelected": "キャラクターが選択されていません", + "noAvatarToCopySelected": "コピーするキャラクター選択されていません", + "pleaseSelectAtLeastOneProfile": "プロファイルを少なくとも1つ選んでください", "pleaseEnterUid": "UIDを入力してください", "failedToFetchEnkaData": "Enka のデータ取得に失敗", "pleaseSelectAtLeastOneCharacter": "キャラクターを最低1つ選択してください", @@ -159,7 +159,7 @@ "pleaseSelectAllOptions": "すべてのオプションを選択してください", "relicSavedSuccessfully": "遺物の保存に成功しました", "mainSettings": "メイン設定", - "mainStat": "主属性", + "mainStat": "メインステータス", "set": "セット", "pleaseSelectASet": "セットを選択してください", "effectBonus": "効果ボーナス", @@ -168,14 +168,14 @@ "randomizeRolls": "ロール回数ランダム化", "selectASubStat": "サブステータスを選択", "selectASet": "セットを選択", - "selectAMainStat": "主属性を選択", + "selectAMainStat": "メインステータスを選んでください", "save": "保存", "reset": "リセット", "roll": "ロール", "step": "ステップ", - "memoryOfChaos": "忘却の庭", + "memoryOfChaos": "混沌の記憶", "pureFiction": "虚構叙事", - "apocalypticShadow": "終末の幻影", + "apocalypticShadow": "末日の幻影", "customEnemy": "カスタム敵", "simulatedUniverse": "模擬宇宙", "floor": "階層", @@ -187,7 +187,7 @@ "firstHalfEnemies": "前半の敵", "secondHalfEnemies": "後半の敵", "turbulenceBuff": "乱気流バフ", - "noEventSelected": "未選択のイベント", + "noEventSelected": "イベントが選択されていません", "noTurbulenceBuff": "乱気流バフがありません", "upper": "上半", "lower": "下半", @@ -211,13 +211,13 @@ "searchMonster": "敵を検索...", "changeRelic": "遺物を変更", "deleteRelic": "遺物を削除", - "deleteRelicConfirm": "スロットの遺物を削除してもよろしいですか?", + "deleteRelicConfirm": "この遺物を削除してもよろしいですか?", "setEffects": "効果を設定", "details": "詳細", "normal": "通常攻撃", - "bpskill": "スキル", - "maze": "技術", - "ultra": "アルティメット", + "bpskill": "戦闘スキル", + "maze": "秘技", + "ultra": "必殺技", "servantskill": "メモスプライトスキル", "severaltalent": "メモスプライトの才能", "singleattack": "単体攻撃", @@ -236,7 +236,7 @@ "maxAll": "すべて最大化", "maxAllSuccess": "スキルレベルを最大に設定しました。", "maxAllFailed": "スキルレベルの最大設定に失敗しました。", - "noRelicEquipped": "聖遺物が装備されていません", + "noRelicEquipped": "遺物が装備されていません", "anomalyArbitration": "異相の仲裁", "normalMode": "通常モード", "hardMode": "困難モード", @@ -245,6 +245,9 @@ "selectMode": "モードを選択", "rollBack": "前の状態に戻る", "upRoll": "サブステータスを増やす", - "downRoll": "サブステータスを減らす" + "downRoll": "サブステータスを減らす", + "actions": "アクション", + "avatars": "アバター", + "quickView": "クイックビュー" } } \ No newline at end of file diff --git a/messages/ko.json b/messages/ko.json index 0a70cad..a010439 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -112,18 +112,18 @@ "max": "최대", "ultimateEnergy": "궁극 에너지", "currentEnergy": "현재 에너지", - "setTo50": "50%로 설정", + "setTo50": "50%로 설정", "battleConfiguration": "전투 구성", "useTechnique": "비기 사용", "techniqueNote": "전투 전 비기 효과 활성화", - "enhancement": "강화", + "enhancement": "강화", "enhancementLevel": "강화 레벨", "origin": "출처", "enhancedNote": "강화 레벨이 높을수록 추가 효과 해제", "lightconeEquipment": "라이트콘 장비", "lightconeSettings": "라이트콘 설정", "placeholderLevel": "레벨 입력", - "superimpositionRank": "중첩 등급", + "superimpositionRank": "중첩 등급", "ranksNote": "등급이 높을수록 효과가 강함", "changeLightcone": "라이트콘 변경", "removeLightcone": "라이트콘 제거", @@ -245,6 +245,9 @@ "selectMode": "모드를 선택", "rollBack": "이전 상태로 되돌리기", "upRoll": "부옵션 추가", - "downRoll": "부옵션 감소" - } -} + "downRoll": "부옵션 감소", + "actions": "동작", + "avatars": "아바타", + "quickView": "빠른 조회" + } +} \ No newline at end of file diff --git a/messages/vi.json b/messages/vi.json index 046f36b..9f4fba6 100644 --- a/messages/vi.json +++ b/messages/vi.json @@ -245,6 +245,9 @@ "selectMode": "Chọn chế độ", "rollBack": "Quay lại bước trước", "upRoll": "Tăng dòng", - "downRoll": "Giảm dòng" + "downRoll": "Giảm dòng", + "actions": "Hành động", + "avatars": "Nhân vật", + "quickView": "Xem nhanh" } } \ No newline at end of file diff --git a/messages/zh.json b/messages/zh.json index b423533..8c336a1 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -245,6 +245,9 @@ "selectMode": "选择模式", "rollBack": "回到之前的状态", "upRoll": "增加副属性", - "downRoll": "减少副属性" + "downRoll": "减少副属性", + "actions": "操作", + "avatars": "头像", + "quickView": "快速预览" } } \ No newline at end of file diff --git a/package.json b/package.json index 8000ea5..0b357fb 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,6 @@ "dependencies": { "@next/bundle-analyzer": "^15.5.4", "@tanstack/react-query": "^5.83.0", - "@vercel/analytics": "^1.5.0", - "@vercel/speed-insights": "^1.2.0", "axios": "^1.10.0", "fast-average-color": "^9.5.0", "framer-motion": "^12.12.1", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index d284332..8e38a79 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,12 +7,11 @@ import Footer from "@/components/footer"; import { NextIntlClientProvider } from "next-intl"; import { getLocale, getMessages } from "next-intl/server"; import { ToastContainer } from 'react-toastify'; -import AvatarBar from "@/components/avatarBar"; -import ActionBar from "@/components/actionBar"; import QueryProviderWrapper from "@/components/queryProvider"; import ClientDataFetcher from "@/components/clientDataFetcher"; -import { SpeedInsights } from "@vercel/speed-insights/next" -import { Analytics } from "@vercel/analytics/next" +import AvatarBar from "@/components/avatarBar"; +import ActionBar from "@/components/actionBar"; + const geistSans = Geist({ variable: "--font-geist-sans", @@ -74,19 +73,19 @@ export default async function RootLayout({ - +
-
+
-
+
{children} -
+
@@ -95,8 +94,7 @@ export default async function RootLayout({ - - + diff --git a/src/components/actionBar/index.tsx b/src/components/actionBar/index.tsx index bcd460d..e5b0fb1 100644 --- a/src/components/actionBar/index.tsx +++ b/src/components/actionBar/index.tsx @@ -17,6 +17,7 @@ import useGlobalStore from "@/stores/globalStore"; import { connectToPS, syncDataToPS } from "@/helper"; import CopyImport from "../importBar/copy"; import useCopyProfileStore from "@/stores/copyProfile"; +import AvatarBar from "../avatarBar"; export default function ActionBar() { @@ -25,7 +26,14 @@ export default function ActionBar() { const { setListCopyAvatar } = useCopyProfileStore() const transI18n = useTranslations("DataPage") const { locale } = useLocaleStore() - const { isOpenCreateProfile, setIsOpenCreateProfile, isOpenCopy, setIsOpenCopy } = useModelStore() + const { + isOpenCreateProfile, + setIsOpenCreateProfile, + isOpenCopy, + setIsOpenCopy, + isOpenAvatars, + setIsOpenAvatars + } = useModelStore() const { avatars, setAvatar } = useUserDataStore() const [profileName, setProfileName] = useState(""); const [formState, setFormState] = useState("EDIT"); @@ -85,6 +93,7 @@ export default function ActionBar() { // Handle ESC key to close modal useEffect(() => { + if (!isOpenCreateProfile) { handleCloseModal("update_profile_modal"); return; @@ -93,6 +102,12 @@ export default function ActionBar() { handleCloseModal("copy_profile_modal"); return; } + console.log(isOpenAvatars) + if (!isOpenAvatars) { + + handleCloseModal("avatars_modal"); + return; + } const handleEscKey = (event: KeyboardEvent) => { if (event.key === 'Escape' && isOpenCreateProfile) { @@ -101,12 +116,15 @@ export default function ActionBar() { if (event.key === 'Escape' && isOpenCopy) { handleCloseModal("copy_profile_modal"); } + if (event.key === 'Escape' && isOpenAvatars) { + handleCloseModal("avatars_modal"); + } }; window.addEventListener('keydown', handleEscKey); return () => window.removeEventListener('keydown', handleEscKey); - }, [isOpenCopy, isOpenCreateProfile]); + }, [isOpenCopy, isOpenCreateProfile, isOpenAvatars]); const actionMove = (path: string) => { router.push(`/${path}`) @@ -154,49 +172,48 @@ export default function ActionBar() { } return ( -
-
-
-
-
+
+
+ +
+
+
{avatarSelected && ( - <> +
{'fire'} -
-

- {transI18n(avatarSelected.baseType.toLowerCase())} -

-
{" / "}
- - {avatarSelected?.id && ( -
{`(${avatarSelected.id})`}
- )} -
- +

+ {transI18n(avatarSelected.baseType.toLowerCase())} +

+
{" / "}
+ + {avatarSelected?.id && ( +
{`(${avatarSelected.id})`}
+ )} +
)}
-
+
{transI18n("profile")}: -
+
- + {profileCurrent?.profile_name} @@ -204,7 +221,7 @@ export default function ActionBar() {
-
    +
      {listProfile.map((profile, index) => (
+
+ +
+ +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
-
- {/* Action Buttons */} -
- - - - - - -
+
+ + + + + +
- - +
@@ -366,6 +442,32 @@ export default function ActionBar() {
+ + +
+
+ { + setIsOpenAvatars(false) + handleCloseModal("avatars_modal") + }} + > + ✕ + +
+
+

+ {transI18n("avatars").toUpperCase()} +

+
+ {setIsOpenAvatars(false); handleCloseModal("avatars_modal")}} /> +
+
+ +
); diff --git a/src/components/avatarBar/index.tsx b/src/components/avatarBar/index.tsx index 03ee9d6..6f9a228 100644 --- a/src/components/avatarBar/index.tsx +++ b/src/components/avatarBar/index.tsx @@ -7,13 +7,12 @@ import useAvatarStore from "@/stores/avatarStore" import { useTranslations } from "next-intl" -export default function AvatarBar() { +export default function AvatarBar({ onClose }: { onClose?: () => void }) { const [listElement, setListElement] = useState>({ "fire": false, "ice": false, "imaginary": false, "physical": false, "quantum": false, "thunder": false, "wind": false }) const [listPath, setListPath] = useState>({ "knight": false, "mage": false, "priest": false, "rogue": false, "shaman": false, "warlock": false, "warrior": false, "memory": false }) const { listAvatar, setAvatarSelected, setSkillSelected, setFilter, filter } = useAvatarStore() const transI18n = useTranslations("DataPage") const { locale } = useLocaleStore() - useEffect(() => { @@ -31,12 +30,12 @@ export default function AvatarBar() {
setFilter({ ...filter, name: e.target.value, locale: locale })} />
-
+
{Object.keys(listElement).map((key, index) => (
-
+
{Object.keys(listPath).map((key, index) => (
-
    +
      {listAvatar.map((item, index) => ( -
      {setAvatarSelected(item); setSkillSelected(null)}}> +
      { + setAvatarSelected(item); + setSkillSelected(null) + if (onClose) onClose() + }}>
      ))} diff --git a/src/components/eidolonsInfo/index.tsx b/src/components/eidolonsInfo/index.tsx index f0d5c83..9ebcffd 100644 --- a/src/components/eidolonsInfo/index.tsx +++ b/src/components/eidolonsInfo/index.tsx @@ -7,10 +7,13 @@ import ParseText from "../parseText"; import useLocaleStore from "@/stores/localeStore"; import useUserDataStore from "@/stores/userDataStore"; import { useMemo } from "react"; +import { useTranslations } from "next-intl"; + export default function EidolonsInfo() { const { avatarSelected, mapAvatarInfo } = useListAvatarStore() const { locale } = useLocaleStore() + const transI18n = useTranslations("DataPage") const { setAvatars, avatars } = useUserDataStore() const charRank = useMemo(() => { @@ -23,6 +26,11 @@ export default function EidolonsInfo() { }, [avatarSelected, avatars, locale, mapAvatarInfo]); return ( +
      +

      +
      + {transI18n("eidolons")} +

      {charRank && avatars[avatarSelected?.id || ""] && (
      @@ -63,5 +71,6 @@ export default function EidolonsInfo() {
      )}
      +
      ); } diff --git a/src/components/importBar/copy.tsx b/src/components/importBar/copy.tsx index e11117a..66e0f48 100644 --- a/src/components/importBar/copy.tsx +++ b/src/components/importBar/copy.tsx @@ -134,7 +134,7 @@ export default function CopyImport() {
      {transI18n("filter")}
      -
      +
      {/* Path */}
      diff --git a/src/components/monsterBar/as.tsx b/src/components/monsterBar/as.tsx index 431ffed..c1ed15f 100644 --- a/src/components/monsterBar/as.tsx +++ b/src/components/monsterBar/as.tsx @@ -160,7 +160,12 @@ export default function AsBar() { excludeSet={[]} selectedCustomSet={as_config.event_id.toString()} placeholder={transI18n("selectASEvent")} - setSelectedCustomSet={(id) => setAsConfig({ ...as_config, event_id: Number(id), challenge_id: 0, buff_id: 0 })} + setSelectedCustomSet={(id) => setAsConfig({ + ...as_config, + event_id: Number(id), + challenge_id: mapASInfo[Number(id)]?.Level.slice(-1)[0]?.Id || 0, + buff_id: 0 + })} />
      {/* Settings */} diff --git a/src/components/monsterBar/moc.tsx b/src/components/monsterBar/moc.tsx index be888e5..4728815 100644 --- a/src/components/monsterBar/moc.tsx +++ b/src/components/monsterBar/moc.tsx @@ -127,7 +127,11 @@ export default function MocBar() { excludeSet={[]} selectedCustomSet={moc_config.event_id.toString()} placeholder={transI18n("selectMOCEvent")} - setSelectedCustomSet={(id) => setMocConfig({ ...moc_config, event_id: Number(id), challenge_id: 0 })} + setSelectedCustomSet={(id) => setMocConfig({ + ...moc_config, + event_id: Number(id), + challenge_id: mapMOCInfo[Number(id)]?.slice(-1)[0]?.Id || 0, + })} />
      {/* Settings */} @@ -140,7 +144,10 @@ export default function MocBar() {