Dev#90
Conversation
…for CommDesk - Introduced FLATPAK_BUILD_GUIDE.md for Flatpak packaging instructions. - Created FLATPAK_COMMANDS.sh for quick reference commands related to Flatpak. - Developed PRODUCTION_DEPLOYMENT.md outlining production deployment strategies and CI/CD workflows. - Established TESTING_AND_QA.md detailing testing architecture, QA workflows, and performance validation. - Added latest.json for version management and release notes. - Created org.commdesk.CommDesk.desktop for application integration. - Included release.pub for update signing with Minisign public key. Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
feat: Organizer Event-Based Task Management System — CommDesk
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive Task Management system, including full CRUD functionality, a submission and review workflow, and advanced filtering and search capabilities. The implementation covers new pages, hooks, and a suite of reusable UI components like Avatars, Modals, and Toasts, alongside significant updates to the global design tokens and theme configuration. Feedback focuses on improving the robustness of the system by using more reliable unique ID and color generation methods to avoid collisions. Additionally, there are recommendations to enhance accessibility through semantic HTML, improve error handling in asynchronous operations, and optimize React rendering by removing unnecessary timeouts in validation logic.
| function getColor(name: string): string { | ||
| const code = name.charCodeAt(0) + (name.charCodeAt(1) || 0); | ||
| return BG_COLORS[code % BG_COLORS.length]; | ||
| } |
There was a problem hiding this comment.
The color generation logic only considers the first two characters of the name, which leads to frequent color collisions for different names (e.g., "John" and "Joe" would get the same color). A more robust approach is to hash the entire string.
| function getColor(name: string): string { | |
| const code = name.charCodeAt(0) + (name.charCodeAt(1) || 0); | |
| return BG_COLORS[code % BG_COLORS.length]; | |
| } | |
| function getColor(name: string): string { | |
| const code = name.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0); | |
| return BG_COLORS[code % BG_COLORS.length]; | |
| } |
| const handleSubmit = async () => { | ||
| if (!text.trim()) { setError("Comment cannot be empty."); return; } | ||
| setError(""); | ||
| await addComment.mutateAsync({ taskId, text: text.trim() }); | ||
| setText(""); | ||
| }; |
There was a problem hiding this comment.
The handleSubmit function calls mutateAsync without a try-catch block. If the network request fails, the error won't be caught locally to display a meaningful message to the user via the setError state, and it might result in an unhandled promise rejection.
const handleSubmit = async () => {
if (!text.trim()) { setError("Comment cannot be empty."); return; }
setError("");
try {
await addComment.mutateAsync({ taskId, text: text.trim() });
setText("");
} catch (err) {
setError("Failed to post comment. Please try again.");
}
};
| <div onClick={() => setUseScore((v) => !v)} | ||
| className="relative w-8 h-4 rounded-full cursor-pointer transition-colors" | ||
| style={{ backgroundColor: useScore ? "var(--cd-primary)" : "var(--cd-surface-3)" }}> | ||
| <span className={`absolute top-0.5 w-3 h-3 bg-white rounded-full shadow transition-transform ${useScore ? "translate-x-4" : "translate-x-0.5"}`} /> | ||
| </div> |
There was a problem hiding this comment.
Using a div with an onClick handler for a toggle action is not accessible to screen readers or keyboard users. It should be replaced with a semantic button with appropriate ARIA attributes.
<button
type="button"
role="switch"
aria-checked={useScore}
onClick={() => setUseScore((v) => !v)}
className="relative w-8 h-4 rounded-full transition-colors"
style={{ backgroundColor: useScore ? "var(--cd-primary)" : "var(--cd-surface-3)" }}>
<span className={`absolute top-0.5 w-3 h-3 bg-white rounded-full shadow transition-transform ${useScore ? "translate-x-4" : "translate-x-0.5"}`} />
</button>
| const timer = setTimeout(() => { | ||
| setErrors(validate({ eventId, title, description, assignedTo, deadline, points: points === "" ? undefined : Number(points) })); | ||
| }, 0); | ||
| return () => clearTimeout(timer); |
There was a problem hiding this comment.
The use of setTimeout with a delay of 0 inside useEffect is unnecessary for validation logic in React 18+ and can lead to redundant render cycles. State updates are already batched.
setErrors(validate({ eventId, title, description, assignedTo, deadline, points: points === "" ? undefined : Number(points) }));
| .filter(Boolean) as typeof mockMembers; | ||
|
|
||
| const newTask: Task = { | ||
| id: `task-${Date.now()}`, |
No description provided.