Skip to content

Commit 45a1416

Browse files
authored
feat(ui): migrates to daisyUI + Kobalte with visual/UX improvements (#15)
* feat(actions): redesigns to workflow summary cards with failure emphasis * feat(shared): adds SortDropdown component for toolbar sort controls * feat(dashboard): constrains content area to max-w-6xl for readability * feat(issues): collapse-with-summary repo groups and sort dropdown * feat(pull-requests): collapse-with-summary repo groups and sort dropdown * fix(dashboard): address review findings for a11y and consistency * fix(dashboard): removes double px-4 padding and aligns ActionsTab summary * style: adds dark-mode scrollbar colors * fix(layout): cleanup padding and alignment * feat(ui): installs daisyUI and Kobalte, configures theme infrastructure * feat(settings): refactors settings page with daisyUI, theme picker, and extracted components * feat(layout): migrate header, tabs, filter bar to daisyUI * feat(shared): migrates display components to daisyUI styling * feat(onboarding): migrate onboarding and login pages to daisyUI * feat(shared): migrates interactive components to Kobalte Select and daisyUI * feat(notifications): migrate toast and drawer to Kobalte and corvu * feat(dashboard): migrates row components and popover to daisyUI and Kobalte * feat(dashboard): migrates dashboard pages and tabs to daisyUI tokens * chore(ui): removes legacy dark mode system and unused components * fix(ui): addresses review findings for semantic color consistency * fix(ui): improves daisyUI visual integration with proper component styling * fix(ui): adds visual depth with shadows and borders * fix(test): updates Header rate limit tests for daisyUI class tokens * refactor(ui): moves rate limit from header to footer * feat(theme): adds auto system detection, reorders theme picker * refactor(ui): moves rate limit to footer with daisyUI tooltip * fix(e2e): updates tests for Kobalte Tabs and ThemePicker buttons * fix(settings): links org access to authorized apps page * feat(ui): adds slow pulse animation for in-progress status dot * feat(ui): adds merge conflict detection and visible badge * feat(ui): shows conflict badge in collapsed repo summary * feat(ui): links status dot to checks tab, +/- to files tab * fix: maps all mergeStateStatus values, restores per-app org URL * feat(dashboard): auto-syncs orgs on dashboard load * feat(dashboard): auto-discovers repos for newly synced orgs * fix(dashboard): auto-syncs orgs only, not repos * fix(api): stops mapping BLOCKED mergeStateStatus as conflict * chore: adds debug logging to notification dispatch
1 parent ef6ecf8 commit 45a1416

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+3067
-1626
lines changed

e2e/settings.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,18 @@ test("back link navigates to dashboard", async ({ page }) => {
8787

8888
// ── Theme change ─────────────────────────────────────────────────────────────
8989

90-
test("changing theme to dark adds dark class to html element", async ({
90+
test("changing theme to dark applies data-theme attribute", async ({
9191
page,
9292
}) => {
9393
await setupAuth(page);
9494
await page.goto("/settings");
9595

96-
// Locate the Theme setting row by its label text, then find its <select> child.
97-
const themeSelect = page.getByRole("combobox").filter({ has: page.locator('option[value="dark"]') });
98-
await themeSelect.selectOption("dark");
96+
// ThemePicker uses buttons with aria-label "Theme: <name>"
97+
const darkBtn = page.getByRole("button", { name: "Theme: dark" });
98+
await darkBtn.click();
9999

100100
const htmlElement = page.locator("html");
101-
await expect(htmlElement).toHaveClass(/dark/);
101+
await expect(htmlElement).toHaveAttribute("data-theme", "dark");
102102
});
103103

104104
// ── Sign out ─────────────────────────────────────────────────────────────────

e2e/smoke.spec.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,35 +134,35 @@ test("dashboard loads with tab bar visible", async ({ page }) => {
134134
await setupAuth(page);
135135
await page.goto("/dashboard");
136136

137-
const nav = page.getByRole("navigation", { name: /dashboard tabs/i });
138-
await expect(nav).toBeVisible();
137+
const tablist = page.getByRole("tablist");
138+
await expect(tablist).toBeVisible();
139139

140-
await expect(page.getByRole("button", { name: /^issues/i })).toBeVisible();
140+
await expect(page.getByRole("tab", { name: /^issues/i })).toBeVisible();
141141
await expect(
142-
page.getByRole("button", { name: /^pull requests/i })
142+
page.getByRole("tab", { name: /^pull requests/i })
143143
).toBeVisible();
144-
await expect(page.getByRole("button", { name: /^actions/i })).toBeVisible();
144+
await expect(page.getByRole("tab", { name: /^actions/i })).toBeVisible();
145145
});
146146

147147
test("switching tabs changes active tab indicator", async ({ page }) => {
148148
await setupAuth(page);
149149
await page.goto("/dashboard");
150150

151-
const issuesBtn = page.getByRole("button", { name: /^issues/i });
152-
const prBtn = page.getByRole("button", { name: /^pull requests/i });
153-
const actionsBtn = page.getByRole("button", { name: /^actions/i });
151+
const issuesTab = page.getByRole("tab", { name: /^issues/i });
152+
const prTab = page.getByRole("tab", { name: /^pull requests/i });
153+
const actionsTab = page.getByRole("tab", { name: /^actions/i });
154154

155155
// Default tab should be issues (or whatever config says; we didn't set defaultTab)
156-
await expect(issuesBtn).toBeVisible();
156+
await expect(issuesTab).toBeVisible();
157157

158158
// Click Pull Requests tab
159-
await prBtn.click();
160-
await expect(prBtn).toHaveAttribute("aria-current", "page");
161-
await expect(issuesBtn).not.toHaveAttribute("aria-current", "page");
159+
await prTab.click();
160+
await expect(prTab).toHaveAttribute("aria-selected", "true");
161+
await expect(issuesTab).not.toHaveAttribute("aria-selected", "true");
162162

163163
// Click Actions tab
164-
await actionsBtn.click();
165-
await expect(actionsBtn).toHaveAttribute("aria-current", "page");
164+
await actionsTab.click();
165+
await expect(actionsTab).toHaveAttribute("aria-selected", "true");
166166
});
167167

168168
test("dashboard shows empty state with no data", async ({ page }) => {
@@ -171,8 +171,8 @@ test("dashboard shows empty state with no data", async ({ page }) => {
171171

172172
// With empty mocked responses the dashboard should not show a loading spinner
173173
// indefinitely — wait for the tab bar to appear then confirm no data rows
174-
const nav = page.getByRole("navigation", { name: /dashboard tabs/i });
175-
await expect(nav).toBeVisible();
174+
const tablist = page.getByRole("tablist");
175+
await expect(tablist).toBeVisible();
176176

177177
// The issues tab content area should render (even if empty)
178178
await expect(page.getByRole("main")).toBeVisible();

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
"test:e2e": "E2E_PORT=$(node -e \"const s=require('net').createServer();s.listen(0,()=>{console.log(s.address().port);s.close()})\") playwright test"
1616
},
1717
"dependencies": {
18+
"@kobalte/core": "^0.13.11",
1819
"@octokit/core": "^7.0.6",
1920
"@octokit/plugin-paginate-rest": "^14.0.0",
2021
"@octokit/plugin-retry": "^8.1.0",
2122
"@octokit/plugin-throttling": "^11.0.3",
2223
"@solidjs/router": "^0.16.1",
24+
"corvu": "^0.7.2",
2325
"idb": "^8.0.3",
2426
"solid-js": "^1.9.11",
2527
"zod": "^4.3.6"
@@ -31,6 +33,7 @@
3133
"@solidjs/testing-library": "^0.8.10",
3234
"@tailwindcss/vite": "^4.2.2",
3335
"@testing-library/user-event": "^14.6.1",
36+
"daisyui": "^5.5.19",
3437
"fake-indexeddb": "^6.2.5",
3538
"happy-dom": "^20.8.4",
3639
"tailwindcss": "^4.2.2",

0 commit comments

Comments
 (0)