fix(ui): restrict tablo delete to admins, hide chat attachments and border

- Only show trash icon on tablo cards/rows when user is admin
- Comment out attachment button and file inputs in chat composer
- Remove top border from chat composer
- Add org logo to NavigationBar avatar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Arthur Belleville 2026-04-14 22:49:00 +02:00
parent 8ac4510542
commit e7b1a04966
No known key found for this signature in database
2 changed files with 33 additions and 32 deletions

View file

@ -128,16 +128,18 @@ function TabloCard({
<span className={cn("px-3 py-1 rounded-full text-sm font-medium", badgeClass)}>
{label}
</span>
<button
type="button"
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors p-2 -m-2 min-w-[44px] min-h-[44px] flex items-center justify-center"
onClick={(e) => {
e.stopPropagation();
onDelete(tablo.id);
}}
>
<Trash2Icon className="w-4 h-4" />
</button>
{tablo.is_admin && (
<button
type="button"
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors p-2 -m-2 min-w-[44px] min-h-[44px] flex items-center justify-center"
onClick={(e) => {
e.stopPropagation();
onDelete(tablo.id);
}}
>
<Trash2Icon className="w-4 h-4" />
</button>
)}
</div>
{/* Icon + name */}
@ -260,16 +262,18 @@ function TabloRow({
</div>
</td>
<td className="px-6 py-4 text-right">
<button
type="button"
className="text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400 transition-colors p-2 rounded min-w-[44px] min-h-[44px] inline-flex items-center justify-center"
onClick={(e) => {
e.stopPropagation();
onDelete(tablo.id);
}}
>
<Trash2Icon className="w-4 h-4" />
</button>
{tablo.is_admin && (
<button
type="button"
className="text-gray-400 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-400 transition-colors p-2 rounded min-w-[44px] min-h-[44px] inline-flex items-center justify-center"
onClick={(e) => {
e.stopPropagation();
onDelete(tablo.id);
}}
>
<Trash2Icon className="w-4 h-4" />
</button>
)}
</td>
</tr>
);

View file

@ -15,10 +15,10 @@ import {
Trash2,
X,
Paperclip,
Image as ImageIcon,
Smile,
// Image as ImageIcon,
// Smile,
Upload,
Plus,
// Plus,
Play,
Pause,
Mic,
@ -1156,12 +1156,12 @@ function ChatComposer({
const [value, setValue] = React.useState("")
const [files, setFiles] = React.useState<FilePreviewItem[]>([])
const [isDragging, setIsDragging] = React.useState(false)
const [showAttachMenu, setShowAttachMenu] = React.useState(false)
// const [showAttachMenu, setShowAttachMenu] = React.useState(false)
const { textareaRef, resize } = useAutoResize({ maxRows: 6 })
const { handleKeyDown: handleTypingKeyDown, stopTyping } =
useTypingIndicator({ onTypingChange: onTyping })
const fileInputRef = React.useRef<HTMLInputElement>(null)
const imageInputRef = React.useRef<HTMLInputElement>(null)
// const fileInputRef = React.useRef<HTMLInputElement>(null)
// const imageInputRef = React.useRef<HTMLInputElement>(null)
const hasContent = value.trim().length > 0 || files.length > 0
const addFiles = React.useCallback((newFiles: FileList | File[]) => {
@ -1226,7 +1226,6 @@ function ChatComposer({
}
if (imageFiles.length > 0) {
addFiles(imageFiles)
setShowAttachMenu(false)
}
},
[addFiles]
@ -1247,7 +1246,6 @@ function ChatComposer({
setIsDragging(false)
if (e.dataTransfer.files.length > 0) {
addFiles(e.dataTransfer.files)
setShowAttachMenu(false)
}
},
[addFiles]
@ -1285,11 +1283,11 @@ function ChatComposer({
)}
{/* Composer body — frosted glass */}
<div className="border-t border-border bg-card px-3 py-2 backdrop-blur-[20px] backdrop-saturate-[180%]">
<div className="bg-card px-3 py-2">
<div>
{/* Input row */}
<div className="flex items-end gap-2">
{/* + button with attachment popout */}
{/* + button with attachment popout disabled until file upload is implemented
<div className="relative">
<button
onClick={() => setShowAttachMenu(!showAttachMenu)}
@ -1302,7 +1300,6 @@ function ChatComposer({
<Plus className="size-5" />
</button>
{/* Popout menu */}
{showAttachMenu && (
<div className="chat-toolbar-enter absolute bottom-full left-0 mb-2 w-44 overflow-hidden rounded-xl border border-border bg-card py-1 shadow-md">
<button
@ -1330,9 +1327,9 @@ function ChatComposer({
)}
</div>
{/* Hidden file inputs */}
<input ref={fileInputRef} type="file" multiple className="hidden" onChange={(e) => { if (e.target.files) addFiles(e.target.files); e.target.value = "" }} />
<input ref={imageInputRef} type="file" accept="image/*" multiple className="hidden" onChange={(e) => { if (e.target.files) addFiles(e.target.files); e.target.value = "" }} />
*/}
<div className="relative flex flex-1 items-end rounded-[22px] border border-border bg-card">
<textarea