hensei-web/components/raids/RaidItem/index.tsx
Justin Edmund 3d67622353
Fix i18n migration to next-intl (#430)
## Summary
- Fixed translation key format compatibility with next-intl
- Fixed pluralization format from i18next to next-intl format
- Fixed dynamic translation key error handling
- Updated server components to match API response structure
- Fixed useSearchParams import location

## Changes
- Changed pluralization from `{{count}} items` to `{count} items` format
- Added proper error handling for missing translation keys
- Fixed import paths for next-intl hooks
- Fixed PartyPageClient trying to set non-existent appState.parties

## Test plan
- [x] Verified translations render correctly
- [x] Tested pluralization works with different counts
- [x] Confirmed no console errors about missing translations
- [x] Tested party page functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-03 16:25:59 -07:00

113 lines
2.5 KiB
TypeScript

import React, { ComponentProps, PropsWithChildren } from 'react'
import { useTranslations } from 'next-intl'
import classNames from 'classnames'
import { CommandItem } from '~components/common/Command'
import styles from './index.module.scss'
interface Props extends ComponentProps<'div'> {
className?: string
icon?: {
alt: string
src: string
}
extra: boolean
selected: boolean
tabIndex?: number
value: string | number
onSelect: () => void
onArrowKeyPressed?: (direction: 'Up' | 'Down') => void
onEscapeKeyPressed?: () => void
}
const placeholderSlugs = [
'all',
'farming',
'three-gauge',
'five-gauge',
'ex-plus',
'nm90',
'nm95',
'nm100',
'nm150',
'nm200',
'1-star',
'2-star',
'3-star',
'4-star',
'5-star',
'db95',
'db135',
'db175',
]
const RaidItem = React.forwardRef<HTMLDivElement, PropsWithChildren<Props>>(
function Item(
{
icon,
value,
extra,
selected,
tabIndex,
children,
onEscapeKeyPressed,
onArrowKeyPressed,
...props
}: PropsWithChildren<Props>,
forwardedRef
) {
const t = useTranslations('common')
const classes = classNames({
raid: true,
[styles.item]: true,
})
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === 'Escape' && onEscapeKeyPressed) {
event.preventDefault()
onEscapeKeyPressed()
}
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
event.preventDefault()
if (onArrowKeyPressed) {
onArrowKeyPressed(event.key === 'ArrowUp' ? 'Up' : 'Down')
}
}
if (event.key === 'Enter') {
event.preventDefault()
props.onSelect()
}
}
return (
<CommandItem
{...props}
className={classes}
tabIndex={tabIndex}
value={`${value}`}
onClick={props.onSelect}
onKeyDown={handleKeyDown}
ref={forwardedRef}
>
{placeholderSlugs.includes(`${value}`) ? (
<div className={styles.placeholder} />
) : (
icon && <img alt={icon.alt} src={icon.src} />
)}
<span className={styles.text}>{children}</span>
{selected && (
<i className={styles.selected}>{t('combobox.selected')}</i>
)}
{extra && <i className={styles.extraIndicator}>EX</i>}
</CommandItem>
)
}
)
RaidItem.defaultProps = {
extra: false,
selected: false,
}
export default RaidItem