✨feature: Add projects homepage and support for adding new projects
This commit is contained in:
+96
-8
@@ -15,15 +15,19 @@ use IronKanban\Service\BoardService;
|
||||
$projectRepository = new ProjectRepository();
|
||||
$projects = $projectRepository->getAll();
|
||||
$requestedProject = isset($_GET['project']) ? trim((string) $_GET['project']) : '';
|
||||
$activeProjectId = $requestedProject !== '' ? $requestedProject : ($projects[0]->id ?? '');
|
||||
$activeProjectId = $requestedProject;
|
||||
$boardService = new BoardService();
|
||||
$initialState = null;
|
||||
$loadError = null;
|
||||
$showDashboard = $requestedProject === '';
|
||||
|
||||
if ($activeProjectId !== '') {
|
||||
try {
|
||||
$initialState = $boardService->getBoardState($activeProjectId);
|
||||
$showDashboard = false;
|
||||
} catch (Throwable $exception) {
|
||||
$initialState = null;
|
||||
$showDashboard = true;
|
||||
$loadError = 'The requested project could not be loaded. Pick another project or create a new one.';
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -44,6 +48,16 @@ if ($activeProjectId !== '') {
|
||||
<h1>IronKanban</h1>
|
||||
<p class="sidebar-copy">Projects stay as flat files, while the UI gives you drag-and-drop columns, quick edits, notes, and polling-based refreshes.</p>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-actions">
|
||||
<a class="button ghost" href="/">All Projects</a>
|
||||
<?php if ($showDashboard) : ?>
|
||||
<a class="button primary" href="#project-create-form">New Project</a>
|
||||
<?php elseif ($initialState !== null) : ?>
|
||||
<a class="button primary" href="/?project=<?php echo rawurlencode((string) $initialState['project']['id']); ?>">Open Current Board</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<section class="project-list">
|
||||
<div class="section-heading">
|
||||
<h2>Projects</h2>
|
||||
@@ -55,13 +69,14 @@ if ($activeProjectId !== '') {
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<?php foreach ($projects as $project) : ?>
|
||||
<a class="project-link<?php echo $project->id === $activeProjectId ? ' active' : ''; ?>" href="/?project=<?php echo rawurlencode($project->id); ?>">
|
||||
<a class="project-link<?php echo $project->id === $activeProjectId && !$showDashboard ? ' active' : ''; ?>" href="/?project=<?php echo rawurlencode($project->id); ?>">
|
||||
<strong><?php echo e($project->title); ?></strong>
|
||||
<span><?php echo e($project->id); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section class="project-root">
|
||||
<div class="section-heading">
|
||||
<h2>Storage</h2>
|
||||
@@ -70,11 +85,83 @@ if ($activeProjectId !== '') {
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<main class="workspace" id="app" data-project-id="<?php echo e($activeProjectId); ?>">
|
||||
<?php if ($initialState === null) : ?>
|
||||
<section class="hero empty-state">
|
||||
<h2>No project selected</h2>
|
||||
<p>Create or copy a project folder into <code><?php echo e(project_root()); ?></code> using the markdown layout from the notes.</p>
|
||||
<main class="workspace" id="app" data-project-id="<?php echo e($showDashboard ? '' : $activeProjectId); ?>" data-view="<?php echo e($showDashboard ? 'dashboard' : 'board'); ?>">
|
||||
<?php if ($showDashboard) : ?>
|
||||
<section class="dashboard-intro hero">
|
||||
<div>
|
||||
<p class="eyebrow">Project Dashboard</p>
|
||||
<h2>Choose a project or start a fresh one</h2>
|
||||
<p class="project-description">Each project stays as markdown on disk, with its own notes, tasks, board definition, and revision tracking.</p>
|
||||
</div>
|
||||
<div class="dashboard-intro-meta">
|
||||
<span><?php echo count($projects); ?> project<?php echo count($projects) === 1 ? '' : 's'; ?></span>
|
||||
<span>Stored in <code><?php echo e(project_root()); ?></code></span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<?php if ($loadError !== null) : ?>
|
||||
<section class="hero error-state">
|
||||
<h2>Project unavailable</h2>
|
||||
<p><?php echo e($loadError); ?></p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<section class="dashboard-grid">
|
||||
<section class="project-create-panel">
|
||||
<div class="section-heading">
|
||||
<h2>Create Project</h2>
|
||||
</div>
|
||||
<form class="project-create-form" id="project-create-form" data-project-form>
|
||||
<label>
|
||||
<span>Title</span>
|
||||
<input type="text" name="title" maxlength="200" required placeholder="Release Planning">
|
||||
</label>
|
||||
<label>
|
||||
<span>Slug</span>
|
||||
<input type="text" name="slug" maxlength="200" placeholder="release-planning">
|
||||
</label>
|
||||
<label>
|
||||
<span>Description</span>
|
||||
<textarea name="body" rows="7" placeholder="Describe the project, goals, and context."></textarea>
|
||||
</label>
|
||||
<div class="project-create-actions">
|
||||
<p class="form-hint">Leave the slug blank to generate it automatically.</p>
|
||||
<button type="submit" class="button primary">Create Project</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="projects-panel">
|
||||
<div class="section-heading">
|
||||
<h2>Projects</h2>
|
||||
<span><?php echo count($projects); ?></span>
|
||||
</div>
|
||||
<?php if ($projects === []) : ?>
|
||||
<div class="empty-state">
|
||||
<h3>No projects yet</h3>
|
||||
<p>Create your first project to generate a board with default kanban columns.</p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="project-card-grid">
|
||||
<?php foreach ($projects as $project) : ?>
|
||||
<?php
|
||||
$preview = trim(preg_replace('/\s+/', ' ', $project->body) ?? '');
|
||||
$preview = $preview !== '' ? $preview : 'No project description yet.';
|
||||
$preview = strlen($preview) > 180 ? substr($preview, 0, 177) . '...' : $preview;
|
||||
?>
|
||||
<a class="project-card" href="/?project=<?php echo rawurlencode($project->id); ?>">
|
||||
<p class="eyebrow">Project</p>
|
||||
<h3><?php echo e($project->title); ?></h3>
|
||||
<p class="project-card-body"><?php echo e($preview); ?></p>
|
||||
<div class="project-card-footer">
|
||||
<span class="project-card-slug"><?php echo e($project->id); ?></span>
|
||||
<span class="project-card-cta">Open Board</span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</section>
|
||||
<?php else : ?>
|
||||
<header class="workspace-header">
|
||||
@@ -84,6 +171,7 @@ if ($activeProjectId !== '') {
|
||||
<p class="project-description"><?php echo nl2br(e((string) $initialState['project']['body'])); ?></p>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<a class="button ghost" href="/">All Projects</a>
|
||||
<button type="button" class="button ghost" data-action="new-column">New Column</button>
|
||||
<button type="button" class="button primary" data-action="new-task">New Task</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user