noot
This commit is contained in:
parent
0e759282b3
commit
3f58fac4a2
@ -12,7 +12,7 @@ import {
|
|||||||
useRole,
|
useRole,
|
||||||
} from '@floating-ui/react'
|
} from '@floating-ui/react'
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import { useAtom } from 'jotai'
|
import { useAtom, useAtomValue } from 'jotai'
|
||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import { TricksterCharacter } from '../lib/trickster'
|
import { TricksterCharacter } from '../lib/trickster'
|
||||||
import { charactersAtom, selectedCharacterAtom } from '../state/atoms'
|
import { charactersAtom, selectedCharacterAtom } from '../state/atoms'
|
||||||
@ -46,6 +46,8 @@ export const CharacterCard = ({ character, noTopBorder = false }: { character: T
|
|||||||
const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, dismiss, role])
|
const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, dismiss, role])
|
||||||
const [selectedCharacter, setSelectedCharacter] = useAtom(selectedCharacterAtom)
|
const [selectedCharacter, setSelectedCharacter] = useAtom(selectedCharacterAtom)
|
||||||
|
|
||||||
|
const isBank = character.base_job === -8
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
@ -62,9 +64,9 @@ export const CharacterCard = ({ character, noTopBorder = false }: { character: T
|
|||||||
p-2 ${character.path === selectedCharacter?.path ? `bg-blue-200 hover:bg-blue-100` : ''}`}
|
p-2 ${character.path === selectedCharacter?.path ? `bg-blue-200 hover:bg-blue-100` : ''}`}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col justify-between h-full">
|
<div className="flex flex-col justify-between h-full">
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-1 items-center">
|
||||||
<div className="flex flex-row justify-center">
|
<div className="flex flex-row justify-center">
|
||||||
{character.base_job === -8 ? (
|
{isBank ? (
|
||||||
<img
|
<img
|
||||||
className="h-8"
|
className="h-8"
|
||||||
src="https://beta.lifeto.co/item_img/gel.nri.003.000.png"
|
src="https://beta.lifeto.co/item_img/gel.nri.003.000.png"
|
||||||
@ -72,16 +74,15 @@ export const CharacterCard = ({ character, noTopBorder = false }: { character: T
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
className="h-16"
|
className="h-16 bg-gray-200"
|
||||||
src={`https://knowledge.lifeto.co/animations/character/chr${(
|
src=""
|
||||||
character.current_type || character.base_job
|
|
||||||
)
|
|
||||||
.toString()
|
|
||||||
.padStart(3, '0')}_13.png`}
|
|
||||||
alt={`Character ${character.name}`}
|
alt={`Character ${character.name}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-xs font-semibold text-center">
|
||||||
|
{isBank ? 'Bank' : character.name}
|
||||||
|
</div>
|
||||||
<FloatingPortal>
|
<FloatingPortal>
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div
|
<div
|
||||||
@ -103,6 +104,100 @@ export const CharacterCard = ({ character, noTopBorder = false }: { character: T
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SelectedCharacterDisplay = () => {
|
||||||
|
const selectedCharacter = useAtomValue(selectedCharacterAtom)
|
||||||
|
const [{ data: rawCharacters }] = useAtom(charactersAtom)
|
||||||
|
|
||||||
|
if (!selectedCharacter) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center gap-2 p-4 border border-gray-300 rounded bg-gray-50 h-[140px] justify-center">
|
||||||
|
<div className="text-sm text-gray-400">No character selected</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedCharacter.base_job === -8) {
|
||||||
|
// Find the character associated with this bank
|
||||||
|
const characterPair = rawCharacters?.find(pair => pair.bank.id === selectedCharacter.id)
|
||||||
|
const associatedCharacter = characterPair?.character
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center gap-2 p-4 border border-gray-300 rounded bg-gray-50 h-[140px] justify-center">
|
||||||
|
<div className="text-sm font-bold">Bank for: {associatedCharacter?.name || 'Unknown'}</div>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<img
|
||||||
|
className="h-24"
|
||||||
|
src="https://knowledge.lifeto.co/animations/npc/npc041_4.png"
|
||||||
|
alt="Bank NPC"
|
||||||
|
/>
|
||||||
|
{associatedCharacter && (
|
||||||
|
<img
|
||||||
|
className="h-24"
|
||||||
|
src={`https://knowledge.lifeto.co/animations/character/chr${(
|
||||||
|
associatedCharacter.current_type || associatedCharacter.base_job
|
||||||
|
)
|
||||||
|
.toString()
|
||||||
|
.padStart(3, '0')}_13.png`}
|
||||||
|
alt={`${associatedCharacter.name} walking`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center gap-2 p-4 border border-gray-300 rounded bg-gray-50 h-[140px] justify-center">
|
||||||
|
<div className="text-sm font-bold">Selected: {selectedCharacter.name}</div>
|
||||||
|
<img
|
||||||
|
className="h-24"
|
||||||
|
src={`https://knowledge.lifeto.co/animations/character/chr${(
|
||||||
|
selectedCharacter.current_type || selectedCharacter.base_job
|
||||||
|
)
|
||||||
|
.toString()
|
||||||
|
.padStart(3, '0')}_13.png`}
|
||||||
|
alt={`${selectedCharacter.name} walking`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const CharacterRow = ({ characterPair }: { characterPair: { bank: TricksterCharacter; character: TricksterCharacter } }) => {
|
||||||
|
const [selectedCharacter, setSelectedCharacter] = useAtom(selectedCharacterAtom)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-row">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setSelectedCharacter(characterPair.bank)}
|
||||||
|
className={`flex items-center justify-center px-1 py-0.5 border border-black hover:bg-blue-100 ${
|
||||||
|
characterPair.bank.path === selectedCharacter?.path ? 'bg-blue-200' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="https://beta.lifeto.co/item_img/gel.nri.003.000.png"
|
||||||
|
alt="Bank"
|
||||||
|
className="h-6"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setSelectedCharacter(characterPair.character)}
|
||||||
|
className={`flex items-center justify-start px-2 py-1 border-l-0 border-t border-r border-b border-black hover:bg-blue-100 flex-1 ${
|
||||||
|
characterPair.character.path === selectedCharacter?.path ? 'bg-blue-200' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={`https://beta.lifeto.co/img/job/${characterPair.character.current_type - 1}.png`}
|
||||||
|
alt="Class icon"
|
||||||
|
className="h-4 w-4 mr-2"
|
||||||
|
/>
|
||||||
|
{characterPair.character.name}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export const CharacterRoulette = () => {
|
export const CharacterRoulette = () => {
|
||||||
const [{ data: rawCharacters }] = useAtom(charactersAtom)
|
const [{ data: rawCharacters }] = useAtom(charactersAtom)
|
||||||
|
|
||||||
@ -137,25 +232,27 @@ export const CharacterRoulette = () => {
|
|||||||
})
|
})
|
||||||
.map(x => {
|
.map(x => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col" key={`${x.item.character.account_id}`}>
|
<CharacterRow key={`${x.item.character.account_id}`} characterPair={x.item} />
|
||||||
<CharacterCard key={x.item.bank.id} character={x.item.bank} />
|
|
||||||
<CharacterCard key={x.item.character.id} character={x.item.character} noTopBorder={true} />
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-4">
|
||||||
<input
|
<SelectedCharacterDisplay />
|
||||||
className="border border-black-1 bg-gray-100 placeholder-gray-600 p-1 max-w-[180px]"
|
<div className="flex flex-col gap-2">
|
||||||
placeholder="search character..."
|
<input
|
||||||
value={search}
|
className="border border-black-1 bg-gray-100 placeholder-gray-600 p-1"
|
||||||
onChange={e => {
|
placeholder="search character..."
|
||||||
setSearch(e.target.value)
|
value={search}
|
||||||
}}
|
onChange={e => {
|
||||||
></input>
|
setSearch(e.target.value)
|
||||||
<div className="flex flex-row flex-wrap overflow-x-scroll gap-1 h-full min-h-36 max-w-48">
|
}}
|
||||||
{searchResults ? searchResults : null}
|
/>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
{searchResults.length > 0 ? searchResults : (
|
||||||
|
search ? <div className="text-sm text-gray-500 p-2">No characters matched search</div> : null
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user