diff --git a/apps/frontend/src/app/App.tsx b/apps/frontend/src/app/App.tsx
index f6afb280d4..ea62d966f4 100644
--- a/apps/frontend/src/app/App.tsx
+++ b/apps/frontend/src/app/App.tsx
@@ -146,7 +146,7 @@ function Content() {
-
+
boolean)
hideDesc?: boolean
disabled?: boolean
+ bgt?: CardBackgroundColor
}
export default function ConditionalDisplay({
@@ -20,6 +22,7 @@ export default function ConditionalDisplay({
hideHeader = false,
hideDesc = false,
disabled = false,
+ bgt = 'normal',
}: ConditionalDisplayProps) {
const { data } = useContext(DataContext)
let fields
@@ -35,14 +38,14 @@ export default function ConditionalDisplay({
})
}
return (
-
+
{!evalIfFunc(hideHeader, conditional) && (
)}
- {fields && }
-
+ {fields && }
+
)
}
diff --git a/apps/frontend/src/app/Components/DocumentDisplay.tsx b/apps/frontend/src/app/Components/DocumentDisplay.tsx
index 44f0fb1544..00fbea7be7 100644
--- a/apps/frontend/src/app/Components/DocumentDisplay.tsx
+++ b/apps/frontend/src/app/Components/DocumentDisplay.tsx
@@ -1,3 +1,5 @@
+import type { CardBackgroundColor } from '@genshin-optimizer/common/ui'
+import { CardThemed } from '@genshin-optimizer/common/ui'
import { Box, Divider, Typography } from '@mui/material'
import { useContext } from 'react'
import { DataContext } from '../Context/DataContext'
@@ -8,7 +10,6 @@ import type {
IDocumentText,
} from '../Types/sheet'
import { evalIfFunc } from '../Util/Util'
-import CardDark from './Card/CardDark'
import CardHeaderCustom from './Card/CardHeaderCustom'
import ConditionalDisplay from './Conditional/ConditionalDisplay'
import FieldsDisplay from './FieldDisplay'
@@ -20,6 +21,7 @@ type DocumentDisplayProps = {
hideDesc?: boolean
hideHeader?: boolean | ((section: DocumentSection) => boolean)
disabled?: boolean
+ bgt?: CardBackgroundColor
}
export default function DocumentDisplay({
@@ -28,6 +30,7 @@ export default function DocumentDisplay({
hideDesc = false,
hideHeader = false,
disabled = false,
+ bgt = 'normal',
}: DocumentDisplayProps) {
const { data } = useContext(DataContext)
if (!sections.length) return null
@@ -44,6 +47,7 @@ export default function DocumentDisplay({
hideDesc={hideDesc}
hideHeader={hideHeader}
disabled={disabled}
+ bgt={bgt}
/>
)
})
@@ -61,11 +65,13 @@ function SectionDisplay({
hideDesc = false,
hideHeader = false,
disabled = false,
+ bgt = 'normal',
}: {
section: DocumentSection
hideDesc?: boolean
hideHeader?: boolean | ((section: DocumentSection) => boolean)
disabled?: boolean
+ bgt?: CardBackgroundColor
}) {
if ('fields' in section) {
return (
@@ -73,6 +79,7 @@ function SectionDisplay({
section={section}
hideDesc={hideDesc}
hideHeader={hideHeader}
+ bgt={bgt}
/>
)
} else if ('states' in section) {
@@ -82,6 +89,7 @@ function SectionDisplay({
hideDesc={hideDesc}
hideHeader={hideHeader}
disabled={disabled}
+ bgt={bgt}
/>
)
} /* if ("text" in section) */ else {
@@ -93,13 +101,15 @@ function FieldsSectionDisplay({
section,
hideDesc,
hideHeader,
+ bgt = 'normal',
}: {
section: IDocumentFields
hideDesc?: boolean
hideHeader?: boolean | ((section: DocumentSection) => boolean)
+ bgt?: CardBackgroundColor
}) {
return (
-
+
{!evalIfFunc(hideHeader, section) && section.header && (
)}
-
-
+
+
)
}
diff --git a/apps/frontend/src/app/Components/FieldDisplay.tsx b/apps/frontend/src/app/Components/FieldDisplay.tsx
index 440ff3acfb..aaa2a130a7 100644
--- a/apps/frontend/src/app/Components/FieldDisplay.tsx
+++ b/apps/frontend/src/app/Components/FieldDisplay.tsx
@@ -1,9 +1,10 @@
+import type { CardBackgroundColor } from '@genshin-optimizer/common/ui'
import { valueString } from '@genshin-optimizer/common/util'
import type { AmpReactionKey } from '@genshin-optimizer/gi/consts'
import { allAmpReactionKeys } from '@genshin-optimizer/gi/consts'
import { Groups } from '@mui/icons-material'
import HelpIcon from '@mui/icons-material/Help'
-import type { ListProps, Palette, PaletteColor } from '@mui/material'
+import type { ListProps, PaletteColor } from '@mui/material'
import {
Box,
Divider,
@@ -24,9 +25,15 @@ import AmpReactionModeText from './AmpReactionModeText'
import BootstrapTooltip from './BootstrapTooltip'
import ColorText from './ColoredText'
-export default function FieldsDisplay({ fields }: { fields: IFieldDisplay[] }) {
+export default function FieldsDisplay({
+ fields,
+ bgt = 'normal',
+}: {
+ fields: IFieldDisplay[]
+ bgt?: CardBackgroundColor
+}) {
return (
-
+
{fields.map((field, i) => (
))}
@@ -213,25 +220,27 @@ export function NodeFieldDisplayText({ node }: { node: NodeDisplay }) {
)
}
export interface FieldDisplayListProps extends ListProps {
- light?: keyof Palette
- dark?: keyof Palette
+ bgt?: CardBackgroundColor
palletOption?: keyof PaletteColor
}
export const FieldDisplayList = styled(List)(
- ({
- theme,
- light = 'contentNormal',
- dark = 'contentDark',
- palletOption = 'main',
- }) => ({
- borderRadius: theme.shape.borderRadius,
- overflow: 'hidden',
- margin: 0,
- '> .MuiListItem-root:nth-of-type(even)': {
- backgroundColor: (theme.palette[light] as PaletteColor)[palletOption],
- },
- '> .MuiListItem-root:nth-of-type(odd)': {
- backgroundColor: (theme.palette[dark] as PaletteColor)[palletOption],
- },
- })
+ ({ theme, bgt = 'normal' }) => {
+ const palette =
+ bgt === 'light'
+ ? 'contentLight'
+ : bgt === 'dark'
+ ? 'contentDark'
+ : 'contentNormal'
+ return {
+ borderRadius: theme.shape.borderRadius,
+ overflow: 'hidden',
+ margin: 0,
+ '> .MuiListItem-root:nth-of-type(even)': {
+ backgroundColor: (theme.palette[palette] as PaletteColor)['main'],
+ },
+ '> .MuiListItem-root:nth-of-type(odd)': {
+ backgroundColor: (theme.palette[palette] as PaletteColor)['dark'],
+ },
+ }
+ }
)
diff --git a/apps/frontend/src/app/Components/Weapon/WeaponFullCard.tsx b/apps/frontend/src/app/Components/Weapon/WeaponFullCard.tsx
index 9a8e2da3c8..2f766f9a13 100644
--- a/apps/frontend/src/app/Components/Weapon/WeaponFullCard.tsx
+++ b/apps/frontend/src/app/Components/Weapon/WeaponFullCard.tsx
@@ -1,3 +1,5 @@
+import type { CardBackgroundColor } from '@genshin-optimizer/common/ui'
+import { CardThemed } from '@genshin-optimizer/common/ui'
import { weaponAsset } from '@genshin-optimizer/gi/assets'
import type { ICachedWeapon } from '@genshin-optimizer/gi/db'
import { useWeapon } from '@genshin-optimizer/gi/db-ui'
@@ -10,14 +12,19 @@ import { uiInput as input } from '../../Formula'
import { computeUIData, dataObjForWeapon } from '../../Formula/api'
import type { NodeDisplay } from '../../Formula/uiData'
import { nodeVStr } from '../../Formula/uiData'
-import CardDark from '../Card/CardDark'
import SqBadge from '../SqBadge'
export default function WeaponFullCard({ weaponId }: { weaponId: string }) {
const weapon = useWeapon(weaponId)
if (!weapon) return null
return
}
-export function WeaponFullCardObj({ weapon }: { weapon: IWeapon }) {
+export function WeaponFullCardObj({
+ weapon,
+ bgt = 'normal',
+}: {
+ weapon: IWeapon
+ bgt?: CardBackgroundColor
+}) {
const weaponSheet = weapon?.key && getWeaponSheet(weapon.key)
const UIData = useMemo(
() =>
@@ -31,7 +38,7 @@ export function WeaponFullCardObj({ weapon }: { weapon: IWeapon }) {
)
if (!weapon || !weaponSheet || !UIData) return null
return (
-
+
-
+
)
}
function WeaponStat({ node }: { node: NodeDisplay }) {
diff --git a/apps/frontend/src/app/ErrorBoundary/index.tsx b/apps/frontend/src/app/ErrorBoundary/index.tsx
index 4cd4a1fa9f..4d0b696ee3 100644
--- a/apps/frontend/src/app/ErrorBoundary/index.tsx
+++ b/apps/frontend/src/app/ErrorBoundary/index.tsx
@@ -22,6 +22,7 @@ import { Trans, withTranslation } from 'react-i18next'
import CardLight from '../Components/Card/CardLight'
import DatabaseCard from '../PageSettings/DatabaseCard'
import SpaghettiCode from './SpaghettiCode.png'
+import { isDev } from '../Util/Util'
interface Props extends WithTranslation {
children?: ReactNode
@@ -38,6 +39,7 @@ class ErrorBoundary extends Component {
public static getDerivedStateFromError(error: Error): State {
// Update state so the next render will show the fallback UI.
+ if (isDev) return { error: undefined }
return { error }
}
diff --git a/apps/frontend/src/app/PageTeam/CharacterDisplay/Content.tsx b/apps/frontend/src/app/PageTeam/CharacterDisplay/Content.tsx
index 3e1c93ef77..2a71631c8a 100644
--- a/apps/frontend/src/app/PageTeam/CharacterDisplay/Content.tsx
+++ b/apps/frontend/src/app/PageTeam/CharacterDisplay/Content.tsx
@@ -4,7 +4,6 @@ import type { CharacterKey } from '@genshin-optimizer/gi/consts'
import BarChartIcon from '@mui/icons-material/BarChart'
import CalculateIcon from '@mui/icons-material/Calculate'
import FactCheckIcon from '@mui/icons-material/FactCheck'
-import GroupsIcon from '@mui/icons-material/Groups'
import PersonIcon from '@mui/icons-material/Person'
import ScienceIcon from '@mui/icons-material/Science'
import TrendingUpIcon from '@mui/icons-material/TrendingUp'
@@ -31,7 +30,6 @@ import StatModal from './StatModal'
import TabBuild from './Tabs/TabOptimize'
import TabOverview from './Tabs/TabOverview'
import TabTalent from './Tabs/TabTalent'
-import TabTeambuffs from './Tabs/TabTeambuffs'
import TabTheorycraft from './Tabs/TabTheorycraft'
import TabUpopt from './Tabs/TabUpgradeOpt'
@@ -99,7 +97,6 @@ function CharacterPanel() {
} />
)}
} />
- } />
{!isTCBuild && (
} />
)}
@@ -159,13 +156,6 @@ function TabNav({
component={RouterLink}
to={`${characterKey}/talent`}
/>
- }
- component={RouterLink}
- to={`${characterKey}/teambuffs`}
- />
{!isTCBuild && (
+
{name}
-
- {buildIds.length} Builds
-
-
- {buildTcIds.length} TC Builds
-
+
+
+ {buildIds.length} Builds
+
+
+ {buildTcIds.length} TC Builds
+
+
}
{...dropdownBtnProps}
diff --git a/apps/frontend/src/app/PageTeam/CharacterDisplay/Tabs/TabTeambuffs.tsx b/apps/frontend/src/app/PageTeam/TeamSetting/TeamComponents.tsx
similarity index 56%
rename from apps/frontend/src/app/PageTeam/CharacterDisplay/Tabs/TabTeambuffs.tsx
rename to apps/frontend/src/app/PageTeam/TeamSetting/TeamComponents.tsx
index 3ba313d811..23ed160f63 100644
--- a/apps/frontend/src/app/PageTeam/CharacterDisplay/Tabs/TabTeambuffs.tsx
+++ b/apps/frontend/src/app/PageTeam/TeamSetting/TeamComponents.tsx
@@ -1,9 +1,11 @@
import { CardThemed, SqBadge } from '@genshin-optimizer/common/ui'
+import { objPathValue } from '@genshin-optimizer/common/util'
import { artifactAsset } from '@genshin-optimizer/gi/assets'
import {
useBuildTc,
useCharacter,
useDatabase,
+ useTeam,
useTeamChar,
} from '@genshin-optimizer/gi/db-ui'
import { ArtifactSetName } from '@genshin-optimizer/gi/ui'
@@ -18,62 +20,31 @@ import {
} from '@mui/material'
import { Suspense, useContext, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
-import { useMatch, useNavigate } from 'react-router-dom'
-import CardLight from '../../../Components/Card/CardLight'
-import { CharacterCardEquipmentRow } from '../../../Components/Character/CharacterCard/CharacterCardEquipmentRow'
+import CardLight from '../../Components/Card/CardLight'
+import { CharacterCardEquipmentRow } from '../../Components/Character/CharacterCard/CharacterCardEquipmentRow'
import {
CharacterCardHeader,
CharacterCardHeaderContent,
-} from '../../../Components/Character/CharacterCard/CharacterCardHeader'
-import ColorText from '../../../Components/ColoredText'
-import DocumentDisplay from '../../../Components/DocumentDisplay'
-import { NodeFieldDisplay } from '../../../Components/FieldDisplay'
-import ImgIcon from '../../../Components/Image/ImgIcon'
-import { InfoTooltipInline } from '../../../Components/InfoTooltip'
-import { WeaponFullCardObj } from '../../../Components/Weapon/WeaponFullCard'
-import type { CharacterContextObj } from '../../../Context/CharacterContext'
-import { CharacterContext } from '../../../Context/CharacterContext'
-import type { dataContextObj } from '../../../Context/DataContext'
-import { DataContext } from '../../../Context/DataContext'
-import type { TeamCharacterContextObj } from '../../../Context/TeamCharacterContext'
-import { TeamCharacterContext } from '../../../Context/TeamCharacterContext'
-import { dataSetEffects, getArtSheet } from '../../../Data/Artifacts'
-import type CharacterSheet from '../../../Data/Characters/CharacterSheet'
-import { resonanceSheets } from '../../../Data/Resonance'
-import { input } from '../../../Formula'
-import type { NodeDisplay } from '../../../Formula/uiData'
-import { objPathValue } from '../../../Util/Util'
+} from '../../Components/Character/CharacterCard/CharacterCardHeader'
+import ColorText from '../../Components/ColoredText'
+import DocumentDisplay from '../../Components/DocumentDisplay'
+import { NodeFieldDisplay } from '../../Components/FieldDisplay'
+import ImgIcon from '../../Components/Image/ImgIcon'
+import { InfoTooltipInline } from '../../Components/InfoTooltip'
+import { WeaponFullCardObj } from '../../Components/Weapon/WeaponFullCard'
+import type { CharacterContextObj } from '../../Context/CharacterContext'
+import { CharacterContext } from '../../Context/CharacterContext'
+import type { dataContextObj } from '../../Context/DataContext'
+import { DataContext } from '../../Context/DataContext'
+import type { TeamCharacterContextObj } from '../../Context/TeamCharacterContext'
+import { TeamCharacterContext } from '../../Context/TeamCharacterContext'
+import { dataSetEffects, getArtSheet } from '../../Data/Artifacts'
+import type CharacterSheet from '../../Data/Characters/CharacterSheet'
+import { resonanceSheets } from '../../Data/Resonance'
+import { input } from '../../Formula'
+import type { NodeDisplay } from '../../Formula/uiData'
-export default function TabTeambuffs() {
- const {
- team: { teamCharIds },
- teamCharId,
- } = useContext(TeamCharacterContext)
- return (
-
-
-
-
-
-
- {(teamCharIds.filter((id) => id && id !== teamCharId) as string[]).map(
- (id) => (
-
-
-
- )
- )}
-
-
- )
-}
-function TeamBuffDisplay() {
+export function TeamBuffDisplay() {
const { data, oldData } = useContext(DataContext)
const teamBuffs = data.getTeamBuff() as any
const nodes: Array<[string[], NodeDisplay]> = []
@@ -117,12 +88,11 @@ function TeamBuffDisplay() {
)
}
-function ResonanceDisplay() {
+export function ResonanceDisplay({ teamId }: { teamId: string }) {
const { t } = useTranslation('page_character')
const { data } = useContext(DataContext)
- const {
- team: { teamCharIds },
- } = useContext(TeamCharacterContext)
+
+ const { teamCharIds } = useTeam(teamId)!
const teamCount = teamCharIds.reduce((a, t) => a + (t ? 1 : 0), 0)
return (
<>
@@ -169,23 +139,22 @@ function ResonanceDisplay() {
>
)
}
-function TeammateDisplay({ teamCharId }: { teamCharId: string }) {
- const { teamData } = useContext(DataContext)
- const navigate = useNavigate()
- const { teamId, team } = useContext(TeamCharacterContext)
+export function TeammateDisplay({
+ teamCharId,
+ dataContextValue,
+ teamId,
+}: {
+ teamCharId: string
+ teamId: string
+ dataContextValue: dataContextObj
+}) {
+ const { teamData } = dataContextValue
+ const team = useTeam(teamId)!
const teamChar = useTeamChar(teamCharId)!
const teamMateKey = teamChar?.key
const character = useCharacter(teamMateKey)!
const { key: characterKey } = character
- const {
- params: { tab = '' },
- } = useMatch({ path: '/teams/:teamId/:characterKey/:tab', end: false }) ?? {
- params: { tab: '' },
- }
-
- const onClick = () => navigate(`/teams/${teamId}/${characterKey}/${tab}`)
-
const dataBundle = teamData[teamMateKey]
const teammateCharacterContext: TeamCharacterContextObj | undefined = useMemo(
() =>
@@ -215,57 +184,37 @@ function TeammateDisplay({ teamCharId }: { teamCharId: string }) {
},
[dataBundle, teamData]
)
+ if (
+ !teamMateKey ||
+ !teammateCharacterContext ||
+ !teamMateDataContext ||
+ !characterContext
+ )
+ return null
return (
-
- {teamMateKey && teammateCharacterContext && (
-
- {teamMateDataContext && (
-
- {characterContext && (
-
-
- }
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )}
-
- )}
-
- )}
-
+
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
)
}
function EquipmentRow() {
@@ -283,7 +232,7 @@ function TcEquipmentRow() {
artifact: { sets },
} = useBuildTc(buildTcId)!
return (
-
+
)
}
-function CharacterCardWeaponFull() {
+function CharacterCardWeaponFull({ teamCharId }: { teamCharId: string }) {
const { data } = useContext(DataContext)
- const { teamCharId } = useContext(TeamCharacterContext)
const database = useDatabase()
const weapon = useMemo(() => {
- const weaponId = data.get(input.weapon.id).value?.toString() ?? ''
- if (weaponId) return database.weapons.get(weaponId)
+ const weaponId = data.get(input.weapon.id).value?.toString() ?? 'invalid'
+
+ if (weaponId && weaponId !== 'invalid')
+ return database.weapons.get(weaponId)
else return database.teamChars.getLoadoutWeapon(teamCharId) // TC build
}, [database, data, teamCharId])
+ console.log({ weapon })
if (!weapon) return null
- return
+ return
}
function CharArtifactCondDisplay() {
const { data } = useContext(DataContext)
@@ -332,7 +283,7 @@ function CharArtifactCondDisplay() {
[data]
)
if (!sections) return null
- return
+ return
}
function CharWeaponCondDisplay() {
const {
@@ -341,7 +292,13 @@ function CharWeaponCondDisplay() {
const { teamData } = useContext(DataContext)
const weaponSheet = teamData[charKey]!.weaponSheet
if (!weaponSheet.document) return null
- return
+ return (
+
+ )
}
function CharTalentCondDisplay() {
const {
@@ -353,5 +310,5 @@ function CharTalentCondDisplay() {
(sts) => sts.sections
)
if (!sections) return null
- return
+ return
}
diff --git a/apps/frontend/src/app/PageTeam/TeamSettingElement.tsx b/apps/frontend/src/app/PageTeam/TeamSetting/index.tsx
similarity index 64%
rename from apps/frontend/src/app/PageTeam/TeamSettingElement.tsx
rename to apps/frontend/src/app/PageTeam/TeamSetting/index.tsx
index 211e70d1cb..70cf3dfec2 100644
--- a/apps/frontend/src/app/PageTeam/TeamSettingElement.tsx
+++ b/apps/frontend/src/app/PageTeam/TeamSetting/index.tsx
@@ -8,7 +8,8 @@ import { useDBMeta, useDatabase } from '@genshin-optimizer/gi/db-ui'
import { CharacterName } from '@genshin-optimizer/gi/ui'
import AddIcon from '@mui/icons-material/Add'
import CloseIcon from '@mui/icons-material/Close'
-import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline'
+import GroupsIcon from '@mui/icons-material/Groups'
+import SettingsIcon from '@mui/icons-material/Settings'
import {
Alert,
Box,
@@ -16,19 +17,31 @@ import {
CardContent,
CardHeader,
Divider,
+ Grid,
TextField,
Typography,
} from '@mui/material'
import { Suspense, useDeferredValue, useEffect, useState } from 'react'
-import CharacterSelectionModal from '../Components/Character/CharacterSelectionModal'
-import CloseButton from '../Components/CloseButton'
-import CharIconSide from '../Components/Image/CharIconSide'
-import { LoadoutDropdown } from './LoadoutDropdown'
-import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'
-import GroupsIcon from '@mui/icons-material/Groups'
+import CharacterSelectionModal from '../../Components/Character/CharacterSelectionModal'
+import CloseButton from '../../Components/CloseButton'
+import CharIconSide from '../../Components/Image/CharIconSide'
+import type { dataContextObj } from '../../Context/DataContext'
+import { DataContext } from '../../Context/DataContext'
+import { LoadoutDropdown } from '../LoadoutDropdown'
+import {
+ ResonanceDisplay,
+ TeamBuffDisplay,
+ TeammateDisplay,
+} from './TeamComponents'
// TODO: Translation
-export default function TeamSettingElement({ teamId }: { teamId: string }) {
+export default function TeamSetting({
+ teamId,
+ dataContextValue,
+}: {
+ teamId: string
+ dataContextValue?: dataContextObj
+}) {
const database = useDatabase()
const team = database.teams.get(teamId)!
const noChars = team.teamCharIds.every((id) => !id)
@@ -71,14 +84,18 @@ export default function TeamSettingElement({ teamId }: { teamId: string }) {
color="info"
sx={{ flexGrow: 1 }}
startIcon={}
- endIcon={}
+ endIcon={}
onClick={() => setOpen((open) => !open)}
>
{team.name}
- setOpen(false)}>
+ setOpen(false)}
+ containerProps={{ maxWidth: 'xl' }}
+ >
-
+
>
)
}
-function TeamCharacterSelector({ teamId }: { teamId: string }) {
+function TeamCharacterSelector({
+ teamId,
+ dataContextValue,
+}: {
+ teamId: string
+ dataContextValue?: dataContextObj
+}) {
const database = useDatabase()
const team = database.teams.get(teamId)!
const { teamCharIds } = team
@@ -180,28 +206,45 @@ function TeamCharacterSelector({ teamId }: { teamId: string }) {
onSelect={onSelect}
/>
- {teamCharIds.map((teamCharId, ind) =>
- teamCharId ? (
- setCharSelectIndex(ind)}
- />
- ) : (
-
- )
- )}
+
+
+ {dataContextValue && (
+
+
+
+
+ )}
+
+ {teamCharIds.map((teamCharId, ind) => (
+
+ {teamCharId ? (
+ setCharSelectIndex(ind)}
+ dataContextValue={dataContextValue}
+ />
+ ) : (
+
+ )}
+
+ ))}
+
>
)
}
@@ -209,11 +252,13 @@ function CharSelButton({
index,
teamId,
teamCharId,
+ dataContextValue,
onClickChar,
}: {
index: number
teamId: string
teamCharId: string
+ dataContextValue?: dataContextObj
onClickChar: () => void
}) {
const database = useDatabase()
@@ -238,35 +283,43 @@ function CharSelButton({
team.teamCharIds[index] = undefined
})
return (
-
-
-
- }
- >
-
-
-
- {!!index && (
- }
- color="info"
- >
- Active
-
- )}
-
-
-
-
+ //
+ //
+
+
+ }
+ >
+
+
+
+
+
+ {index ? (
+
+ ) : (
+
+ )}
+ {dataContextValue && (
+
+ )}
+
)
}
diff --git a/apps/frontend/src/app/PageTeam/index.tsx b/apps/frontend/src/app/PageTeam/index.tsx
index acc0baa463..970059d3fb 100644
--- a/apps/frontend/src/app/PageTeam/index.tsx
+++ b/apps/frontend/src/app/PageTeam/index.tsx
@@ -1,11 +1,7 @@
import { CardThemed } from '@genshin-optimizer/common/ui'
import type { CharacterKey } from '@genshin-optimizer/gi/consts'
import { charKeyToLocGenderedCharKey } from '@genshin-optimizer/gi/consts'
-import type {
- GeneratedBuild,
- Team,
- TeamCharacter,
-} from '@genshin-optimizer/gi/db'
+import type { GeneratedBuild } from '@genshin-optimizer/gi/db'
import {
useCharacter,
useDBMeta,
@@ -40,13 +36,13 @@ import {
type TeamCharacterContextObj,
} from '../Context/TeamCharacterContext'
import { getCharSheet } from '../Data/Characters'
-import useTeamData from '../ReactHooks/useTeamData'
+import { useTeamDataNoContext } from '../ReactHooks/useTeamData'
import useTitle from '../ReactHooks/useTitle'
import { shouldShowDevComponents } from '../Util/Util'
import Content from './CharacterDisplay/Content'
-import TeamCharacterSelector from './TeamCharacterSelector'
-import TeamSettingElement from './TeamSettingElement'
import { EnemyEditorElement } from './EnemyEditorElement'
+import TeamCharacterSelector from './TeamCharacterSelector'
+import TeamSetting from './TeamSetting'
export default function PageTeam() {
const navigate = useNavigate()
@@ -73,10 +69,14 @@ export default function PageTeam() {
)
}
+
const tabs = ['overview', 'talent', 'teambuffs', 'optimize']
if (shouldShowDevComponents) tabs.push('upopt')
const tabsTc = ['overview', 'talent', 'teambuffs']
-
+const fallback =
+// Stored per teamCharId
+const chartDataAll: Record = {}
+const graphBuildAll: Record = {}
function Page({ teamId, onClose }: { teamId: string; onClose?: () => void }) {
const navigate = useNavigate()
const { silly } = useContext(SillyContext)
@@ -158,11 +158,35 @@ function Page({ teamId, onClose }: { teamId: string; onClose?: () => void }) {
)
)
+ const teamCharacterContextValue: TeamCharacterContextObj | undefined =
+ useMemo(() => {
+ if (!teamCharId || !teamChar) return undefined
+ return {
+ teamId,
+ team,
+ teamCharId,
+ teamChar,
+ }
+ }, [teamId, team, teamCharId, teamChar])
+
+ const teamData = useTeamDataNoContext(teamId, teamCharId ?? '')
+ const { target: charUIData } =
+ (characterKey && teamData?.[characterKey]) ?? {}
+
+ const dataContextValue: dataContextObj | undefined = useMemo(() => {
+ if (!teamData || !charUIData) return undefined
+ return {
+ data: charUIData,
+ teamData,
+ oldData: undefined,
+ }
+ }, [charUIData, teamData])
+
return (
-
+
@@ -172,53 +196,31 @@ function Page({ teamId, onClose }: { teamId: string; onClose?: () => void }) {
characterKey={characterKey}
tab={tab}
/>
- {characterKey && team && teamChar && teamCharId && (
-
- )}
+ {teamCharacterContextValue ? (
+ dataContextValue ? (
+
+
+
+
+
+ ) : (
+ fallback
+ )
+ ) : null}
)
}
-// Stored per teamCharId
-const chartDataAll: Record = {}
-const graphBuildAll: Record = {}
-function PageContent({
- characterKey,
- teamCharId,
- teamChar,
- teamId,
- team,
- tab,
-}: {
- characterKey: CharacterKey
- teamCharId: string
- teamChar: TeamCharacter
- teamId: string
- team: Team
- tab: string
-}) {
+function InnerContent({ tab }: { tab: string }) {
const { gender } = useDBMeta()
- const characterSheet = getCharSheet(characterKey, gender)
- const character = useCharacter(characterKey)
- const teamCharacterContextValue: TeamCharacterContextObj | undefined =
- useMemo(() => {
- if (!character || !characterSheet) return undefined
- return {
- teamId,
- team,
- teamCharId,
- teamChar,
- character,
- characterSheet,
- }
- }, [teamId, team, teamCharId, teamChar, character, characterSheet])
+ const {
+ teamCharId,
+ teamChar: { key: characterKey },
+ } = useContext(TeamCharacterContext)
+ const characterSheet = characterKey
+ ? getCharSheet(characterKey, gender)
+ : undefined
+ const character = useCharacter(characterKey as CharacterKey)
const CharacterContextValue: CharacterContextObj | undefined = useMemo(
() =>
character &&
@@ -228,6 +230,7 @@ function PageContent({
},
[character, characterSheet]
)
+
const [chartData, setChartDataState] = useState(
chartDataAll[teamCharId]
)
@@ -238,6 +241,7 @@ function PageContent({
setChartDataState(chartDataAll[teamCharId])
setGraphBuildState(graphBuildAll[teamCharId])
}, [teamCharId, setChartDataState, setGraphBuildState])
+
const graphContextValue: GraphContextObj | undefined = useMemo(() => {
return {
chartData,
@@ -258,44 +262,14 @@ function PageContent({
setChartDataState,
setGraphBuildState,
])
- return teamCharacterContextValue &&
- graphContextValue &&
- CharacterContextValue ? (
-
-
-
-
-
-
-
-
-
-
-
- ) : (
-
- )
-}
-function DataContextWrapper({ children }: { children: React.ReactNode }) {
- const {
- teamChar: { key: characterKey },
- } = useContext(TeamCharacterContext)
- const teamData = useTeamData()
- const { target: charUIData } = teamData?.[characterKey] ?? {}
-
- const dataContextValue: dataContextObj | undefined = useMemo(() => {
- if (!teamData || !charUIData) return undefined
- return {
- data: charUIData,
- teamData,
- oldData: undefined,
- }
- }, [charUIData, teamData])
- if (!dataContextValue)
- return
+ if (!CharacterContextValue) return fallback
return (
-
- {children}
-
+
+
+
+
+
+
+
)
}
diff --git a/apps/frontend/src/app/ReactHooks/useTeamData.tsx b/apps/frontend/src/app/ReactHooks/useTeamData.tsx
index 209c730a33..b76985b0c5 100644
--- a/apps/frontend/src/app/ReactHooks/useTeamData.tsx
+++ b/apps/frontend/src/app/ReactHooks/useTeamData.tsx
@@ -42,6 +42,21 @@ export default function useTeamData(
): TeamData | undefined {
const { teamId, teamCharId: overrideTeamCharId } =
useContext(TeamCharacterContext)
+ return useTeamDataNoContext(
+ teamId,
+ overrideTeamCharId,
+ mainStatAssumptionLevel,
+ overrideArt,
+ overrideWeapon
+ )
+}
+export function useTeamDataNoContext(
+ teamId: string,
+ overrideTeamCharId: string,
+ mainStatAssumptionLevel = 0,
+ overrideArt?: ICachedArtifact[] | Data,
+ overrideWeapon?: ICachedWeapon
+): TeamData | undefined {
const database = useDatabase()
const [dbDirty, setDbDirty] = useForceUpdate()
const dbDirtyDeferred = useDeferredValue(dbDirty)
diff --git a/libs/common/ui/src/components/Card/CardThemed.tsx b/libs/common/ui/src/components/Card/CardThemed.tsx
index 2165a18e7b..a678f15855 100644
--- a/libs/common/ui/src/components/Card/CardThemed.tsx
+++ b/libs/common/ui/src/components/Card/CardThemed.tsx
@@ -1,8 +1,9 @@
'use client'
import type { CardProps } from '@mui/material'
import { Card, styled } from '@mui/material'
+export type CardBackgroundColor = 'light' | 'dark' | 'normal'
interface StyledCardProps extends CardProps {
- bgt?: 'light' | 'dark'
+ bgt?: CardBackgroundColor
}
/**
* A colored Card that is by default `contentNormal` colored.
diff --git a/libs/common/ui/src/components/ModalWrapper.tsx b/libs/common/ui/src/components/ModalWrapper.tsx
index 0fd13febc7..9223b32aae 100644
--- a/libs/common/ui/src/components/ModalWrapper.tsx
+++ b/libs/common/ui/src/components/ModalWrapper.tsx
@@ -29,12 +29,13 @@ export function ModalWrapper({
- {children}
+
+ {children}
+
)
}
diff --git a/libs/common/ui/src/theme/index.ts b/libs/common/ui/src/theme/index.ts
index 5c6f37a170..d81199ffce 100644
--- a/libs/common/ui/src/theme/index.ts
+++ b/libs/common/ui/src/theme/index.ts
@@ -63,6 +63,7 @@ declare module '@mui/material/InputBase' {
const defaultTheme = createTheme({
palette: {
+ tonalOffset: 0.1,
mode: `dark`,
},
})
diff --git a/libs/gi/localization/assets/locales/en/page_character.json b/libs/gi/localization/assets/locales/en/page_character.json
index a3b1a89e78..10abfb8713 100644
--- a/libs/gi/localization/assets/locales/en/page_character.json
+++ b/libs/gi/localization/assets/locales/en/page_character.json
@@ -3,7 +3,6 @@
"tabs": {
"overview": "Overview",
"talent": "Talents",
- "teambuffs": "Team Buffs",
"optimize": "Optimize",
"theorycraft": "Theorycraft"
},