This commit is contained in:
@@ -254,9 +254,25 @@
|
|||||||
"extraSetting": "额外设置",
|
"extraSetting": "额外设置",
|
||||||
"disableCensorship": "禁用审查",
|
"disableCensorship": "禁用审查",
|
||||||
"hideUI": "隐藏界面",
|
"hideUI": "隐藏界面",
|
||||||
"theoryCraftMode": "理论研究模式",
|
"theoryCraftMode": "Theory Craft 模式",
|
||||||
"cycleCount": "循环次数",
|
"cycleCount": "循环次数",
|
||||||
"pleaseSelectAllSubStats": "请选取所有副属性",
|
"pleaseSelectAllSubStats": "请选取所有副属性",
|
||||||
"subStatRollCountCannotBeZero": "副属性的行数不能为0"
|
"subStatRollCountCannotBeZero": "副属性的行数不能为0",
|
||||||
|
"theoryCraft": "Theory Craft",
|
||||||
|
"multipathCharacter": "多命途角色",
|
||||||
|
"mainPath": "主角命途",
|
||||||
|
"march7Path": "三月七命途",
|
||||||
|
"challenge": "挑战",
|
||||||
|
"skipNode": "跳过节点",
|
||||||
|
"disableSkip": "禁用跳过",
|
||||||
|
"skipNode1": "跳过节点1",
|
||||||
|
"skipNode2": "跳过节点2",
|
||||||
|
"extraFeatures": "附加功能",
|
||||||
|
"detailTheoryCraft": "开启后可自定义循环数,并在敌人设置中调整生命值。",
|
||||||
|
"detailSkipNode": "开启后可跳过混沌回忆或虚构叙事的(节点1/节点2)。",
|
||||||
|
"detailChallengePeak": "允许更改当前异相中的「巅峰」赛季。",
|
||||||
|
"detailHiddenUi": "开启后将隐藏游戏界面。",
|
||||||
|
"detailDisableCensorship": "开启后将关闭游戏内的审查。",
|
||||||
|
"detailMultipathCharacter": "允许更改部分角色的命途。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,22 +19,22 @@
|
|||||||
"servant": "Servant",
|
"servant": "Servant",
|
||||||
"damage": "Damage",
|
"damage": "Damage",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"warrior": "Destruction",
|
"warrior": "Destruction",
|
||||||
"knight": "Preservation",
|
"knight": "Preservation",
|
||||||
"mage": "Erudition",
|
"mage": "Erudition",
|
||||||
"priest": "Abundance",
|
"priest": "Abundance",
|
||||||
"rogue": "The Hunt",
|
"rogue": "The Hunt",
|
||||||
"shaman": "Harmony",
|
"shaman": "Harmony",
|
||||||
"warlock": "Nihility",
|
"warlock": "Nihility",
|
||||||
"memory": "Remembrance",
|
"memory": "Remembrance",
|
||||||
"elation": "The Elation",
|
"elation": "The Elation",
|
||||||
"fire": "Fire",
|
"fire": "Fire",
|
||||||
"ice": "Ice",
|
"ice": "Ice",
|
||||||
"imaginary": "Imaginary",
|
"imaginary": "Imaginary",
|
||||||
"physical": "Physical",
|
"physical": "Physical",
|
||||||
"quantum": "Quantum",
|
"quantum": "Quantum",
|
||||||
"thunder": "Thunder",
|
"thunder": "Thunder",
|
||||||
"wind": "Wind",
|
"wind": "Wind",
|
||||||
"hp": "Hp",
|
"hp": "Hp",
|
||||||
"atk": "Atk",
|
"atk": "Atk",
|
||||||
"speed": "Speed",
|
"speed": "Speed",
|
||||||
@@ -60,8 +60,8 @@
|
|||||||
"dot": "Damage over time ",
|
"dot": "Damage over time ",
|
||||||
"qte": "QTE Skill",
|
"qte": "QTE Skill",
|
||||||
"level": "Level",
|
"level": "Level",
|
||||||
"relics": "Relics",
|
"relics": "Relics",
|
||||||
"eidolons": "Eidolons",
|
"eidolons": "Eidolons",
|
||||||
"lightcones": "Lightcones",
|
"lightcones": "Lightcones",
|
||||||
"loadData": "Load data",
|
"loadData": "Load data",
|
||||||
"exportData": "Export data",
|
"exportData": "Export data",
|
||||||
@@ -258,6 +258,22 @@
|
|||||||
"theoryCraftMode": "Theorycraft Mode",
|
"theoryCraftMode": "Theorycraft Mode",
|
||||||
"cycleCount": "Cycle Count",
|
"cycleCount": "Cycle Count",
|
||||||
"pleaseSelectAllSubStats": "Please select all sub stats",
|
"pleaseSelectAllSubStats": "Please select all sub stats",
|
||||||
"subStatRollCountCannotBeZero": "Sub stat roll count cannot be zero"
|
"subStatRollCountCannotBeZero": "Sub stat roll count cannot be zero",
|
||||||
|
"theorycraft": "Theorycraft",
|
||||||
|
"multipathCharacter": "Multipath Character",
|
||||||
|
"mainPath": "Main Path",
|
||||||
|
"march7Path": "March 7 Path",
|
||||||
|
"challenge": "Challenge",
|
||||||
|
"skipNode": "Skip Node",
|
||||||
|
"disableSkip": "Disable skip",
|
||||||
|
"skipNode1": "Skip node 1",
|
||||||
|
"skipNode2": "Skip node 2",
|
||||||
|
"extraFeatures": "Extra Features",
|
||||||
|
"detailTheoryCraft": "Enabling this feature allows you to customize the cycle count and adjust enemy HP in the enemy settings.",
|
||||||
|
"detailSkipNode": "Enabling this feature allows you to skip (Node 1/Node 2) in Memory of Chaos or Pure Fiction.",
|
||||||
|
"detailChallengePeak": "Allows changing the Peak season in the current Anomaly.",
|
||||||
|
"detailHiddenUi": "Enabling this feature will hide the game UI.",
|
||||||
|
"detailDisableCensorship": "Enabling this feature will disable in-game censorship.",
|
||||||
|
"detailMultipathCharacter": "Allows changing the Path of certain characters."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,6 +257,22 @@
|
|||||||
"theoryCraftMode": "シアリークラフトモード",
|
"theoryCraftMode": "シアリークラフトモード",
|
||||||
"cycleCount": "サイクル数",
|
"cycleCount": "サイクル数",
|
||||||
"pleaseSelectAllSubStats": "すべてのサブステータスを選択してください",
|
"pleaseSelectAllSubStats": "すべてのサブステータスを選択してください",
|
||||||
"subStatRollCountCannotBeZero": "サブステータスの行数は0にできません"
|
"subStatRollCountCannotBeZero": "サブステータスの行数は0にできません",
|
||||||
|
"theoryCraft": "シアリークラフト",
|
||||||
|
"multipathCharacter": "複数運命キャラ",
|
||||||
|
"mainPath": "主人公の運命",
|
||||||
|
"march7Path": "三月なのかの運命",
|
||||||
|
"challenge": "挑戦",
|
||||||
|
"skipNode": "ノードをスキップ",
|
||||||
|
"disableSkip": "スキップ無効",
|
||||||
|
"skipNode1": "ノード1をスキップ",
|
||||||
|
"skipNode2": "ノード2をスキップ",
|
||||||
|
"extraFeatures": "追加機能",
|
||||||
|
"detailTheoryCraft": "この機能を有効にすると、サイクル数の調整や敵設定でHPの調整が可能になります。",
|
||||||
|
"detailSkipNode": "この機能を有効にすると、混沌の記憶または虚構叙事の(ノード1/ノード2)をスキップできます。",
|
||||||
|
"detailChallengePeak": "現在の異相における「頂」のシーズンを変更できます。",
|
||||||
|
"detailHiddenUi": "この機能を有効にすると、ゲームのUIを非表示にします。",
|
||||||
|
"detailDisableCensorship": "この機能を有効にすると、ゲーム内の検閲を無効にします。",
|
||||||
|
"detailMultipathCharacter": "一部キャラクターの運命を変更できます。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,9 +254,25 @@
|
|||||||
"extraSetting": "추가 설정",
|
"extraSetting": "추가 설정",
|
||||||
"disableCensorship": "검열 비활성화",
|
"disableCensorship": "검열 비활성화",
|
||||||
"hideUI": "UI 숨기기",
|
"hideUI": "UI 숨기기",
|
||||||
"theoryCraftMode": "이론 제작 모드",
|
"theoryCraftMode": "Theory Craft 모드",
|
||||||
"cycleCount": "사이클 수",
|
"cycleCount": "사이클 수",
|
||||||
"pleaseSelectAllSubStats": "모든 부옵션을 선택하세요",
|
"pleaseSelectAllSubStats": "모든 부옵션을 선택하세요",
|
||||||
"subStatRollCountCannotBeZero": "부옵션의 줄 수는 0일 수 없습니다"
|
"subStatRollCountCannotBeZero": "부옵션의 줄 수는 0일 수 없습니다",
|
||||||
|
"theoryCraft": "Theory Craft",
|
||||||
|
"multipathCharacter": "다중 운명 캐릭터",
|
||||||
|
"mainPath": "개척자 운명",
|
||||||
|
"march7Path": "삼월칠일 운명",
|
||||||
|
"challenge": "도전",
|
||||||
|
"skipNode": "노드 건너뛰기",
|
||||||
|
"disableSkip": "건너뛰기 비활성화",
|
||||||
|
"skipNode1": "노드 1 건너뛰기",
|
||||||
|
"skipNode2": "노드 2 건너뛰기",
|
||||||
|
"extraFeatures": "추가 기능",
|
||||||
|
"detailTheoryCraft": "이 기능을 활성화하면 사이클 수를 조정하고 적 설정에서 HP를 변경할 수 있습니다.",
|
||||||
|
"detailSkipNode": "이 기능을 활성화하면 혼돈의 기억 또는 허구 서사의 (노드 1/노드 2)를 건너뛸 수 있습니다.",
|
||||||
|
"detailChallengePeak": "현재 이형에서의 피크 시즌을 변경할 수 있습니다.",
|
||||||
|
"detailHiddenUi": "이 기능을 활성화하면 게임 UI가 숨겨집니다.",
|
||||||
|
"detailDisableCensorship": "이 기능을 활성화하면 게임 내 검열이 비활성화됩니다.",
|
||||||
|
"detailMultipathCharacter": "일부 캐릭터의 운명을 변경할 수 있습니다."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,9 +254,25 @@
|
|||||||
"extraSetting": "Cài đặt bổ sung",
|
"extraSetting": "Cài đặt bổ sung",
|
||||||
"disableCensorship": "Tắt kiểm duyệt",
|
"disableCensorship": "Tắt kiểm duyệt",
|
||||||
"hideUI": "Ẩn giao diện",
|
"hideUI": "Ẩn giao diện",
|
||||||
"theoryCraftMode": "Chế độ Theorycraft",
|
"theoryCraftMode": "Chế độ Theory Craft",
|
||||||
"cycleCount": "Số vòng",
|
"cycleCount": "Số vòng",
|
||||||
"pleaseSelectAllSubStats": "Vui lòng chọn tất cả chỉ số phụ",
|
"pleaseSelectAllSubStats": "Vui lòng chọn tất cả chỉ số phụ",
|
||||||
"subStatRollCountCannotBeZero": "Số dòng của chỉ số phụ không thể bằng 0"
|
"subStatRollCountCannotBeZero": "Số dòng của chỉ số phụ không thể bằng 0",
|
||||||
|
"theoryCraft": "Theory Craft",
|
||||||
|
"multipathCharacter": "Nhân vật đa Vận Mệnh",
|
||||||
|
"mainPath": "Vận Mệnh Nhân Vật Chính",
|
||||||
|
"march7Path": "Vận Mệnh March 7",
|
||||||
|
"challenge": "Thử thách",
|
||||||
|
"skipNode": "Bỏ qua node",
|
||||||
|
"disableSkip": "Tắt bỏ qua",
|
||||||
|
"skipNode1": "Bỏ qua node 1",
|
||||||
|
"skipNode2": "Bỏ qua node 2",
|
||||||
|
"extraFeatures": "Tính năng bổ sung",
|
||||||
|
"detailTheoryCraft": "Khi bật tính năng này sẽ cho phép tùy chỉnh số cycle và trong mục kẻ địch tủy chỉnh sẽ cho phép điều chỉnh số hp.",
|
||||||
|
"detailSkipNode": "Khi bật tính năng này sẽ cho phép bỏ qua (node 1/node 2) của Hồi ức hỗn độn hoặc Kể chuyện hư cấu.",
|
||||||
|
"detailChallengePeak": "Cho phép thay đổi mùa Trọng tại dị tướng hiện tại.",
|
||||||
|
"detailHiddenUi": "Khi bật tính năng này sẽ ẩn giao diện của game.",
|
||||||
|
"detailDisableCensorship": "Khi bật tính năng này sẽ tắt kiểm duyệt của game.",
|
||||||
|
"detailMultipathCharacter": "Cho phép thay đổi Vận Mệnh của một vài nhân vật."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,9 +254,25 @@
|
|||||||
"extraSetting": "额外设置",
|
"extraSetting": "额外设置",
|
||||||
"disableCensorship": "禁用审查",
|
"disableCensorship": "禁用审查",
|
||||||
"hideUI": "隐藏界面",
|
"hideUI": "隐藏界面",
|
||||||
"theoryCraftMode": "理论研究模式",
|
"theoryCraftMode": "Theory Craft 模式",
|
||||||
"cycleCount": "循环次数",
|
"cycleCount": "循环次数",
|
||||||
"pleaseSelectAllSubStats": "请选取所有副属性",
|
"pleaseSelectAllSubStats": "请选取所有副属性",
|
||||||
"subStatRollCountCannotBeZero": "副属性的行数不能为0"
|
"subStatRollCountCannotBeZero": "副属性的行数不能为0",
|
||||||
|
"theoryCraft": "Theory Craft",
|
||||||
|
"multipathCharacter": "多命途角色",
|
||||||
|
"mainPath": "主角命途",
|
||||||
|
"march7Path": "三月七命途",
|
||||||
|
"challenge": "挑战",
|
||||||
|
"skipNode": "跳过节点",
|
||||||
|
"disableSkip": "禁用跳过",
|
||||||
|
"skipNode1": "跳过节点1",
|
||||||
|
"skipNode2": "跳过节点2",
|
||||||
|
"extraFeatures": "附加功能",
|
||||||
|
"detailTheoryCraft": "开启后可自定义循环数,并在敌人设置中调整生命值。",
|
||||||
|
"detailSkipNode": "开启后可跳过混沌回忆或虚构叙事的(节点1/节点2)。",
|
||||||
|
"detailChallengePeak": "允许更改当前异相中的「巅峰」赛季。",
|
||||||
|
"detailHiddenUi": "开启后将隐藏游戏界面。",
|
||||||
|
"detailDisableCensorship": "开启后将关闭游戏内的审查。",
|
||||||
|
"detailMultipathCharacter": "允许更改部分角色的命途。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
|
||||||
@plugin "daisyui" {
|
@plugin "daisyui" {
|
||||||
themes: winter --default, night --prefersdark, cupcake, coffee;
|
themes: winter --default, night --prefersdark, cupcake, coffee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
@plugin 'tailwind-scrollbar' {
|
@plugin 'tailwind-scrollbar' {
|
||||||
nocompatible: true;
|
nocompatible: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--size-big: 4vw;
|
--size-big: 4vw;
|
||||||
--size-medium: 3vw;
|
--size-medium: 3vw;
|
||||||
@@ -30,40 +35,3 @@
|
|||||||
::-webkit-scrollbar-button {
|
::-webkit-scrollbar-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
@layer components {
|
|
||||||
/* .my-react-select-container {
|
|
||||||
} */
|
|
||||||
.my-react-select-container .my-react-select__control {
|
|
||||||
@apply bg-white dark:bg-neutral-700 border-2 border-neutral-300 dark:border-neutral-700 hover:border-neutral-400 dark:hover:border-neutral-500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-react-select-container .my-react-select__control--is-focused {
|
|
||||||
@apply border-neutral-500 hover:border-neutral-500 dark:border-neutral-400 dark:hover:border-neutral-400 shadow-none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-react-select-container .my-react-select__menu {
|
|
||||||
@apply bg-neutral-100 dark:bg-neutral-700 border-2 border-neutral-300 dark:border-neutral-600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.my-react-select-container .my-react-select__option {
|
|
||||||
@apply text-neutral-600 dark:text-neutral-200 bg-neutral-100 hover:bg-neutral-200 dark:bg-neutral-700 dark:hover:bg-neutral-800;
|
|
||||||
}
|
|
||||||
/* .my-react-select-container .my-react-select__option--is-focused {
|
|
||||||
@apply bg-neutral-200 dark:bg-neutral-800;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.my-react-select-container .my-react-select__indicator-separator {
|
|
||||||
@apply bg-neutral-400;
|
|
||||||
}
|
|
||||||
.my-react-select-container .my-react-select__menu {
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
.my-react-select-container .my-react-select__input-container,
|
|
||||||
.my-react-select-container .my-react-select__placeholder,
|
|
||||||
.my-react-select-container .my-react-select__single-value {
|
|
||||||
@apply text-neutral-600 dark:text-neutral-200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ export default function CharacterCard({ data }: CharacterCardProps) {
|
|||||||
className="z-10 flex flex-col items-center rounded-xl shadow-xl
|
className="z-10 flex flex-col items-center rounded-xl shadow-xl
|
||||||
bg-linear-to-br from-base-300 via-base-100 to-warning/70
|
bg-linear-to-br from-base-300 via-base-100 to-warning/70
|
||||||
transform transition-transform duration-300 ease-in-out
|
transform transition-transform duration-300 ease-in-out
|
||||||
hover:scale-105 cursor-pointer min-h-[170px] sm:min-h-[180px] md:min-h-[210px] lg:min-h-[220px] xl:min-h-[240px] 2xl:min-h-[340px]"
|
hover:scale-105 cursor-pointer min-h-42.5 sm:min-h-45 md:min-h-52.5 lg:min-h-55 xl:min-h-60 2xl:min-h-85"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`w-full rounded-md bg-linear-to-br ${data.rank === "CombatPowerAvatarRarityType5"
|
className={`w-full rounded-md bg-linear-to-br ${data.rank === "CombatPowerAvatarRarityType5"
|
||||||
|
|||||||
@@ -1,80 +1,229 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { motion } from "framer-motion"
|
import { motion } from "framer-motion"
|
||||||
import { EyeOff, Eye, Hammer, RefreshCw, ShieldBan } from "lucide-react"
|
import { EyeOff, Eye, Hammer, RefreshCw, ShieldBan, User, Swords, SkipForward, BowArrow, Info } from "lucide-react"
|
||||||
import useGlobalStore from '@/stores/globalStore';
|
import useGlobalStore from '@/stores/globalStore'
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl"
|
||||||
|
import useEventStore from "@/stores/eventStore"
|
||||||
|
import { getLocaleName, getNameChar } from "@/helper"
|
||||||
|
import useLocaleStore from "@/stores/localeStore"
|
||||||
|
import useAvatarStore from "@/stores/avatarStore"
|
||||||
|
import SelectCustomImage from "../select/customSelectImage"
|
||||||
|
|
||||||
export default function ExtraSettingBar() {
|
export default function ExtraSettingBar() {
|
||||||
const { extraData, setExtraData } = useGlobalStore()
|
const { extraData, setExtraData } = useGlobalStore()
|
||||||
const transI18n = useTranslations("DataPage")
|
const transI18n = useTranslations("DataPage")
|
||||||
|
const { PEAKEvent } = useEventStore()
|
||||||
|
const { listAvatar } = useAvatarStore()
|
||||||
|
const { locale } = useLocaleStore()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-4 sm:px-6 py-4">
|
<div className="px-4 sm:px-6 py-4 space-y-8">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
{extraData?.theory_craft && (
|
||||||
{/* Theorycraft Mode */}
|
<div className="space-y-4">
|
||||||
{extraData?.theory_craft?.mode !== undefined && (
|
<h3 className="text-lg font-bold flex items-center gap-2">
|
||||||
<motion.div
|
{transI18n("theoryCraft")}
|
||||||
whileHover={{ scale: 1.02 }}
|
<div className="tooltip tooltip-info" data-tip={transI18n("detailTheoryCraft")}>
|
||||||
className="form-control bg-base-200 p-4 rounded-xl shadow"
|
<Info className="text-primary" size={20} />
|
||||||
>
|
</div>
|
||||||
<label className="flex flex-wrap items-center label cursor-pointer justify-start gap-3">
|
</h3>
|
||||||
<Hammer className="text-primary" size={20}/>
|
|
||||||
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
|
<label className="flex flex-wrap items-center cursor-pointer justify-start gap-3">
|
||||||
|
<Hammer className="text-primary" size={20} />
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="toggle toggle-primary"
|
className="toggle toggle-primary"
|
||||||
checked={extraData?.theory_craft?.mode}
|
checked={extraData?.theory_craft?.mode}
|
||||||
onChange={(e) =>
|
onChange={(e) => {
|
||||||
setExtraData({
|
setExtraData({
|
||||||
...extraData,
|
...extraData,
|
||||||
theory_craft: { ...extraData?.theory_craft, mode: e.target.checked }
|
theory_craft: {
|
||||||
|
hp: extraData?.theory_craft?.hp || {},
|
||||||
|
cycle_count: extraData?.theory_craft?.cycle_count || 0,
|
||||||
|
mode: e.target.checked
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<span className="label-text font-semibold">{transI18n("theoryCraftMode")}</span>
|
<span className="label-text font-semibold">{transI18n("theoryCraftMode")}</span>
|
||||||
</label>
|
</label>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Cycle Count */}
|
{extraData?.theory_craft?.mode && (
|
||||||
{extraData?.theory_craft?.mode && (
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
<motion.div
|
<label className="flex flex-wrap items-center justify-start gap-3">
|
||||||
whileHover={{ scale: 1.02 }}
|
<RefreshCw className="text-info" size={20} />
|
||||||
className="form-control bg-base-200 p-4 rounded-xl shadow"
|
<span className="label-text font-semibold">{transI18n("cycleCount")}</span>
|
||||||
>
|
<input
|
||||||
<label className="flex flex-wrap items-center label justify-start gap-3">
|
type="number"
|
||||||
<RefreshCw className="text-info" size={20}/>
|
className="input input-primary"
|
||||||
<span className="label-text font-semibold">{transI18n("cycleCount")}</span>
|
value={extraData?.theory_craft?.cycle_count}
|
||||||
<input
|
onChange={(e) =>
|
||||||
type="number"
|
setExtraData({
|
||||||
className="input input-bordered"
|
...extraData,
|
||||||
value={extraData?.theory_craft?.cycle_count}
|
theory_craft: {
|
||||||
onChange={(e) =>
|
hp: extraData?.theory_craft?.hp || {},
|
||||||
setExtraData({
|
cycle_count: parseInt(e.target.value) || 1,
|
||||||
...extraData,
|
mode: extraData?.theory_craft?.mode || false
|
||||||
theory_craft: {
|
}
|
||||||
...extraData?.theory_craft,
|
})
|
||||||
cycle_count: parseInt(e.target.value) || 1
|
}
|
||||||
}
|
min="1"
|
||||||
})
|
/>
|
||||||
}
|
</label>
|
||||||
min="1"
|
</motion.div>
|
||||||
/>
|
)}
|
||||||
</label>
|
</div>
|
||||||
</motion.div>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Hidden UI */}
|
|
||||||
{extraData?.setting?.hide_ui !== undefined && (
|
|
||||||
<motion.div
|
{/*MULTIPATH CHAR */}
|
||||||
whileHover={{ scale: 1.02 }}
|
<div className="space-y-4">
|
||||||
className="form-control bg-base-200 p-4 rounded-xl shadow"
|
<h3 className="text-lg font-bold flex items-center gap-2">
|
||||||
>
|
{transI18n("multipathCharacter")}
|
||||||
<label className="flex flex-wrap items-center label cursor-pointer justify-start gap-3">
|
<div className="tooltip tooltip-info" data-tip={transI18n("detailMultipathCharacter")}>
|
||||||
{extraData?.setting?.hide_ui
|
<Info className="text-primary" size={20} />
|
||||||
? <EyeOff className="text-warning" size={20}/>
|
</div>
|
||||||
: <Eye className="text-success" size={20}/>
|
</h3>
|
||||||
|
|
||||||
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
|
<label className="flex items-center gap-3">
|
||||||
|
<User className="text-warning" size={20} />
|
||||||
|
<span className="label-text font-semibold">{transI18n("mainPath")}</span>
|
||||||
|
<SelectCustomImage
|
||||||
|
customSet={listAvatar.filter((it) => extraData?.multi_path?.multi_path_main?.includes(Number(it.id))).map((it) => ({
|
||||||
|
value: it.id,
|
||||||
|
label: getNameChar(locale, it),
|
||||||
|
imageUrl: `/icon/${it.baseType.toLowerCase()}.webp`
|
||||||
|
}))}
|
||||||
|
excludeSet={[]}
|
||||||
|
selectedCustomSet={extraData?.multi_path?.main?.toString() || ""}
|
||||||
|
placeholder={transI18n("selectAMainStat")}
|
||||||
|
setSelectedCustomSet={(it) => {
|
||||||
|
if (!it) return
|
||||||
|
setExtraData({
|
||||||
|
...extraData,
|
||||||
|
multi_path: {
|
||||||
|
march_7: extraData?.multi_path?.march_7 || 1001,
|
||||||
|
main: Number(it) || 8001,
|
||||||
|
multi_path_main: extraData?.multi_path?.multi_path_main || [],
|
||||||
|
multi_path_march_7: extraData?.multi_path?.multi_path_march_7 || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</label>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
|
<label className="flex items-center gap-3">
|
||||||
|
<BowArrow className="text-info" size={20} />
|
||||||
|
<span className="label-text font-semibold">{transI18n("march7Path")}</span>
|
||||||
|
<SelectCustomImage
|
||||||
|
customSet={listAvatar.filter((it) => extraData?.multi_path?.multi_path_march_7?.includes(Number(it.id))).map((it) => ({
|
||||||
|
value: it.id,
|
||||||
|
label: getNameChar(locale, it),
|
||||||
|
imageUrl: `/icon/${it.baseType.toLowerCase()}.webp`
|
||||||
|
}))}
|
||||||
|
excludeSet={[]}
|
||||||
|
selectedCustomSet={extraData?.multi_path?.march_7?.toString() || ""}
|
||||||
|
placeholder={transI18n("selectAMainStat")}
|
||||||
|
setSelectedCustomSet={(it) => {
|
||||||
|
if (!it) return
|
||||||
|
setExtraData({
|
||||||
|
...extraData,
|
||||||
|
multi_path: {
|
||||||
|
march_7: Number(it) || 1001,
|
||||||
|
main: extraData?.multi_path?.main || 8001,
|
||||||
|
multi_path_main: extraData?.multi_path?.multi_path_main || [],
|
||||||
|
multi_path_march_7: extraData?.multi_path?.multi_path_march_7 || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* CHALLENGE */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h3 className="text-lg font-bold">{transI18n("challenge")}</h3>
|
||||||
|
|
||||||
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
|
<label className="flex items-center gap-3">
|
||||||
|
<Swords className="text-error" size={20} />
|
||||||
|
<span className="label-text font-semibold">{transI18n("anomalyArbitration")}</span>
|
||||||
|
<div className="tooltip tooltip-info" data-tip={transI18n("detailChallengePeak")}>
|
||||||
|
<Info className="text-primary" size={20} />
|
||||||
|
</div>
|
||||||
|
<select
|
||||||
|
value={extraData?.challenge?.challenge_peak_group_id || ""}
|
||||||
|
className="select select-error"
|
||||||
|
onChange={(e) =>
|
||||||
|
setExtraData({
|
||||||
|
...extraData,
|
||||||
|
challenge: {
|
||||||
|
skip_node: extraData?.challenge?.skip_node || 0,
|
||||||
|
challenge_peak_group_id: parseInt(e.target.value) || 0,
|
||||||
|
challenge_peak_group_id_list: extraData?.challenge?.challenge_peak_group_id_list || []
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
>
|
||||||
|
{PEAKEvent.filter(event => extraData?.challenge?.challenge_peak_group_id_list?.includes(Number(event.id))).map(event => (
|
||||||
|
<option key={event.id} value={event.id}>
|
||||||
|
{getLocaleName(locale, event)} ({event.id})
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
|
<label className="flex items-center gap-3">
|
||||||
|
<SkipForward className="text-warning" size={20} />
|
||||||
|
<span className="label-text font-semibold">{transI18n("skipNode")}</span>
|
||||||
|
<div className="tooltip tooltip-info" data-tip={transI18n("detailSkipNode")}>
|
||||||
|
<Info className="text-primary" size={20} />
|
||||||
|
</div>
|
||||||
|
<select
|
||||||
|
value={extraData?.challenge?.skip_node || "0"}
|
||||||
|
className="select select-warning"
|
||||||
|
onChange={(e) =>
|
||||||
|
setExtraData({
|
||||||
|
...extraData,
|
||||||
|
challenge: {
|
||||||
|
challenge_peak_group_id: extraData?.challenge?.challenge_peak_group_id || 0,
|
||||||
|
challenge_peak_group_id_list: extraData?.challenge?.challenge_peak_group_id_list || [],
|
||||||
|
skip_node: parseInt(e.target.value) || 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<option value="0">{transI18n("disableSkip")}</option>
|
||||||
|
<option value="1">{transI18n("skipNode1")}</option>
|
||||||
|
<option value="2">{transI18n("skipNode2")}</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/*EXTRA FEATURES */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<h3 className="text-lg font-bold">{transI18n("extraFeatures")}</h3>
|
||||||
|
|
||||||
|
{extraData?.setting?.hide_ui !== undefined && (
|
||||||
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
|
<label className="flex flex-wrap items-center cursor-pointer justify-start gap-3">
|
||||||
|
{extraData?.setting?.hide_ui
|
||||||
|
? <EyeOff className="text-warning" size={20} />
|
||||||
|
: <Eye className="text-success" size={20} />
|
||||||
|
}
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="toggle toggle-secondary"
|
className="toggle toggle-secondary"
|
||||||
@@ -82,23 +231,27 @@ export default function ExtraSettingBar() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setExtraData({
|
setExtraData({
|
||||||
...extraData,
|
...extraData,
|
||||||
setting: { ...extraData?.setting, hide_ui: e.target.checked }
|
setting: {
|
||||||
|
hide_ui: e.target.checked,
|
||||||
|
censorship: extraData?.setting?.censorship || false,
|
||||||
|
cm: extraData?.setting?.cm || false,
|
||||||
|
first_person: extraData?.setting?.first_person || false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<span className="label-text font-semibold">{transI18n("hideUI")}</span>
|
<span className="label-text font-semibold">{transI18n("hideUI")}</span>
|
||||||
|
<div className="tooltip tooltip-info" data-tip={transI18n("detailHiddenUi")}>
|
||||||
|
<Info className="text-primary" size={20} />
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Censorship */}
|
|
||||||
{extraData?.setting?.censorship !== undefined && (
|
{extraData?.setting?.censorship !== undefined && (
|
||||||
<motion.div
|
<motion.div className="form-control bg-base-200 p-4 rounded-xl shadow">
|
||||||
whileHover={{ scale: 1.02 }}
|
<label className="flex flex-wrap items-center cursor-pointer justify-start gap-3">
|
||||||
className="form-control bg-base-200 p-4 rounded-xl shadow"
|
<ShieldBan className="text-error" size={20} />
|
||||||
>
|
|
||||||
<label className="flex flex-wrap items-center label cursor-pointer justify-start gap-3">
|
|
||||||
<ShieldBan className="text-error" size={20}/>
|
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="toggle toggle-accent"
|
className="toggle toggle-accent"
|
||||||
@@ -106,15 +259,26 @@ export default function ExtraSettingBar() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setExtraData({
|
setExtraData({
|
||||||
...extraData,
|
...extraData,
|
||||||
setting: { ...extraData?.setting, censorship: e.target.checked }
|
setting: {
|
||||||
|
censorship: e.target.checked,
|
||||||
|
hide_ui: extraData?.setting?.hide_ui || false,
|
||||||
|
cm: extraData?.setting?.cm || false,
|
||||||
|
first_person: extraData?.setting?.first_person || false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<span className="label-text font-semibold">{transI18n("disableCensorship")}</span>
|
<span className="label-text font-semibold">{transI18n("disableCensorship")}</span>
|
||||||
|
<div className="tooltip tooltip-info" data-tip={transI18n("detailDisableCensorship")}>
|
||||||
|
<Info className="text-primary" size={20} />
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export default function PeakBar() {
|
|||||||
<SelectCustomText
|
<SelectCustomText
|
||||||
customSet={PEAKEvent.map((peak) => ({
|
customSet={PEAKEvent.map((peak) => ({
|
||||||
id: peak.id,
|
id: peak.id,
|
||||||
name: `${getLocaleName(locale, peak)} (${peak.id}) `,
|
name: `${getLocaleName(locale, peak)} (${peak.id})`,
|
||||||
}))}
|
}))}
|
||||||
excludeSet={[]}
|
excludeSet={[]}
|
||||||
selectedCustomSet={peak_config.event_id.toString()}
|
selectedCustomSet={peak_config.event_id.toString()}
|
||||||
|
|||||||
@@ -413,19 +413,19 @@ export default function RelicMaker() {
|
|||||||
<div className="grid grid-cols-3 gap-1">
|
<div className="grid grid-cols-3 gap-1">
|
||||||
<button
|
<button
|
||||||
onClick={() => handleSubStatChange(v.affixId, index, v.rollCount + 1, v.stepCount + 0)}
|
onClick={() => handleSubStatChange(v.affixId, index, v.rollCount + 1, v.stepCount + 0)}
|
||||||
className="btn btn-sm bg-white text-slate-800 hover:bg-gray-200 border-0"
|
className="btn btn-sm btn-info border-0"
|
||||||
>
|
>
|
||||||
{calcAffixBonus(subAffixOptions[v.affixId], 0, v.rollCount + 1)}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
{calcAffixBonus(subAffixOptions[v.affixId], 0, v.rollCount + 1)}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleSubStatChange(v.affixId, index, v.rollCount + 1, v.stepCount + 1)}
|
onClick={() => handleSubStatChange(v.affixId, index, v.rollCount + 1, v.stepCount + 1)}
|
||||||
className="btn btn-sm bg-white text-slate-800 hover:bg-gray-200 border-0"
|
className="btn btn-sm btn-info border-0"
|
||||||
>
|
>
|
||||||
{calcAffixBonus(subAffixOptions[v.affixId], v.stepCount + 1, v.rollCount + 1)}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
{calcAffixBonus(subAffixOptions[v.affixId], v.stepCount + 1, v.rollCount + 1)}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleSubStatChange(v.affixId, index, v.rollCount + 1, v.stepCount + 2)}
|
onClick={() => handleSubStatChange(v.affixId, index, v.rollCount + 1, v.stepCount + 2)}
|
||||||
className="btn btn-sm bg-white text-slate-800 hover:bg-gray-200 border-0"
|
className="btn btn-sm btn-info border-0"
|
||||||
>
|
>
|
||||||
{calcAffixBonus(subAffixOptions[v.affixId], v.stepCount + 2, v.rollCount + 1)}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
{calcAffixBonus(subAffixOptions[v.affixId], v.stepCount + 2, v.rollCount + 1)}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
||||||
</button>
|
</button>
|
||||||
@@ -441,19 +441,19 @@ export default function RelicMaker() {
|
|||||||
<div className="grid grid-cols-3 gap-1">
|
<div className="grid grid-cols-3 gap-1">
|
||||||
<button
|
<button
|
||||||
onClick={() => handleSubStatChange(v.affixId, index, Math.max(v.rollCount - 1, 0), Math.max(v.stepCount, 0))}
|
onClick={() => handleSubStatChange(v.affixId, index, Math.max(v.rollCount - 1, 0), Math.max(v.stepCount, 0))}
|
||||||
className="btn btn-sm bg-white text-slate-800 hover:bg-gray-200 border-0"
|
className="btn btn-sm btn-info border-0"
|
||||||
>
|
>
|
||||||
{calcAffixBonus(subAffixOptions[v.affixId], 0, Math.max(v.rollCount - 1, 0))}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
{calcAffixBonus(subAffixOptions[v.affixId], 0, Math.max(v.rollCount - 1, 0))}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleSubStatChange(v.affixId, index, Math.max(v.rollCount - 1, 0), Math.max(v.stepCount - 1, 0))}
|
onClick={() => handleSubStatChange(v.affixId, index, Math.max(v.rollCount - 1, 0), Math.max(v.stepCount - 1, 0))}
|
||||||
className="btn btn-sm bg-white text-slate-800 hover:bg-gray-200 border-0"
|
className="btn btn-sm btn-info border-0"
|
||||||
>
|
>
|
||||||
{calcAffixBonus(subAffixOptions[v.affixId], Math.max(v.stepCount - 1, 0), Math.max(v.rollCount - 1, 0))}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
{calcAffixBonus(subAffixOptions[v.affixId], Math.max(v.stepCount - 1, 0), Math.max(v.rollCount - 1, 0))}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleSubStatChange(v.affixId, index, Math.max(v.rollCount - 1, 0), Math.max(v.stepCount - 2, 0))}
|
onClick={() => handleSubStatChange(v.affixId, index, Math.max(v.rollCount - 1, 0), Math.max(v.stepCount - 2, 0))}
|
||||||
className="btn btn-sm bg-white text-slate-800 hover:bg-gray-200 border-0"
|
className="btn btn-sm btn-info border-0"
|
||||||
>
|
>
|
||||||
{calcAffixBonus(subAffixOptions[v.affixId], Math.max(v.stepCount - 2, 0), Math.max(v.rollCount - 1, 0))}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
{calcAffixBonus(subAffixOptions[v.affixId], Math.max(v.stepCount - 2, 0), Math.max(v.rollCount - 1, 0))}{mappingStats?.[subAffixOptions[v.affixId]?.property]?.unit || ""}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Select, { SingleValue } from 'react-select'
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import useLocaleStore from '@/stores/localeStore'
|
import useLocaleStore from '@/stores/localeStore'
|
||||||
import ParseText from '../parseText'
|
import ParseText from '../parseText'
|
||||||
|
import { themeColors } from '@/constant/constant'
|
||||||
|
|
||||||
export type SelectOption = {
|
export type SelectOption = {
|
||||||
value: string
|
value: string
|
||||||
@@ -12,8 +13,8 @@ export type SelectOption = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SelectCustomProp = {
|
type SelectCustomProp = {
|
||||||
customSet: SelectOption[]
|
customSet: SelectOption[]
|
||||||
excludeSet: SelectOption[]
|
excludeSet: SelectOption[]
|
||||||
selectedCustomSet: string
|
selectedCustomSet: string
|
||||||
placeholder: string
|
placeholder: string
|
||||||
setSelectedCustomSet: (value: string) => void
|
setSelectedCustomSet: (value: string) => void
|
||||||
@@ -21,31 +22,54 @@ type SelectCustomProp = {
|
|||||||
|
|
||||||
export default function SelectCustomImage({ customSet, excludeSet, selectedCustomSet, placeholder, setSelectedCustomSet }: SelectCustomProp) {
|
export default function SelectCustomImage({ customSet, excludeSet, selectedCustomSet, placeholder, setSelectedCustomSet }: SelectCustomProp) {
|
||||||
const options: SelectOption[] = customSet
|
const options: SelectOption[] = customSet
|
||||||
const { locale } = useLocaleStore()
|
const { locale, theme } = useLocaleStore()
|
||||||
|
|
||||||
|
const c = themeColors[theme] || themeColors.winter
|
||||||
|
|
||||||
const customStyles = {
|
const customStyles = {
|
||||||
option: (provided: any) => ({
|
option: (p: any, s: any) => ({
|
||||||
...provided,
|
...p,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px',
|
gap: '8px',
|
||||||
padding: '8px',
|
padding: '8px 12px',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: s.isFocused ? c.bgHover : c.bg,
|
||||||
|
color: c.text,
|
||||||
|
cursor: 'pointer'
|
||||||
}),
|
}),
|
||||||
singleValue: (provided: any) => ({
|
|
||||||
...provided,
|
singleValue: (p: any) => ({
|
||||||
|
...p,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px',
|
gap: '8px',
|
||||||
backgroundColor: 'transparent',
|
color: c.text
|
||||||
}),
|
}),
|
||||||
menuPortal: (provided: any) => ({ ...provided, zIndex: 9999 }),
|
|
||||||
menu: (provided: any) => ({ ...provided, zIndex: 9999 })
|
control: (p: any) => ({
|
||||||
|
...p,
|
||||||
|
backgroundColor: c.bg,
|
||||||
|
borderColor: c.border,
|
||||||
|
boxShadow: 'none'
|
||||||
|
}),
|
||||||
|
|
||||||
|
menu: (p: any) => ({
|
||||||
|
...p,
|
||||||
|
backgroundColor: c.bg,
|
||||||
|
color: c.text,
|
||||||
|
zIndex: 9999
|
||||||
|
}),
|
||||||
|
|
||||||
|
menuPortal: (p: any) => ({
|
||||||
|
...p,
|
||||||
|
zIndex: 9999
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatOptionLabel = (option: SelectOption) => (
|
const formatOptionLabel = (option: SelectOption) => (
|
||||||
<div className="flex items-center gap-1 w-full h-full z-50">
|
<div className="flex items-center gap-1 w-full h-full z-50">
|
||||||
<Image src={option.imageUrl} alt="" width={125} height={125} className="w-8 h-8 object-contain bg-warning-content rounded-full" />
|
<Image src={option.imageUrl} alt="" width={125} height={125} className="w-8 h-8 object-contain bg-warning-content rounded-full" />
|
||||||
<ParseText className='font-bold text-warning-content' text={option.label} locale={locale} />
|
<ParseText className='font-bold' text={option.label} locale={locale} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,14 +77,15 @@ export default function SelectCustomImage({ customSet, excludeSet, selectedCusto
|
|||||||
<Select
|
<Select
|
||||||
options={options.filter(opt => !excludeSet.some(ex => ex.value === opt.value))}
|
options={options.filter(opt => !excludeSet.some(ex => ex.value === opt.value))}
|
||||||
value={options.find(opt => {
|
value={options.find(opt => {
|
||||||
return opt.value === selectedCustomSet}) || null}
|
return opt.value === selectedCustomSet
|
||||||
|
}) || null}
|
||||||
onChange={(selected: SingleValue<SelectOption>) => {
|
onChange={(selected: SingleValue<SelectOption>) => {
|
||||||
setSelectedCustomSet(selected?.value || '')
|
setSelectedCustomSet(selected?.value || '')
|
||||||
}}
|
}}
|
||||||
formatOptionLabel={formatOptionLabel}
|
formatOptionLabel={formatOptionLabel}
|
||||||
styles={customStyles}
|
styles={customStyles}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
className="my-react-select-container"
|
className="my-react-select-container"
|
||||||
classNamePrefix="my-react-select"
|
classNamePrefix="my-react-select"
|
||||||
isSearchable
|
isSearchable
|
||||||
isClearable
|
isClearable
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import Select, { SingleValue } from 'react-select'
|
import Select, { SingleValue } from 'react-select'
|
||||||
import { replaceByParam } from '@/helper'
|
import { replaceByParam } from '@/helper'
|
||||||
|
import useLocaleStore from '@/stores/localeStore'
|
||||||
|
import { themeColors } from '@/constant/constant'
|
||||||
|
|
||||||
export type SelectOption = {
|
export type SelectOption = {
|
||||||
id: string
|
id: string
|
||||||
@@ -20,29 +22,52 @@ type SelectCustomProp = {
|
|||||||
|
|
||||||
export default function SelectCustomText({ customSet, excludeSet, selectedCustomSet, placeholder, setSelectedCustomSet }: SelectCustomProp) {
|
export default function SelectCustomText({ customSet, excludeSet, selectedCustomSet, placeholder, setSelectedCustomSet }: SelectCustomProp) {
|
||||||
const options: SelectOption[] = customSet
|
const options: SelectOption[] = customSet
|
||||||
|
const { theme } = useLocaleStore()
|
||||||
|
const c = themeColors[theme] || themeColors.winter
|
||||||
|
|
||||||
const customStyles = {
|
const customStyles = {
|
||||||
option: (provided: any) => ({
|
option: (p: any, s: any) => ({
|
||||||
...provided,
|
...p,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px',
|
gap: '8px',
|
||||||
padding: '8px',
|
padding: '8px 12px',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: s.isFocused ? c.bgHover : c.bg,
|
||||||
|
color: c.text,
|
||||||
|
cursor: 'pointer'
|
||||||
}),
|
}),
|
||||||
singleValue: (provided: any) => ({
|
|
||||||
...provided,
|
singleValue: (p: any) => ({
|
||||||
|
...p,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '8px'
|
gap: '8px',
|
||||||
|
color: c.text
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
control: (p: any) => ({
|
||||||
|
...p,
|
||||||
|
backgroundColor: c.bg,
|
||||||
|
borderColor: c.border,
|
||||||
|
boxShadow: 'none'
|
||||||
|
}),
|
||||||
|
|
||||||
menuPortal: (provided: any) => ({ ...provided, zIndex: 9999 }),
|
menu: (p: any) => ({
|
||||||
menu: (provided: any) => ({ ...provided, zIndex: 9999 })
|
...p,
|
||||||
|
backgroundColor: c.bg,
|
||||||
|
color: c.text,
|
||||||
|
zIndex: 9999
|
||||||
|
}),
|
||||||
|
|
||||||
|
menuPortal: (p: any) => ({
|
||||||
|
...p,
|
||||||
|
zIndex: 9999
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const formatOptionLabel = (option: SelectOption) => (
|
const formatOptionLabel = (option: SelectOption) => (
|
||||||
<div className="flex flex-col gap-1 w-full h-full z-50 text-warning-content ">
|
<div className="flex flex-col gap-1 w-full h-full z-50">
|
||||||
<div
|
<div
|
||||||
className="font-bold text-lg"
|
className="font-bold text-lg"
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const ThemeProvider = ({ children }: PropsWithChildren) => {
|
|||||||
const storedTheme = localStorage.getItem("theme");
|
const storedTheme = localStorage.getItem("theme");
|
||||||
if (storedTheme) setTheme(storedTheme);
|
if (storedTheme) setTheme(storedTheme);
|
||||||
}
|
}
|
||||||
}, []);
|
}, [setTheme]);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const changeTheme = (nextTheme: string | null) => {
|
const changeTheme = (nextTheme: string | null) => {
|
||||||
|
|||||||
@@ -169,3 +169,31 @@ export const ratioStats = [
|
|||||||
"SpeedAddedRatio",
|
"SpeedAddedRatio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const themeColors: Record<string, { bg: string; bgHover: string; text: string; border: string }> = {
|
||||||
|
winter: {
|
||||||
|
bg: '#ffffff',
|
||||||
|
bgHover: '#f1f5f9',
|
||||||
|
text: '#3a4f6b',
|
||||||
|
border: '#cbd5e1'
|
||||||
|
},
|
||||||
|
night: {
|
||||||
|
bg: '#1d232a',
|
||||||
|
bgHover: '#2a323c',
|
||||||
|
text: '#cbcdd1',
|
||||||
|
border: '#3f3f46'
|
||||||
|
},
|
||||||
|
cupcake: {
|
||||||
|
bg: '#faf7f5',
|
||||||
|
bgHover: '#f3eae6',
|
||||||
|
text: '#281333',
|
||||||
|
border: '#e5d3cb'
|
||||||
|
},
|
||||||
|
coffee: {
|
||||||
|
bg: '#20161f',
|
||||||
|
bgHover: '#2a1d29',
|
||||||
|
text: '#c4a051',
|
||||||
|
border: '#3a2a36'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
export interface ExtraData {
|
export interface ExtraData {
|
||||||
theory_craft: {
|
theory_craft?: {
|
||||||
hp: Record<string, number[]>
|
hp: Record<string, number[]>
|
||||||
cycle_count: number
|
cycle_count: number
|
||||||
mode: boolean
|
mode: boolean
|
||||||
}
|
}
|
||||||
setting: {
|
setting?: {
|
||||||
censorship: boolean
|
censorship: boolean
|
||||||
cm: boolean
|
cm: boolean
|
||||||
first_person: boolean
|
first_person: boolean
|
||||||
hide_ui: boolean
|
hide_ui: boolean
|
||||||
}
|
}
|
||||||
challenge: {
|
challenge?: {
|
||||||
skip_node: number
|
skip_node: number
|
||||||
challenge_peak_group_id: number
|
challenge_peak_group_id: number
|
||||||
challenge_peak_group_id_list: number[]
|
challenge_peak_group_id_list: number[]
|
||||||
}
|
}
|
||||||
multi_path: {
|
multi_path?: {
|
||||||
main: number
|
main: number
|
||||||
march_7: number
|
march_7: number
|
||||||
multi_path_main: number[]
|
multi_path_main: number[]
|
||||||
|
|||||||
Reference in New Issue
Block a user