139 lines
3.6 KiB
TypeScript
139 lines
3.6 KiB
TypeScript
import { memo } from 'react'
|
||
import { Pencil, Trash2 } from 'lucide-react'
|
||
|
||
import type { Organisation } from '../../../../entities/employee/model/types'
|
||
|
||
function getOrganisationInitials(name: string) {
|
||
const words = name.trim().split(/\s+/).filter(Boolean)
|
||
|
||
if (words.length === 0) return 'ОР'
|
||
|
||
return words
|
||
.slice(0, 2)
|
||
.map((word) => word[0])
|
||
.join('')
|
||
.toUpperCase()
|
||
}
|
||
|
||
function formatCreationDate(timestamp?: number) {
|
||
if (!timestamp) return 'Дата создания не указана'
|
||
|
||
return `Создана ${new Intl.DateTimeFormat('ru-RU', {
|
||
day: '2-digit',
|
||
month: '2-digit',
|
||
year: 'numeric',
|
||
}).format(new Date(timestamp))}`
|
||
}
|
||
|
||
type OrganisationsTableProps = {
|
||
organisations: Organisation[]
|
||
onOpen: (organisation: Organisation) => void
|
||
onEdit: (organisation: Organisation) => void
|
||
onDelete: (organisation: Organisation) => void
|
||
}
|
||
|
||
type OrganisationTableRowProps = {
|
||
organisation: Organisation
|
||
onOpen: (organisation: Organisation) => void
|
||
onEdit: (organisation: Organisation) => void
|
||
onDelete: (organisation: Organisation) => void
|
||
}
|
||
|
||
const OrganisationTableRow = memo(function OrganisationTableRow({
|
||
organisation,
|
||
onOpen,
|
||
onEdit,
|
||
onDelete,
|
||
}: OrganisationTableRowProps) {
|
||
return (
|
||
<tr
|
||
className="employees-table__row employees-table__row--clickable"
|
||
tabIndex={0}
|
||
onClick={() => onOpen(organisation)}
|
||
onKeyDown={(event) => {
|
||
if (event.key === 'Enter') {
|
||
onOpen(organisation)
|
||
}
|
||
}}
|
||
>
|
||
<td>{organisation.id}</td>
|
||
|
||
<td>
|
||
<div className="employee-person">
|
||
<div className={`employee-person__avatar ${organisation.logoUrl ? 'transparent-backdrop' : ''}`}>
|
||
{organisation.logoUrl ? (
|
||
<img src={organisation.logoUrl} alt={organisation.name} />
|
||
) : (
|
||
<span>{getOrganisationInitials(organisation.name)}</span>
|
||
)}
|
||
</div>
|
||
|
||
<div className="employee-person__info">
|
||
<span>{organisation.name}</span>
|
||
<small>{formatCreationDate(organisation.creationDate)}</small>
|
||
</div>
|
||
</div>
|
||
</td>
|
||
|
||
<td>
|
||
<div className="employees-table-actions">
|
||
<button
|
||
className="employees-action-btn employees-action-btn--edit"
|
||
type="button"
|
||
onClick={(event) => {
|
||
event.stopPropagation()
|
||
onEdit(organisation)
|
||
}}
|
||
>
|
||
<Pencil size={16} />
|
||
Редактировать
|
||
</button>
|
||
|
||
<button
|
||
className="employees-action-btn employees-action-btn--delete"
|
||
type="button"
|
||
onClick={(event) => {
|
||
event.stopPropagation()
|
||
onDelete(organisation)
|
||
}}
|
||
>
|
||
<Trash2 size={16} />
|
||
Удалить
|
||
</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
)
|
||
})
|
||
|
||
export const OrganisationsTable = memo(function OrganisationsTable({
|
||
organisations,
|
||
onOpen,
|
||
onEdit,
|
||
onDelete,
|
||
}: OrganisationsTableProps) {
|
||
return (
|
||
<table className="employees-table organisations-table">
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Название организации</th>
|
||
<th>Управление</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
{organisations.map((organisation) => (
|
||
<OrganisationTableRow
|
||
key={organisation.id}
|
||
organisation={organisation}
|
||
onOpen={onOpen}
|
||
onEdit={onEdit}
|
||
onDelete={onDelete}
|
||
/>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
)
|
||
})
|