import { Head, Link, useForm } from '@inertiajs/react';
import { ArrowLeft, FileDown, FileUp, Lock, Send } from 'lucide-react';
import type { FormEvent, ReactNode } from 'react';
import { useRef } from 'react';
import { SupportAttachmentErrors } from '@/components/support-attachment-errors';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useTranslation } from '@/lib/translations';
import { cn } from '@/lib/utils';
import { index as supportIndex } from '@/routes/support';
import { show as showAttachment } from '@/routes/support/attachments';
import { store as storeMessage } from '@/routes/support/messages';
import type {
SupportAttachment,
SupportConversation,
SupportMessage,
} from '@/types';
type Props = {
conversation: SupportConversation;
};
export default function SupportShow({ conversation }: Props) {
const fileInputRef = useRef(null);
const { t } = useTranslation();
const form = useForm({
body: '',
attachments: [] as File[],
});
const isClosed = conversation.status === 'closed';
function submit(event: FormEvent) {
event.preventDefault();
form.post(storeMessage.url(conversation.id), {
forceFormData: true,
preserveScroll: true,
onSuccess: () => {
form.reset();
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
},
});
}
function setAttachments(files: FileList | null) {
form.setData('attachments', Array.from(files ?? []).slice(0, 3));
}
return (
<>
{conversation.category_label}
{conversation.subject}
{t(':count messages', {
count: conversation.messages_count,
})}
{conversation.messages.map((message) => (
))}
{isClosed ? (
{t('This conversation is closed.')}
) : (
)}
>
);
}
SupportShow.layout = {
breadcrumbs: [
{
title: 'Contact admin',
href: supportIndex(),
},
],
};
function MessageBubble({ message }: { message: SupportMessage }) {
const isAdmin = message.author.is_admin;
const { t } = useTranslation();
return (
{message.author.name}
{isAdmin ? t('ADMIN') : t('YOU')}
{message.created_at && (
{formatDateTime(message.created_at)}
)}
{message.body}
{message.attachments && message.attachments.length > 0 && (
)}
);
}
function AttachmentList({ attachments }: { attachments: SupportAttachment[] }) {
return (
);
}
function Field({
label,
error,
children,
}: {
label: string;
error?: string;
children: ReactNode;
}) {
return (
);
}
function StatusBadge({ status }: { status: 'open' | 'closed' }) {
const { t } = useTranslation();
return (
{status === 'open' ? t('OPEN') : t('CLOSED')}
);
}
function formatDateTime(value: string): string {
return new Date(value).toLocaleString([], {
dateStyle: 'medium',
timeStyle: 'short',
});
}
function formatBytes(value: number): string {
if (value < 1024) {
return `${value} B`;
}
if (value < 1024 * 1024) {
return `${Math.round(value / 102.4) / 10} KB`;
}
return `${Math.round(value / 1024 / 102.4) / 10} MB`;
}