@mui/icons-material#BusinessCenter TypeScript Examples

The following examples show how to use @mui/icons-material#BusinessCenter. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ArtifactCardNano.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
function LocationIcon({ location }) {
  const characterSheet = usePromise(CharacterSheet.get(location ?? ""), [location])
  return characterSheet ? <BootstrapTooltip placement="right-end" title={<Typography>{characterSheet.name}</Typography>}><ImgIcon src={characterSheet.thumbImgSide} sx={{ height: "3em", marginTop: "-1.5em", marginLeft: "-0.5em" }} /></BootstrapTooltip> : <BusinessCenter />
}
Example #2
Source File: LocationName.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
export default function LocationName({ location }) {
  const { t } = useTranslation("ui");
  const characterSheet = usePromise(CharacterSheet.get(location ?? ""), [location])
  return <Typography component="span">
    {characterSheet?.name ? characterSheet.nameWIthIcon : <span><BusinessCenter sx={{ verticalAlign: "text-bottom" }} /> {t<string>("inventory")}</span>}
  </Typography>

}
Example #3
Source File: WeaponCardNano.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
function LocationIcon({ location }) {
  const characterSheet = usePromise(CharacterSheet.get(location ?? ""), [location])
  return characterSheet ? <BootstrapTooltip placement="right-end" title={<Typography>{characterSheet.name}</Typography>}><ImgIcon src={characterSheet.thumbImgSide} sx={{ height: "3em", marginTop: "-1.5em", marginLeft: "-0.5em" }} /></BootstrapTooltip> : <BusinessCenter />
}
Example #4
Source File: CharacterAutocomplete.tsx    From genshin-optimizer with MIT License 4 votes vote down vote up
export default function CharacterAutocomplete({ value, onChange, defaultText = "", defaultIcon = "", placeholderText = "", labelText = "", showDefault = false, showInventory = false, showEquipped = false, filter = () => true, disable = () => false, ...props }: CharacterAutocompleteProps) {
  // TODO: #412 We shouldn't be loading all the character translation files. Should have a separate lookup file for character name.
  const { t } = useTranslation(["ui", "artifact", ...allCharacterKeys.map(k => `char_${k}_gen`)])
  const theme = useTheme()
  const { database } = useContext(DatabaseContext)
  const characterSheets = usePromise(CharacterSheet.getAll, [])
  const filterConfigs = useMemo(() => characterSheets && characterFilterConfigs(database, characterSheets), [database, characterSheets])
  const characterKeys = database._getCharKeys().filter(ck => characterSheets?.[ck] && filter(characterSheets[ck], ck)).sort()

  const textForValue = useCallback((value: CharacterAutocompleteValue): string => {
    switch (value) {
      case "Equipped":
        return t("artifact:filterLocation.currentlyEquipped")
      case "Inventory":
        return t("artifact:filterLocation.inventory")
      case "":
        return defaultText
      default:
        return t(`char_${value}_gen:name`)
    }
  }, [defaultText, t])

  const imageForValue = useCallback((value: CharacterAutocompleteValue): Displayable => {
    switch (value) {
      case "Equipped":
        return <FontAwesomeIcon icon={faUserShield} />
      case "Inventory":
        return <BusinessCenter />
      case "":
        return defaultIcon
      default:
        return <ThumbSide src={characterSheets![value]?.thumbImgSide} sx={{ pr: 1 }} />
    }
  }, [defaultIcon, characterSheets])

  const characterOptions = useMemo(() => filterConfigs && charOptions(characterKeys, filterConfigs, textForValue, showDefault, showInventory, showEquipped),
    [filterConfigs, characterKeys, showDefault, showInventory, showEquipped, textForValue])



  if (!characterSheets || !characterOptions) return null

  return <Autocomplete
    autoHighlight
    options={characterOptions}
    getOptionLabel={(option) => option.label}
    onChange={(_, newValue) => onChange(newValue ? newValue.value : "")}
    isOptionEqualToValue={(option, value) => option.value === value.value}
    getOptionDisabled={option => option.value ? disable(option.value) : false}
    value={{ value, label: textForValue(value) }}
    renderInput={(props) => <SolidColoredTextField
      {...props}
      label={labelText}
      placeholder={placeholderText}
      startAdornment={imageForValue(value)}
      hasValue={value ? true : false}
    />}
    renderOption={(props, option) => {
      const favorite = option.value !== "Equipped" && option.value !== "Inventory"
        && option.value !== "" && database._getChar(option.value)?.favorite
      return <MenuItemWithImage
        key={option.value ? option.value : "default"}
        value={option.value ? option.value : "default"}
        image={imageForValue(option.value)}
        text={
          <Suspense fallback={<Skeleton variant="text" width={100} />}>
            <Typography variant="inherit" noWrap>
              {textForValue(option.value)}
            </Typography>
          </Suspense>
        }
        theme={theme}
        isSelected={value === option.value}
        addlElement={<>
          {favorite && <Box display="flex" flexGrow={1} />}
          {favorite && <Favorite sx={{ ml: 1, mr: -0.5 }} />}
        </>}
        props={props}
      />
    }}
    {...props}
  />
}
Example #5
Source File: ArtifactCard.tsx    From genshin-optimizer with MIT License 4 votes vote down vote up
export default function ArtifactCard({ artifactId, artifactObj, onClick, onDelete, mainStatAssumptionLevel = 0, effFilter = allSubstatFilter, probabilityFilter, disableEditSetSlot = false, editor = false, canExclude = false, canEquip = false, extraButtons }: Data): JSX.Element | null {
  const { t } = useTranslation(["artifact", "ui"]);
  const { database } = useContext(DatabaseContext)
  const databaseArtifact = useArtifact(artifactId)
  const sheet = usePromise(ArtifactSheet.get((artifactObj ?? databaseArtifact)?.setKey), [artifactObj, databaseArtifact])
  const equipOnChar = (charKey: CharacterKey | "") => database.setArtLocation(artifactId!, charKey)
  const editable = !artifactObj
  const [showEditor, setshowEditor] = useState(false)
  const onHideEditor = useCallback(() => setshowEditor(false), [setshowEditor])
  const onShowEditor = useCallback(() => editable && setshowEditor(true), [editable, setshowEditor])

  const wrapperFunc = useCallback(children => <CardActionArea onClick={() => artifactId && onClick?.(artifactId)} sx={{ flexGrow: 1, display: "flex", flexDirection: "column" }} >{children}</CardActionArea>, [onClick, artifactId],)
  const falseWrapperFunc = useCallback(children => <Box sx={{ flexGrow: 1, display: "flex", flexDirection: "column" }} >{children}</Box>, [])

  const art = artifactObj ?? databaseArtifact
  if (!art) return null

  const { id, lock, slotKey, rarity, level, mainStatKey, substats, exclude, location = "" } = art
  const mainStatLevel = Math.max(Math.min(mainStatAssumptionLevel, rarity * 4), level)
  const mainStatUnit = KeyMap.unit(mainStatKey)
  const levelVariant = "roll" + (Math.floor(Math.max(level, 0) / 4) + 1)
  const { currentEfficiency, maxEfficiency } = Artifact.getArtifactEfficiency(art, effFilter)
  const artifactValid = maxEfficiency !== 0
  const slotName = sheet?.getSlotName(slotKey) || "Unknown Piece Name"
  const slotDesc = sheet?.getSlotDesc(slotKey)
  const slotDescTooltip = slotDesc && <InfoTooltip title={<Box>
    <Typography variant='h6'>{slotName}</Typography>
    <Typography>{slotDesc}</Typography>
  </Box>} />
  const setEffects = sheet?.setEffects
  const setDescTooltip = sheet && setEffects && <InfoTooltip title={
    <span>
      {Object.keys(setEffects).map(setNumKey => <span key={setNumKey}>
        <Typography variant="h6"><SqBadge color="success">{t(`artifact:setEffectNum`, { setNum: setNumKey })}</SqBadge></Typography>
        <Typography>{sheet.setEffectDesc(setNumKey as any)}</Typography>
      </span>)}
    </span>
  } />
  return <Suspense fallback={<Skeleton variant="rectangular" sx={{ width: "100%", height: "100%", minHeight: 350 }} />}>
    {editor && <Suspense fallback={false}>
      <ArtifactEditor
        artifactIdToEdit={showEditor ? artifactId : ""}
        cancelEdit={onHideEditor}
        disableEditSetSlot={disableEditSetSlot}
      />
    </Suspense>}
    <CardLight sx={{ height: "100%", display: "flex", flexDirection: "column" }}>
      <ConditionalWrapper condition={!!onClick} wrapper={wrapperFunc} falseWrapper={falseWrapperFunc}>
        <Box className={`grad-${rarity}star`} sx={{ position: "relative", width: "100%" }}>
          {!onClick && <IconButton color="primary" disabled={!editable} onClick={() => database.updateArt({ lock: !lock }, id)} sx={{ position: "absolute", right: 0, bottom: 0, zIndex: 2 }}>
            {lock ? <Lock /> : <LockOpen />}
          </IconButton>}
          <Box sx={{ pt: 2, px: 2, position: "relative", zIndex: 1 }}>
            {/* header */}
            <Box component="div" sx={{ display: "flex", alignItems: "center", gap: 1, mb: 1 }}>
              <Chip size="small" label={<strong>{` +${level}`}</strong>} color={levelVariant as any} />
              <Typography component="span" noWrap sx={{ backgroundColor: "rgba(100,100,100,0.35)", borderRadius: "1em", px: 1 }}><strong>{slotName}</strong></Typography>
              <Box flexGrow={1} sx={{ textAlign: "right" }}>
                {slotDescTooltip}
              </Box>
            </Box>
            <Typography color="text.secondary" variant="body2">
              <SlotNameWithIcon slotKey={slotKey} />
            </Typography>
            <Typography variant="h6" color={`${KeyMap.getVariant(mainStatKey)}.main`}>
              <span>{StatIcon[mainStatKey]} {KeyMap.get(mainStatKey)}</span>
            </Typography>
            <Typography variant="h5">
              <strong>
                <ColorText color={mainStatLevel !== level ? "warning" : undefined}>{cacheValueString(Artifact.mainStatValue(mainStatKey, rarity, mainStatLevel) ?? 0, KeyMap.unit(mainStatKey))}{mainStatUnit}</ColorText>
              </strong>
            </Typography>
            <Stars stars={rarity} colored />
            {/* {process.env.NODE_ENV === "development" && <Typography color="common.black">{id || `""`} </Typography>} */}
          </Box>
          <Box sx={{ height: "100%", position: "absolute", right: 0, top: 0 }}>
            <Box
              component="img"
              src={sheet?.slotIcons[slotKey] ?? ""}
              width="auto"
              height="100%"
              sx={{ float: "right" }}
            />
          </Box>
        </Box>
        <CardContent sx={{ flexGrow: 1, display: "flex", flexDirection: "column", pt: 1, pb: 0, width: "100%" }}>
          {substats.map((stat: ICachedSubstat) => <SubstatDisplay key={stat.key} stat={stat} effFilter={effFilter} rarity={rarity} />)}
          <Box sx={{ display: "flex", my: 1 }}>
            <Typography color="text.secondary" component="span" variant="caption" sx={{ flexGrow: 1 }}>{t`artifact:editor.curSubEff`}</Typography>
            <PercentBadge value={currentEfficiency} max={900} valid={artifactValid} />
          </Box>
          {currentEfficiency !== maxEfficiency && <Box sx={{ display: "flex", mb: 1 }}>
            <Typography color="text.secondary" component="span" variant="caption" sx={{ flexGrow: 1 }}>{t`artifact:editor.maxSubEff`}</Typography>
            <PercentBadge value={maxEfficiency} max={900} valid={artifactValid} />
          </Box>}
          <Box flexGrow={1} />
          {probabilityFilter && <strong>Probability: {(probability(art, probabilityFilter) * 100).toFixed(2)}%</strong>}
          <Typography color="success.main">{sheet?.name ?? "Artifact Set"} {setDescTooltip}</Typography>
        </CardContent>
      </ConditionalWrapper>
      <Box sx={{ p: 1, display: "flex", gap: 1, justifyContent: "space-between", alignItems: "center" }}>
        {editable && canEquip
          ? <CharacterAutocomplete sx={{ flexGrow: 1 }} size="small" showDefault
            defaultIcon={<BusinessCenter />} defaultText={t("ui:inventory")}
            value={location} onChange={equipOnChar} />
          : <LocationName location={location} />}
        {editable && <ButtonGroup sx={{ height: "100%" }}>
          {editor && <Tooltip title={<Typography>{t`artifact:edit`}</Typography>} placement="top" arrow>
            <Button color="info" size="small" onClick={onShowEditor} >
              <FontAwesomeIcon icon={faEdit} className="fa-fw" />
            </Button>
          </Tooltip>}
          {canExclude && <Tooltip title={<Typography>{t`artifact:excludeArtifactTip`}</Typography>} placement="top" arrow>
            <Button onClick={() => database.updateArt({ exclude: !exclude }, id)} color={exclude ? "error" : "success"} size="small" >
              <FontAwesomeIcon icon={exclude ? faBan : faChartLine} className="fa-fw" />
            </Button>
          </Tooltip>}
          {!!onDelete && <Button color="error" size="small" onClick={() => onDelete(id)} disabled={lock}>
            <FontAwesomeIcon icon={faTrashAlt} className="fa-fw" />
          </Button>}
          {extraButtons}
        </ButtonGroup>}
      </Box>
    </CardLight >
  </Suspense>
}
Example #6
Source File: WeaponCard.tsx    From genshin-optimizer with MIT License 4 votes vote down vote up
export default function WeaponCard({ weaponId, onClick, onEdit, onDelete, canEquip = false, extraButtons }: WeaponCardProps) {
  const { t } = useTranslation(["page_weapon", "ui"]);
  const { database } = useContext(DatabaseContext)
  const databaseWeapon = useWeapon(weaponId)
  const weapon = databaseWeapon
  const weaponSheet = usePromise(weapon?.key ? WeaponSheet.get(weapon.key) : undefined, [weapon?.key])

  const filter = useCallback(
    (cs: CharacterSheet) => cs.weaponTypeKey === weaponSheet?.weaponType,
    [weaponSheet],
  )

  const wrapperFunc = useCallback(children => <CardActionArea onClick={() => onClick?.(weaponId)} >{children}</CardActionArea>, [onClick, weaponId],)
  const falseWrapperFunc = useCallback(children => <Box >{children}</Box>, [])

  const equipOnChar = useCallback((charKey: CharacterKey | "") => database.setWeaponLocation(weaponId, charKey), [database, weaponId],)

  const UIData = useMemo(() => weaponSheet && weapon && computeUIData([weaponSheet.data, dataObjForWeapon(weapon)]), [weaponSheet, weapon])

  if (!weapon || !weaponSheet || !UIData) return null;
  const { level, ascension, refinement, id, location = "", lock } = weapon
  const weaponTypeKey = UIData.get(input.weapon.type).value!
  const stats = [input.weapon.main, input.weapon.sub, input.weapon.sub2].map(x => UIData.get(x))
  const img = ascension < 2 ? weaponSheet?.img : weaponSheet?.imgAwaken

  return <Suspense fallback={<Skeleton variant="rectangular" sx={{ width: "100%", height: "100%", minHeight: 300 }} />}>
    <CardLight sx={{ height: "100%", display: "flex", flexDirection: "column", justifyContent: "space-between" }}>
      <ConditionalWrapper condition={!!onClick} wrapper={wrapperFunc} falseWrapper={falseWrapperFunc}>
        <Box className={`grad-${weaponSheet.rarity}star`} sx={{ position: "relative", pt: 2, px: 2, }}>
          {!onClick && <IconButton color="primary" onClick={() => database.updateWeapon({ lock: !lock }, id)} sx={{ position: "absolute", right: 0, bottom: 0, zIndex: 2 }}>
            {lock ? <Lock /> : <LockOpen />}
          </IconButton>}
          <Box sx={{ position: "relative", zIndex: 1 }}>
            <Box component="div" sx={{ display: "flex", alignItems: "center", gap: 1, mb: 1 }}>
              <ImgIcon sx={{ fontSize: "1.5em" }} src={Assets.weaponTypes?.[weaponTypeKey]} />
              <Typography noWrap sx={{ textAlign: "center", backgroundColor: "rgba(100,100,100,0.35)", borderRadius: "1em", px: 1 }}><strong>{weaponSheet.name}</strong></Typography>
            </Box>
            <Typography component="span" variant="h5">Lv. {level}</Typography>
            <Typography component="span" variant="h5" color="text.secondary">/{ascensionMaxLevel[ascension]}</Typography>
            <Typography variant="h6">Refinement <strong>{refinement}</strong></Typography>
            <Typography><Stars stars={weaponSheet.rarity} colored /></Typography>
          </Box>
          <Box sx={{ height: "100%", position: "absolute", right: 0, top: 0 }}>
            <Box
              component="img"
              src={img ?? ""}
              width="auto"
              height="100%"
              sx={{ float: "right" }}
            />
          </Box>
        </Box>
        <CardContent>
          {stats.map(node => {
            if (!node.info.key) return null
            const displayVal = valueString(node.value, node.unit, !node.unit ? 0 : undefined)
            return <Box key={node.info.key} sx={{ display: "flex" }}>
              <Typography flexGrow={1}>{StatIcon[node.info.key!]} {KeyMap.get(node.info.key)}</Typography>
              <Typography>{displayVal}</Typography>
            </Box>
          })}
        </CardContent>
      </ConditionalWrapper>
      <Box sx={{ p: 1, display: "flex", gap: 1, justifyContent: "space-between", alignItems: "center" }}>
        {canEquip
          ? <CharacterAutocomplete size="small" sx={{ flexGrow: 1 }}
            showDefault defaultIcon={<BusinessCenter />} defaultText={t("inventory")}
            value={location} onChange={equipOnChar} filter={filter} />
          : <LocationName location={location} />}
        <ButtonGroup>
          {!!onEdit && <Tooltip title={<Typography>{t`page_weapon:edit`}</Typography>} placement="top" arrow>
            <Button color="info" onClick={() => onEdit(id)} >
              <FontAwesomeIcon icon={faEdit} className="fa-fw" />
            </Button>
          </Tooltip>}
          {!!onDelete && <Button color="error" onClick={() => onDelete(id)} disabled={!!location || lock} >
            <FontAwesomeIcon icon={faTrashAlt} className="fa-fw" />
          </Button>}
          {extraButtons}
        </ButtonGroup>
      </Box>
    </CardLight>
  </Suspense>
}
Example #7
Source File: WeaponEditor.tsx    From genshin-optimizer with MIT License 4 votes vote down vote up
export default function WeaponEditor({
  weaponId: propWeaponId,
  footer = false,
  onClose,
  extraButtons
}: WeaponStatsEditorCardProps) {
  const { t } = useTranslation("ui")
  const { data } = useContext(DataContext)

  const { database } = useContext(DatabaseContext)
  const weapon = useWeapon(propWeaponId)
  const { key = "", level = 0, refinement = 0, ascension = 0, lock, location = "", id } = weapon ?? {}
  const weaponSheet = usePromise(WeaponSheet.get(key), [key])

  const weaponDispatch = useCallback((newWeapon: Partial<ICachedWeapon>) => {
    database.updateWeapon(newWeapon, propWeaponId)
  }, [propWeaponId, database])

  const setLevel = useCallback(level => {
    level = clamp(level, 1, 90)
    const ascension = ascensionMaxLevel.findIndex(ascenML => level <= ascenML)
    weaponDispatch({ level, ascension })
  }, [weaponDispatch])

  const setAscension = useCallback(() => {
    const lowerAscension = ascensionMaxLevel.findIndex(ascenML => level !== 90 && level === ascenML)
    if (ascension === lowerAscension) weaponDispatch({ ascension: ascension + 1 })
    else weaponDispatch({ ascension: lowerAscension })
  }, [weaponDispatch, ascension, level])

  const characterSheet = usePromise(location ? CharacterSheet.get(location) : undefined, [location])
  const weaponFilter = characterSheet ? (ws) => ws.weaponType === characterSheet.weaponTypeKey : undefined
  const initialWeaponFilter = characterSheet && characterSheet.weaponTypeKey

  const equipOnChar = useCallback((charKey: CharacterKey | "") => id && database.setWeaponLocation(id, charKey), [database, id])
  const filter = useCallback(
    (cs: CharacterSheet) => cs.weaponTypeKey === weaponSheet?.weaponType,
    [weaponSheet],
  )

  const [showModal, setshowModal] = useState(false)
  const img = ascension < 2 ? weaponSheet?.img : weaponSheet?.imgAwaken

  //check the levels when switching from a 5* to a 1*, for example.
  useEffect(() => {
    if (!weaponSheet || !weaponDispatch || weaponSheet.key !== weapon?.key) return
    if (weaponSheet.rarity <= 2 && (level > 70 || ascension > 4)) {
      const [level, ascension] = lowRarityMilestoneLevels[0]
      weaponDispatch({ level, ascension })
    }
  }, [weaponSheet, weapon, weaponDispatch, level, ascension])


  const weaponUIData = useMemo(() => weaponSheet && weapon && computeUIData([weaponSheet.data, dataObjForWeapon(weapon)]), [weaponSheet, weapon])
  return <ModalWrapper open={!!propWeaponId} onClose={onClose} containerProps={{ maxWidth: "md" }}><CardLight>
    <WeaponSelectionModal show={showModal} onHide={() => setshowModal(false)} onSelect={k => weaponDispatch({ key: k })} filter={weaponFilter} weaponFilter={initialWeaponFilter} />
    <CardContent >
      {weaponSheet && weaponUIData && <Grid container spacing={1.5}>
        <Grid item xs={12} sm={3}>
          <Grid container spacing={1.5}>
            <Grid item xs={6} sm={12}>
              <Box component="img" src={img} className={`grad-${weaponSheet.rarity}star`} sx={{ maxWidth: 256, width: "100%", height: "auto", borderRadius: 1 }} />
            </Grid>
            <Grid item xs={6} sm={12}>
              <Typography><small>{weaponSheet.description}</small></Typography>
            </Grid>
          </Grid>
        </Grid>
        <Grid item xs={12} sm={9} sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
          <Box display="flex" gap={1} flexWrap="wrap" justifyContent="space-between">
            <ButtonGroup>
              <Button onClick={() => setshowModal(true)} >{weaponSheet?.name ?? "Select a Weapon"}</Button>
              {weaponSheet?.hasRefinement && <DropdownButton title={`Refinement ${refinement}`}>
                <MenuItem>Select Weapon Refinement</MenuItem>
                <Divider />
                {[...Array(5).keys()].map(key =>
                  <MenuItem key={key} onClick={() => weaponDispatch({ refinement: key + 1 })} selected={refinement === (key + 1)} disabled={refinement === (key + 1)}>
                    {`Refinement ${key + 1}`}
                  </MenuItem>)}
              </DropdownButton>}
              {extraButtons}
            </ButtonGroup>
          </Box>
          <Box display="flex" gap={1} flexWrap="wrap" justifyContent="space-between">
            <ButtonGroup sx={{ bgcolor: t => t.palette.contentLight.main }} >
              <CustomNumberInputButtonGroupWrapper >
                <CustomNumberInput onChange={setLevel} value={level}
                  startAdornment="Lv. "
                  inputProps={{ min: 1, max: 90, sx: { textAlign: "center" } }}
                  sx={{ width: "100%", height: "100%", pl: 2 }}
                />
              </CustomNumberInputButtonGroupWrapper>
              {weaponSheet && <Button sx={{ pl: 1 }} disabled={!weaponSheet.ambiguousLevel(level)} onClick={setAscension}><strong>/ {ascensionMaxLevel[ascension]}</strong></Button>}
              {weaponSheet && <DropdownButton title={"Select Level"} >
                {weaponSheet.milestoneLevels.map(([lv, as]) => {
                  const sameLevel = lv === ascensionMaxLevel[as]
                  const lvlstr = sameLevel ? `Lv. ${lv}` : `Lv. ${lv}/${ascensionMaxLevel[as]}`
                  const selected = lv === level && as === ascension
                  return <MenuItem key={`${lv}/${as}`} selected={selected} disabled={selected} onClick={() => weaponDispatch({ level: lv, ascension: as })}>{lvlstr}</MenuItem>
                })}
              </DropdownButton>}
            </ButtonGroup>

            <Button color="error" onClick={() => id && database.updateWeapon({ lock: !lock }, id)} startIcon={lock ? <Lock /> : <LockOpen />}>
              {lock ? "Locked" : "Unlocked"}
            </Button>
          </Box>
          <Typography><Stars stars={weaponSheet.rarity} /></Typography>
          <Typography variant="subtitle1"><strong>{weaponSheet.passiveName}</strong></Typography>
          <Typography gutterBottom>{weaponSheet.passiveName && weaponSheet.passiveDescription(weaponUIData.get(input.weapon.refineIndex).value)}</Typography>
          <Box display="flex" flexDirection="column" gap={1}>
            <CardDark >
              <CardHeader title={"Main Stats"} titleTypographyProps={{ variant: "subtitle2" }} />
              <Divider />
              <FieldDisplayList>
                {[input.weapon.main, input.weapon.sub, input.weapon.sub2].map((node, i) => {
                  const n = weaponUIData.get(node)
                  if (n.isEmpty || !n.value) return null
                  return <NodeFieldDisplay key={n.info.key} node={n} component={ListItem} />
                })}
              </FieldDisplayList>
            </CardDark>
            {data && weaponSheet.document && <DocumentDisplay sections={weaponSheet.document} />}
          </Box>
        </Grid>
      </Grid>}
    </CardContent>
    {footer && id && <CardContent sx={{ py: 1 }}>
      <Grid container spacing={1}>
        <Grid item flexGrow={1}>
          <CharacterAutocomplete showDefault defaultIcon={<BusinessCenter />} defaultText={t("inventory")} value={location} onChange={equipOnChar} filter={filter} />
        </Grid>
        {!!onClose && <Grid item><CloseButton sx={{ height: "100%" }} large onClick={onClose} /></Grid>}
      </Grid>
    </CardContent>}
  </CardLight ></ModalWrapper>
}