Files
mkd/components/pr/ResidentReportPage.tsx
2026-02-04 00:17:04 +05:00

123 lines
3.9 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from 'react';
import { ResidentReport } from '../../types';
import { apiClient } from '../../services/apiClient';
import { ResidentReportView } from './ResidentReportView';
import { ArrowLeft, Loader2, AlertCircle } from 'lucide-react';
interface ResidentReportPageProps {
reportId: string | number;
onBack: () => void;
}
export const ResidentReportPage: React.FC<ResidentReportPageProps> = ({ reportId, onBack }) => {
const [report, setReport] = useState<ResidentReport | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
loadReport();
}, [reportId]);
const loadReport = async () => {
try {
setLoading(true);
setError(null);
const data = await apiClient.get<ResidentReport>(`/pr/reports/${reportId}`);
setReport(data);
} catch (err: any) {
console.error('Error loading report:', err);
setError(err.message || 'Не удалось загрузить отчет');
} finally {
setLoading(false);
}
};
if (loading) {
return (
<div className="flex justify-center items-center py-12">
<Loader2 className="w-8 h-8 animate-spin text-primary-600" />
</div>
);
}
if (error) {
return (
<div className="bg-white rounded-2xl border border-red-200 shadow-sm p-6">
<div className="flex items-center gap-2 text-red-600 mb-4">
<AlertCircle className="w-5 h-5" />
<p className="font-medium">Ошибка: {error}</p>
</div>
<button
onClick={onBack}
className="text-primary-600 hover:text-primary-700 font-medium"
>
Назад
</button>
</div>
);
}
if (!report) {
return (
<div className="bg-white rounded-2xl border border-slate-200 shadow-sm p-6 text-center">
<p className="text-slate-600">Отчет не найден</p>
<button
onClick={onBack}
className="mt-4 text-primary-600 hover:text-primary-700 font-medium"
>
Назад
</button>
</div>
);
}
const period = report.periodStart && report.periodEnd
? `${new Date(report.periodStart).toLocaleDateString('ru-RU')} - ${new Date(report.periodEnd).toLocaleDateString('ru-RU')}`
: report.month;
return (
<div className="space-y-6 animate-fade-in">
{/* Заголовок и навигация */}
<div className="flex items-center gap-4">
<button
onClick={onBack}
className="p-2 hover:bg-slate-100 rounded-lg transition-colors"
>
<ArrowLeft className="w-5 h-5 text-slate-600" />
</button>
<div className="flex-1">
<h1 className="text-2xl font-bold text-slate-800">
Отчет собственникам МКД
</h1>
<p className="text-sm text-slate-500 mt-1">
{report.address || `Отчет #${report.id}`} {period}
</p>
</div>
{report.status === 'draft' && (
<span className="px-3 py-1 bg-amber-100 text-amber-700 rounded-lg text-sm font-medium">
Черновик
</span>
)}
{report.status === 'published' && (
<span className="px-3 py-1 bg-emerald-100 text-emerald-700 rounded-lg text-sm font-medium">
Опубликован
</span>
)}
</div>
{/* Контент отчета */}
{report.content ? (
<ResidentReportView
content={report.content}
buildingAddress={report.address}
period={period}
/>
) : (
<div className="bg-white rounded-2xl border border-slate-200 shadow-sm p-12 text-center">
<p className="text-slate-600">Контент отчета не загружен</p>
</div>
)}
</div>
);
};