Skip to content

Latest commit

 

History

History
101 lines (90 loc) · 16.3 KB

File metadata and controls

101 lines (90 loc) · 16.3 KB

This ticket is a catalogue of remaining improvement points. Each issue can be solved in a vacuum. They help with the long-term maintainability of the application without directly affecting user-facing functionality (except caching items).

CSS / Layout Cleanup Candidates

# File Issue Priority
4 components/Discussions/models/DiscussionModelForum.vue Duplicate gap declarations on __bottom-row (lines 459-460) - genuine bug to fix. Remaining layout CSS is structural to the grid/flex component system with mobile overrides; not a VUI swap candidate. Low
8 components/Events/EventsListing.vue 16 !important rules + layout CSS - same pattern as Event.vue / EventsCalendar.vue Medium
9 components/Admin/Funding/IncomeChart.vue ~14 layout CSS rules - legend/header wrappers are pure flex and map 1:1 to <Flex y-center gap="s"> etc. Medium
10 components/Admin/Funding/UserChart.vue ~14 layout CSS rules - nearly identical to IncomeChart.vue; same legend/header flex pattern Medium
11 components/Community/ProjectCard.vue 15+ layout CSS rules - card body, tag row, footer row are all pure flex Medium
12 components/GameServers/GameServerHeader.vue 22 layout CSS rules + 3 !important - action/metadata column wrappers are pure flex column; contains !important overrides Medium
13 components/Shared/GameDetailsModal.vue 14 layout CSS rules - modal body sections are nested flex-direction: column with gap, directly replaceable Medium
14 components/Shared/UserPreviewCard.vue Layout CSS (flex-direction: column, gap) - the top-level wrapper and content column are pure <Flex column gap="m"> Medium
15 components/Shared/ReferendumResults.vue Layout CSS + 2 !important - result rows and container are flex-direction: column with gap Medium
16 components/Shared/SupportModal.vue Layout CSS - modal content sections are flex column gap-m/xs; paypal/tier blocks are flex justify-center gap-l Medium
17 components/Settings/ConnectionsCard.vue Layout CSS + 5 inline style= - connection rows, action wrappers convertible to <Flex y-end column> Medium
18 components/Discussions/models/DiscussionModelComment.vue 10 layout CSS rules, 5 !important - sibling of DiscussionModelForum.vue (#4) with the same pattern of layout CSS and !important overrides; should be treated as a paired cleanup Medium
19 components/Settings/ProfileSummaryCard.vue Layout CSS - content and info sections are flex column gap-l/xxs Low
20 components/Profile/RichPresenceSteam.vue 14 layout CSS rules - all four sections are simple flex column / flex row x-between y-center Low
21 components/Profile/ProfileForm.vue Layout CSS - footer buttons (justify-content: flex-end), avatar row, badge row Low
22 components/Shared/MetadataCard.vue Layout CSS - icon+text rows are <Flex y-center gap="s"> Low
23 components/Shared/MarkdownPreview.vue Layout CSS - preview row is flex y-center gap-xxs Low
24 components/Admin/Complaints/ComplaintCard.vue Layout CSS - card body is flex column Low
25 components/Admin/Users/UserTable.vue Layout CSS - username/status column stacks are flex column gap-2px Low
26 components/Reactions/ReactionsSelect.vue Layout CSS - emote-group and emote-row wrappers are pure flex column gap-xs Low
27 components/Admin/Referendums/ReferendumForm.vue Layout CSS - option rows/add button row are flex y-center gap-xs Low
28 components/Admin/Projects/ProjectForm.vue Layout CSS - preview section, image action row Low
29 pages/votes/[id].vue Layout CSS - options list, choice row, and status block are pure flex column/row Low
31 components/Shared/BulkAvatarDisplay.vue Layout CSS + 4 inline style= - avatar stack cell wrappers are flex y-center x-center Low
32 components/Shared/BulkAvatarDisplayCluster.vue Layout CSS + 4 inline style= - same as BulkAvatarDisplay Low
33 components/Landing/LandingHero.vue Layout CSS - hero content column and action wrapper are flex column gap Low
34 components/Settings/ConnectTeamSpeak.vue Layout CSS - form action row is flex column align-end Low
35 components/Profile/Badges/ProfileBadge.vue Layout CSS - main badge container and icon cells Low
36 pages/forum/index.vue Layout CSS - sidebar and update feed rows Low
37 pages/index.vue Layout CSS - landing sections Low
38 components/Events/EventCardLanding.vue Layout CSS + 3 !important Low
39 components/Community/FundingProgress.vue 40 !important Low
40 components/Profile/ProfileHeader.vue 42 !important + 4 inline style= Low
41 components/Admin/Discussions/DiscussionDetails.vue Layout CSS - detail header wrapper Low
42 components/Admin/Complaints/ComplaintDetails.vue Layout CSS - detail sections Low
43 pages/community/projects/[id].vue 12 layout CSS rules - project detail page with banner, metadata, and description sections; all flex column / flex row wrappers Low
44 pages/community/badges.vue 6 layout CSS rules - badge gallery page Low
45 components/Layout/Footer.vue 2 !important - both are responsive overrides for flex-direction and align-items; replaceable with responsive VUI <Flex> props or <Grid> Low
46 components/Events/EventTiming.vue 2 !important - used to force grid-template-columns at breakpoints; needs :deep() or responsive grid props Low
47 components/Events/CountdownTimer.vue 2 !important, display: flex - same pattern as EventTiming.vue Low
48 components/Admin/KPIContainer.vue 2 !important on flex-wrap - tiny 38-line component; the overrides could be replaced with a <Flex wrap> prop Low

Dead Code / Orphaned Files

# File Issue Priority
75 components/Shared/ErrorToast.vue 2 !important overriding VUI toast text/font styles - small (44 lines) but the overrides suggest the VUI toast token isn't being used correctly; worth a quick audit Low
76 components/Admin/Funding/ExpenseForm.vue 2 !important on border-color for validation state - could use a VUI form validation approach with :deep() instead Low

Large Components Needing Decomposition (DRY / SRP Violations)

# File Size Issue Priority
78 components/Admin/Users/UserForm.vue 1101 lines Admin user form handles avatar upload, badge editing, role assignment, permission verification, birthday picker adapter, and delete confirmation all in one component. Validators extracted to useUserFormValidation. Remaining: extract UserFormBadgeEditor, UserFormRoleSelector, UserFormAvatarSection Medium
81 components/Admin/Users/UserTable.vue 777 lines Data fetching extracted to useAdminUserTableData. Remaining: extract UserTableRow, move sort/filter state to useUserTableFilters composable Low
82 components/Profile/ProfileDetail.vue 643 lines Friendship state machine extracted to useFriendship. Remaining: extract ProfileEditSheet sub-component Low
87 components/Admin/Users/UserDetails.vue 735 lines Detail panel for a user with ban status, activity log, friendship list, profile summary, and inline ban form. Extract UserDetailsBanPanel, UserDetailsProfileSummary Medium
88 components/Admin/Discussions/DiscussionDetails.vue 683 lines Discussion detail panel with file attachments section, author info, moderation actions, and reply listing. Extract DiscussionAttachments, move moderation actions to DiscussionModerationPanel Medium
89 components/Admin/Network/ContainerTable.vue 719 lines Container management table with inline status badges, log viewer embed, action bar, and filter state. Extract ContainerTableRow, ContainerStatusBadge. Also: the per-row action loading pattern (isActionLoading(name, action)) is a local function here while EventTable.vue already gets this from useAdminCrudTable - migrate to the same pattern to close the duplication Medium
90 components/Admin/Complaints/ComplaintDetails.vue 583 lines Complaint detail panel mixing complaint metadata, thread display, and status management. Extract ComplaintThreadPanel Medium
91 components/Admin/Complaints/ComplaintList.vue 578 lines Large list with inline sort, filter, pagination, and card rendering. Extract ComplaintListFilters composable, use ComplaintCard more aggressively Medium
92 components/Admin/Assets/AssetManager.vue 840 lines, 14 template blocks Asset browser combining directory listing, breadcrumb navigation, upload trigger, rename/delete modals, image preview, and multi-bucket support. Extract AssetBreadcrumbs, AssetGrid, AssetPreview Medium
93 components/Editor/RichTextEditor.vue 1102 lines Editor toolbar, image upload, mention picker, math modal, YouTube modal, formatting menus, and font/size/color extension wiring all in one file. Extract EditorToolbarRow, EditorAttachmentUpload; plugins are already split into plugins/ but the parent is still too large Medium
94 components/Settings/MfaCard.vue 791 lines MFA management with TOTP setup wizard (QR + secret + naming), factor list management, remove-factor confirmation, and elevated-role guard. Extract MfaTotpSetup, MfaFactorList Medium
95 components/Settings/ConnectTeamSpeak.vue 658 lines TeamSpeak connection wizard with 4-step flow (manage/request/confirm/success), identity list, server selector, and error handling. Extract TeamspeakConnectionWizard, TeamspeakIdentityList Medium
96 components/Profile/ProfileForm.vue 774 lines Profile edit form with avatar, badge selection, country picker, birthday picker, Markdown editor, link fields, and submit. Extract ProfileFormBadgeSelect, ProfileFormAvatarSection Medium
97 components/Events/EventsCalendar.vue 854 lines, 7 template blocks Full calendar + event detail sidebar, filtering, RSVP, countdown, and VUI !important overrides. Extract EventCalendarSidebar, EventCalendarDayCell Medium
98 components/Admin/Discussions/DiscussionTable.vue 636 lines Discussion admin table with inline topic/author display, status filters, bulk actions. Extract DiscussionTableFilters composable Medium
99 pages/auth/sign-in.vue 655 lines Sign-in page handling email/password form, MFA TOTP step, MFA list-factor step, and OAuth buttons across 11 v-if branches. Extract SignInMfaStep, SignInOAuthButtons Medium
100 components/Discussions/models/DiscussionModelComment.vue 493 lines Paired with DiscussionModelForum.vue (#4) but absent from original ticket. Contains vote/reaction logic, 10 flex rules, 5 !important overrides Medium
101 components/Settings/ConnectionsCard.vue 565 lines One card managing five distinct connection providers (Patreon, Steam, Discord, TeamSpeak, rich-presence toggle), each with its own disconnect handler, loading state, and inline conditional layout. Each provider is its own SRP unit - extract ConnectionRowPatreon, ConnectionRowSteam, ConnectionRowDiscord, ConnectionRowTeamSpeak, ConnectionRowRichPresence, all sharing a generic ConnectionRow wrapper slot pattern Medium
103 components/Admin/Games/GameForm.vue 488 lines Asset management (upload/remove/preview for three asset types) lives alongside the basic game fields form, coupled only by gameForm.shorthand. Extract GameAssetUploadPanel sub-component (the "Game Assets" section with FileUpload instances, handleAssetUpload, handleAssetRemove, Steam asset link dropdown) Medium
104 components/Admin/Games/GameDetails.vue 470 lines Detail sheet fetching assets (3 parallel URL lookups) and related game servers in a single watchEffect. Renders "Game Assets", "Related Game Servers", and metadata in one template. Extract GameDetailsAssets and GameDetailsServers sub-components Medium
108 components/Admin/Projects/ProjectForm.vue 574 lines Admin project form with banner upload, game selector, metadata, and delete. Extract ProjectFormBannerUpload Low
110 pages/auth/confirm.vue 672 lines Auth confirmation page handling email confirm, password reset, and OAuth consent flows in a single file. Split into separate page components or extract AuthConfirmPasswordReset, AuthConfirmEmail Low
111 components/Profile/Badges/ProfileBadge.vue 671 lines Single badge display component with shiny animation, rarity tiers, tooltip, and multi-size rendering all in one. Extract ProfileBadgeTooltip, ProfileBadgeShinyEffect as sub-components Low
112 components/Shared/TeamSpeakViewer.vue 1056 lines Server tree viewer with channel groups, user presence, identity matching, and expand/collapse. Extract TeamspeakChannelGroup, TeamspeakChannelRow, TeamspeakUserRow Low
113 components/Forum/ForumModalAddDiscussion.vue 583 lines Discussion creation modal with topic picker, NSFW toggle, content rules gate, Markdown editor, and draft management. Extract ForumDraftManager, move validation to a composable Low
116 components/Community/ProjectCard.vue 411 lines Three distinct rendering modes (ultraCompact, compact, default) are all in one template with 3-way branching at every level. Consider extracting ProjectCardUltraCompact and ProjectCardCompact as named slots or sub-components Low
121 components/Shared/FileUpload.vue 470 lines Handles two fundamentally different layouts (variant: 'asset' vs 'avatar') with interleaved conditional CSS and aspect-ratio logic. Consider splitting into FileUploadAsset.vue and FileUploadAvatar.vue backed by a shared useFileUpload composable (drag-drop, validation, preview URL management, processFile, checkImageExists) Low
122 components/Admin/Events/EventForm.vue 509 lines Duration field (days/hours/minutes split + conversion to/from total minutes) and the custom Calendar date-picker wrapper are reusable patterns duplicated across forms. Extract EventDurationInput and AdminDateTimePicker as shared form sub-components Low
123 pages/admin/users.vue 475 lines Dual delete path bug fixed - handleUserDelete now uses admin-user-delete edge function. Remaining: extract useAdminUserActions(config) composable for the ban/unban/delete action pipeline and runActionWithDetailLoading helper Low

Composable Design & Consistency Issues

# File(s) Issue Priority
154 composables/useCacheGameAssets.ts localStorage used directly - this composable is the only cache composable that bypasses useCache and writes to window.localStorage directly with hand-rolled JSON serialization, TTL checking, and try/catch suppression. All other asset/data composables use the useCache in-memory store. The inconsistency means game asset cache entries survive page reloads (possibly desirable) but are invisible to cache.invalidateByPattern and cache.clearCache, and are never cleaned up by the shared TTL sweep. The localStorage approach is intentional - game asset URLs are CDN paths that are worth caching across hard reloads (in-memory useCache is cleared on reload). The rationale and tradeoffs are documented in the composable's JSDoc. If cross-reload persistence becomes a common need, extract a usePersistentCache composable and adopt it here. Medium
156 composables/useAdminPermissions.ts Convenience computed explosion - the composable exposes 30+ pre-computed booleans (canManageUsers, canViewUsers, canModifyUsers, canDeleteUsers, canManageEvents, ...). Most are used in only one or two components. The hasPermission and hasAnyPermission functions are already returned and cover all cases dynamically. The pre-computed properties add maintenance burden every time a new resource type is added. Consider removing all the named computeds and letting callers use the raw helpers. Low