From cacdb5b2bd2c6f694cccd5bf485fde279265b9b2 Mon Sep 17 00:00:00 2001 From: Simon Gruber Date: Thu, 7 May 2026 10:44:31 +0200 Subject: [PATCH] Enhance mobile UI Co-authored-by: Copilot --- .../components/views/AdminSubmissionsCard.tsx | 247 ++++++++++++------ src/frontend/src/views/AdminView.tsx | 58 +++- 2 files changed, 220 insertions(+), 85 deletions(-) diff --git a/src/frontend/src/components/views/AdminSubmissionsCard.tsx b/src/frontend/src/components/views/AdminSubmissionsCard.tsx index 6b94e37..fe2ffbc 100644 --- a/src/frontend/src/components/views/AdminSubmissionsCard.tsx +++ b/src/frontend/src/components/views/AdminSubmissionsCard.tsx @@ -1,17 +1,22 @@ -import React from "react"; import { CopyToClipboard } from "react-copy-to-clipboard"; import { + CloseOutlined, CopyOutlined, DeleteOutlined, + DownOutlined, MailOutlined, ReloadOutlined, + SearchOutlined, } from "@ant-design/icons"; import { Button, Card, + Checkbox, + Dropdown, Flex, + Grid, Input, - Pagination, + List, Popconfirm, Select, Space, @@ -42,8 +47,10 @@ function getEstimatedTotalText(rawValue: unknown): string | null { export default function AdminSubmissionsCard({ searchQuery, selectedSubmissionState, + sortBy, onSearchQueryChange, onSelectedSubmissionStateChange, + onSortByChange, onReload, copyText, onCopy, @@ -61,8 +68,10 @@ export default function AdminSubmissionsCard({ }: { searchQuery: string; selectedSubmissionState: "all" | "pending" | "unpaid" | "paid"; + sortBy: "time" | "order" | "email" | "amount"; onSearchQueryChange: (value: string) => void; onSelectedSubmissionStateChange: (value: "all" | "pending" | "unpaid" | "paid") => void; + onSortByChange: (value: "time" | "order" | "email" | "amount") => void; onReload: () => void; copyText: string; onCopy: (text: string, didCopy: boolean) => void; @@ -73,11 +82,71 @@ export default function AdminSubmissionsCard({ submissions: any[]; deletingId: string | number | null; savingStatusKey: string | null; - onDeleteSubmission: (id: string | number) => void; + onDeleteSubmission: (ids: Array) => void; onUpdateSubmissionStatus: (submission: any, changes: { accepted?: boolean; paid?: boolean }) => void; totalEstimatedText: string | null; selectedCount: number; }) { + const hasSelection = selectedRowKeys.length > 0; + const screens = Grid.useBreakpoint(); + const isMobile = !screens.md; + + const actionMenuItems = [ + { + key: "copy", + label: ( + +
+ + {hasSelection ? "Copy (selected)" : "Copy"} +
+
+ ), + }, + { + key: "email", + label: ( + + + {hasSelection ? "Email (selected)" : "Email"} + + ), + }, + ...(hasSelection + ? [ + { + key: "clear", + label: ( +
onSelectedRowKeysChange([])} + style={{ width: "100%" }} + > + + Clear selection +
+ ), + }, + { + key: "delete", + label: ( + 1 ? "s" : ""}?`} + description="This cannot be undone." + okText="Delete" + okButtonProps={{ danger: true, loading: deletingId === "multiple" }} + onConfirm={() => onDeleteSubmission(selectedRowKeys)} + > +
+ + Delete Selected +
+
+ ), + }, + ] + : []), + ]; + const columns = [ { title: "Submission", @@ -129,29 +198,6 @@ export default function AdminSubmissionsCard({ ); }, }, - { - title: "Actions", - key: "actions", - width: 1, - render: (_: any, record: any) => ( - onDeleteSubmission(record.id)} - > - - - ), - }, ]; return ( @@ -159,72 +205,125 @@ export default function AdminSubmissionsCard({ title="Submissions" extra={ - 0 - ? "Copy selected submissions as list to clipboard" - : "Copy submissions as list to clipboard" - } - > - - - - - 0 - ? "Create draft email with selected submissions" - : "Create draft email with submissions" - } - > - - +