feat: implement Story 2.2 — Priority Alerts Panel with UI fixes

Add PriorityAlertsPanel component to the dashboard, update DashboardController
with alert logic, and apply misc UI fixes across sidebar, forms, and pages.
Includes epic-1 retrospective and sprint status update.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-20 12:33:27 +00:00
parent a2ab6f365d
commit 4807376c49
1196 changed files with 170844 additions and 32 deletions

View File

@@ -11,6 +11,7 @@ import {
Users,
} from 'lucide-vue-next';
import { computed } from 'vue';
import PriorityAlertsPanel from '@/components/dashboard/PriorityAlertsPanel.vue';
import StatCard from '@/components/dashboard/StatCard.vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
@@ -163,6 +164,12 @@ function navigateToDeclaration(declaration: DashboardDeclaration): void {
/>
</div>
<!-- Priority Alerts Panel -->
<PriorityAlertsPanel
:alerts="alerts"
:view-all-url="viewAllAlertsUrl"
/>
<!-- Urgent Declarations Table -->
<div class="space-y-4">
<div class="flex items-center justify-between">

View File

@@ -1,18 +1,10 @@
<script setup lang="ts">
import { Head, Link } from '@inertiajs/vue3';
import {
Building2,
Calendar,
FileCheck,
Mail,
Shield,
Users,
} from 'lucide-vue-next';
import { Calendar, FileCheck, Mail, Shield, Users } from 'lucide-vue-next';
import AppLogoIcon from '@/components/AppLogoIcon.vue';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,

View File

@@ -29,7 +29,7 @@ type Props = {
csrfToken: string;
};
const props = defineProps<Props>();
defineProps<Props>();
const page = usePage<{ flash?: { type?: string; message?: string } }>();
const flash = computed(() => page.props.flash);

View File

@@ -1,7 +1,6 @@
<script setup lang="ts">
import { Head, Link } from '@inertiajs/vue3';
import { Building2, FileText, FolderOpen } from 'lucide-vue-next';
import { computed } from 'vue';
import DeclarationCalendar from '@/components/clients/DeclarationCalendar.vue';
import Heading from '@/components/Heading.vue';
import { Badge } from '@/components/ui/badge';

View File

@@ -5,8 +5,6 @@ import { computed, ref, watch, nextTick } from 'vue';
import MessageBubble from '@/components/declarations/MessageBubble.vue';
import Heading from '@/components/Heading.vue';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';

View File

@@ -170,7 +170,9 @@ watch(
(members) => {
if (!permissionsMember.value || !showPermissionsDialog.value) return;
const updated = members.find(
(m) => m.workspace_user_id === permissionsMember.value!.workspace_user_id,
(m) =>
m.workspace_user_id ===
permissionsMember.value!.workspace_user_id,
);
if (updated) {
permissionsMember.value = updated;
@@ -547,7 +549,7 @@ const breadcrumbs: BreadcrumbItem[] = [
isOwner &&
getMemberData(member)!
.role ===
ROLE_MANAGER
ROLE_MANAGER
"
@click="
openPermissionsDialog(

View File

@@ -4,7 +4,6 @@ import Heading from '@/components/Heading.vue';
import UserForm from '@/components/UserForm.vue';
import type { UserFormData } from '@/components/UserForm.vue';
import AppLayout from '@/layouts/AppLayout.vue';
import type { BreadcrumbItem } from '@/types';
type Props = {
indexUrl: string;