Move the new-project form into the dashboard grid as a tile
It now sits last in .dashboard__grid, styled like a project-card (dashed border to read as an action rather than a project) instead of as a separate form below the grid. Relabel it 'Create a project' and add a 'Name' placeholder to the input. Also drop the now-redundant 'no projects yet' empty-state message -- the grid always renders since the create tile lives inside it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ Each user owns **projects**, and each project holds ordered **cards**.
|
|||||||
| 8 | Passwordless login — magic-link by default, password login behind a toggle | ✅ done |
|
| 8 | Passwordless login — magic-link by default, password login behind a toggle | ✅ done |
|
||||||
| 9 | Per-project card statuses ("To do" / "Doing" / "Done"); status chip, new cards start with none | ✅ done |
|
| 9 | Per-project card statuses ("To do" / "Doing" / "Done"); status chip, new cards start with none | ✅ done |
|
||||||
| 10 | Project view — full-width, tabbed: alphabetical "All tasks" list + "Kanban" board, per-column drag ordering | ✅ done |
|
| 10 | Project view — full-width, tabbed: alphabetical "All tasks" list + "Kanban" board, per-column drag ordering | ✅ done |
|
||||||
| 11 | Persistent left sidebar (Dashboard link + project dropdown); dashboard = grid of project tiles + new-project form | ✅ done |
|
| 11 | Persistent left sidebar (Dashboard link + project dropdown); dashboard = grid of project tiles + a "Create a project" tile | ✅ done |
|
||||||
| 12 | Passwordless-only auth — registration and password login removed; a magic link is the sole way in, and creates the account if needed | ✅ done |
|
| 12 | Passwordless-only auth — registration and password login removed; a magic link is the sole way in, and creates the account if needed | ✅ done |
|
||||||
| 13 | Global inbox — cards can have no project; moved into the sidebar, drag in/out of any project's kanban columns | ✅ done |
|
| 13 | Global inbox — cards can have no project; moved into the sidebar, drag in/out of any project's kanban columns | ✅ done |
|
||||||
| 14 | New-project form moved to the dashboard; sidebar project list is now a switcher dropdown; Kanban is a project's default tab | ✅ done |
|
| 14 | New-project form moved to the dashboard; sidebar project list is now a switcher dropdown; Kanban is a project's default tab | ✅ done |
|
||||||
|
|||||||
+4
-3
@@ -58,9 +58,10 @@ it also works as a project switcher from anywhere. `<RouterView
|
|||||||
projects always does a fresh load.
|
projects always does a fresh load.
|
||||||
|
|
||||||
`/` redirects to `/dashboard` (`DashboardView.vue`): a full-width grid linking
|
`/` redirects to `/dashboard` (`DashboardView.vue`): a full-width grid linking
|
||||||
to each project (title + card count), then a **new-project form** directly
|
to each project (title + card count), with a **"Create a project" tile**
|
||||||
below it (creating one stays on the dashboard; the grid and the sidebar
|
styled to match sitting last in the same grid (creating one stays on the
|
||||||
dropdown both pick it up via the shared `projects` store). Signed-out routes
|
dashboard; the grid and the sidebar dropdown both pick it up via the shared
|
||||||
|
`projects` store). Signed-out routes
|
||||||
(`/login`, `/verify-email`) render without the sidebar.
|
(`/login`, `/verify-email`) render without the sidebar.
|
||||||
|
|
||||||
## Inbox
|
## Inbox
|
||||||
|
|||||||
+19
-1
@@ -360,6 +360,25 @@ h1 {
|
|||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project-card--new {
|
||||||
|
border-style: dashed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-card--new label {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.3rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-card--new input {
|
||||||
|
padding: 0.55rem 0.7rem;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--bg);
|
||||||
|
color: var(--text);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- project detail: cards ------------------------------------------ */
|
/* --- project detail: cards ------------------------------------------ */
|
||||||
|
|
||||||
.cards {
|
.cards {
|
||||||
@@ -743,7 +762,6 @@ h1 {
|
|||||||
margin: 1.25rem 0;
|
margin: 1.25rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form--new-project,
|
|
||||||
.form--new-card {
|
.form--new-card {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
padding-top: 1.25rem;
|
padding-top: 1.25rem;
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ async function onCreate() {
|
|||||||
<div class="dashboard">
|
<div class="dashboard">
|
||||||
<p v-if="loadError" class="form-error">{{ loadError }}</p>
|
<p v-if="loadError" class="form-error">{{ loadError }}</p>
|
||||||
<p v-else-if="projects.loading && !projects.loaded" class="muted">Loading…</p>
|
<p v-else-if="projects.loading && !projects.loaded" class="muted">Loading…</p>
|
||||||
<p v-else-if="projects.projects.length === 0" class="muted">
|
|
||||||
No projects yet — create one below. Anything uncategorised lives in the
|
|
||||||
inbox, in the sidebar.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div v-else class="dashboard__grid">
|
<div v-else class="dashboard__grid">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
@@ -60,28 +56,28 @@ async function onCreate() {
|
|||||||
{{ project.card_count }} card{{ project.card_count === 1 ? '' : 's' }}
|
{{ project.card_count }} card{{ project.card_count === 1 ? '' : 's' }}
|
||||||
</span>
|
</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
|
<form class="project-card project-card--new" @submit.prevent="onCreate">
|
||||||
|
<label>
|
||||||
|
<span class="project-card__title">Create a project</span>
|
||||||
|
<input v-model="title" type="text" maxlength="255" placeholder="Name" required :disabled="atLimit" />
|
||||||
|
<small v-if="createError?.fieldError('title')" class="field-error">
|
||||||
|
{{ createError.fieldError('title') }}
|
||||||
|
</small>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<p v-if="createError && Object.keys(createError.details).length === 0" class="form-error">
|
||||||
|
{{ createError.message }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button type="submit" :disabled="submitting || atLimit">
|
||||||
|
{{ submitting ? 'Creating…' : 'Create project' }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<p v-if="atLimit" class="hint">
|
||||||
|
You have reached the maximum of {{ MAX_PROJECTS }} projects.
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="form form--new-project" @submit.prevent="onCreate">
|
|
||||||
<label>
|
|
||||||
<span>New project title</span>
|
|
||||||
<input v-model="title" type="text" maxlength="255" required :disabled="atLimit" />
|
|
||||||
<small v-if="createError?.fieldError('title')" class="field-error">
|
|
||||||
{{ createError.fieldError('title') }}
|
|
||||||
</small>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<p v-if="createError && Object.keys(createError.details).length === 0" class="form-error">
|
|
||||||
{{ createError.message }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<button type="submit" :disabled="submitting || atLimit">
|
|
||||||
{{ submitting ? 'Creating…' : 'Create project' }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<p v-if="atLimit" class="hint">
|
|
||||||
You have reached the maximum of {{ MAX_PROJECTS }} projects.
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user