fix: round 3 UI gaps - habit edit dialog, domain edit, empty states, domain name resolution

This commit is contained in:
2026-07-28 15:02:01 +00:00
parent a06d34264d
commit 9ddab4e5a5
6 changed files with 341 additions and 63 deletions
+28 -11
View File
@@ -48,9 +48,11 @@ export default function ProjectDetailPage() {
const [tasks, setTasks] = useState<Task[]>([]);
const [milestones, setMilestones] = useState<Milestone[]>([]);
const [loading, setLoading] = useState(true);
const [domainMap, setDomainMap] = useState<Map<string, string>>(new Map());
useEffect(() => {
if (projectId) {
fetchDomains();
fetchProject();
fetchTasks();
fetchMilestones();
@@ -58,6 +60,18 @@ export default function ProjectDetailPage() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [projectId]);
async function fetchDomains() {
try {
const res = await fetch('/api/domains?sort=sort_order');
if (res.ok) {
const data = await res.json();
const map = new Map<string, string>();
for (const d of data.items || []) map.set(d.id, d.name);
setDomainMap(map);
}
} catch {}
}
async function fetchProject() {
try {
const response = await fetch(`/api/projects/${projectId}`);
@@ -138,17 +152,20 @@ export default function ProjectDetailPage() {
<p className="mt-1 text-muted-foreground">{project.description}</p>
)}
</div>
<Badge
variant={
project.status === 'active'
? 'default'
: project.status === 'paused'
? 'secondary'
: 'outline'
}
>
{project.status}
</Badge>
<div className="flex items-center gap-2">
<Badge
variant={
project.status === 'active'
? 'default'
: project.status === 'paused'
? 'secondary'
: 'outline'
}
>
{project.status}
</Badge>
<Badge variant="outline">{domainMap.get(project.domain) || project.domain}</Badge>
</div>
</div>
{/* Project stats */}
+16 -2
View File
@@ -64,6 +64,7 @@ export default function ReportsPage() {
const [showTemplates, setShowTemplates] = useState(false);
const [error, setError] = useState<string | null>(null);
const [saveStatus, setSaveStatus] = useState<'Saved' | 'Saving' | 'Failed'>('Saved');
const [domainMap, setDomainMap] = useState<Map<string, string>>(new Map());
const [reportToDelete, setReportToDelete] = useState<Report | null>(null);
const [deleting, setDeleting] = useState(false);
const pendingSave = useRef<{ id: string; updates: Partial<Report> } | null>(null);
@@ -72,11 +73,24 @@ export default function ReportsPage() {
useEffect(() => {
fetchReports();
fetchDomains();
return () => {
if (saveTimer.current) clearTimeout(saveTimer.current);
};
}, []);
async function fetchDomains() {
try {
const res = await fetch('/api/domains?sort=sort_order');
if (res.ok) {
const data = await res.json();
const map = new Map<string, string>();
for (const d of data.items || []) map.set(d.id, d.name);
setDomainMap(map);
}
} catch {}
}
async function fetchReports() {
setLoading(true);
setError(null);
@@ -284,7 +298,7 @@ export default function ReportsPage() {
{report.report_type}
</Badge>
<Badge variant="outline" className="text-xs">
{report.domain}
{domainMap.get(report.domain) || report.domain}
</Badge>
</div>
</div>
@@ -328,7 +342,7 @@ export default function ReportsPage() {
</div>
<div className="mt-2 flex gap-2">
<Badge variant="outline">{selectedReport.report_type}</Badge>
<Badge variant="outline">{selectedReport.domain}</Badge>
<Badge variant="outline">{domainMap.get(selectedReport.domain) || selectedReport.domain}</Badge>
{selectedReport.date_range_start && selectedReport.date_range_end && (
<Badge variant="outline" className="gap-1">
<Clock className="h-3 w-3" />