diff --git a/api/src/Kurs.Platform.Application/Reports/ReportAppService.cs b/api/src/Kurs.Platform.Application/Reports/ReportAppService.cs index 3b05f7f0..55f3d3f8 100644 --- a/api/src/Kurs.Platform.Application/Reports/ReportAppService.cs +++ b/api/src/Kurs.Platform.Application/Reports/ReportAppService.cs @@ -42,8 +42,9 @@ public class ReportAppService : PlatformAppService, IReportAppService public async Task> GetTemplatesAsync(GetReportTemplatesInput input) { - // IQueryable başlat + // IQueryable başlat - Parameters'ı include et var query = await _reportTemplateRepository.GetQueryableAsync(); + query = query.Include(x => x.Parameters); // Filtreleme if (!string.IsNullOrWhiteSpace(input.Filter)) @@ -84,7 +85,15 @@ public class ReportAppService : PlatformAppService, IReportAppService public async Task GetTemplateAsync(Guid id) { - var template = await _reportTemplateRepository.GetAsync(id); + var query = await _reportTemplateRepository.GetQueryableAsync(); + var template = await query + .Include(x => x.Parameters) + .FirstOrDefaultAsync(x => x.Id == id); + + if (template == null) + { + throw new ArgumentException($"Template with id {id} not found"); + } return MapToReportTemplateDto(template); } diff --git a/ui/src/components/reports/Dashboard.tsx b/ui/src/components/reports/Dashboard.tsx index 23edd2ec..b0a3a987 100644 --- a/ui/src/components/reports/Dashboard.tsx +++ b/ui/src/components/reports/Dashboard.tsx @@ -18,7 +18,6 @@ export const Dashboard: React.FC = () => { updateTemplate, deleteTemplate, generateReport, - loadTemplatesByCategory, } = useReports() const tumuCategory = useMemo( @@ -36,7 +35,7 @@ export const Dashboard: React.FC = () => { const [editingTemplate, setEditingTemplate] = useState(null) const [generatingTemplate, setGeneratingTemplate] = useState(null) const [searchQuery, setSearchQuery] = useState('') - const [selectedCategory, setSelectedCategory] = useState(null) + const [selectedCategory, setSelectedCategory] = useState(tumuCategory) const { translate } = useLocalization() // Create category options with "Tümü" at the top @@ -45,35 +44,36 @@ export const Dashboard: React.FC = () => { return categoryNames }, [categories, tumuCategory]) - // Set default category when component mounts - useEffect(() => { - if (!selectedCategory) { - setSelectedCategory(tumuCategory) - } - }, [tumuCategory, selectedCategory]) - - // Handle category change - useEffect(() => { - if (selectedCategory) { - loadTemplatesByCategory(selectedCategory.name) - } - }, [selectedCategory, loadTemplatesByCategory]) - - // Load templates for default category on mount - useEffect(() => { - loadTemplatesByCategory('Tümü') - }, []) - + // Filter templates based on selected category and search query const filteredTemplates = useMemo(() => { - return templates.filter((template) => { - const matchesSearch = - template.name.toLowerCase().includes(searchQuery.toLowerCase()) || - template.description?.toLowerCase().includes(searchQuery.toLowerCase()) || - template.tags.some((tag: any) => tag.toLowerCase().includes(searchQuery.toLowerCase())) + let filtered = templates + + // Filter by category (if not "Tümü") + if (selectedCategory && selectedCategory.name !== 'Tümü') { + filtered = filtered.filter(template => template.categoryName === selectedCategory.name) + } + + // Filter by search query + if (searchQuery) { + filtered = filtered.filter((template) => { + const matchesSearch = + template.name.toLowerCase().includes(searchQuery.toLowerCase()) || + template.description?.toLowerCase().includes(searchQuery.toLowerCase()) || + template.tags.some((tag: any) => tag.toLowerCase().includes(searchQuery.toLowerCase())) - return matchesSearch - }) - }, [templates, searchQuery]) + return matchesSearch + }) + } + + return filtered + }, [templates, selectedCategory, searchQuery]) + + // Calculate total parameters + const totalParameters = useMemo(() => { + return filteredTemplates.reduce((sum, template) => { + return sum + (Array.isArray(template.parameters) ? template.parameters.length : 0) + }, 0) + }, [filteredTemplates]) const handleCreateTemplate = () => { setEditingTemplate(null) @@ -174,21 +174,38 @@ export const Dashboard: React.FC = () => { {/* Main Content */}
-
-

- {translate('::' + selectedCategory?.name)} -

- -
-
- {translate('::' + selectedCategory?.description)} +
+
+

+ {translate('::' + selectedCategory?.name)} +

+
+ {translate('::' + selectedCategory?.description)} +
+
+ +
+ {/* Search Input */} +
+ + setSearchQuery(e.target.value)} + className="pl-10 w-64" + /> +
+ + {/* New Template Button */} + +
{/* Stats */} @@ -196,8 +213,10 @@ export const Dashboard: React.FC = () => {
-

Toplam Şablon

-

{templates.length}

+

+ {selectedCategory?.name === 'Tümü' ? 'Toplam Şablon' : 'Kategori Şablonları'} +

+

{filteredTemplates.length}

@@ -220,9 +239,11 @@ export const Dashboard: React.FC = () => {
-

Toplam Parametre

+

+ {selectedCategory?.name === 'Tümü' ? 'Toplam Parametre' : 'Kategori Parametreleri'} +

- {templates.reduce((sum, t) => sum + t.parameters.length, 0)} + {totalParameters}

@@ -231,20 +252,7 @@ export const Dashboard: React.FC = () => {
- {/* Filters */} -
-
-
- - setSearchQuery(e.target.value)} - className="pl-10" - /> -
-
-
+ {/* Templates Grid */} {filteredTemplates.length === 0 ? (
diff --git a/ui/src/components/reports/ReportGenerator.tsx b/ui/src/components/reports/ReportGenerator.tsx index 7ad0aea6..8cfdb023 100644 --- a/ui/src/components/reports/ReportGenerator.tsx +++ b/ui/src/components/reports/ReportGenerator.tsx @@ -72,7 +72,7 @@ export const ReportGenerator: React.FC = ({ <>
{`${template.name} - Rapor Parametreleri`}
-
+

{template.name}

{template.description}

diff --git a/ui/src/components/reports/ReportViewer.tsx b/ui/src/components/reports/ReportViewer.tsx index 7b9e2c95..e5cc103d 100644 --- a/ui/src/components/reports/ReportViewer.tsx +++ b/ui/src/components/reports/ReportViewer.tsx @@ -6,6 +6,7 @@ import html2canvas from 'html2canvas' import jsPDF from 'jspdf' import { ReportGeneratedDto, ReportTemplateDto } from '@/proxy/reports/models' import { useReports } from '@/utils/hooks/useReports' +import { ROUTES_ENUM } from '@/routes/route.constant' export const ReportViewer: React.FC = () => { const { id } = useParams<{ id: string }>() @@ -129,7 +130,7 @@ export const ReportViewer: React.FC = () => {

{error || 'Rapor bulunamadı'}

- @@ -143,7 +144,7 @@ export const ReportViewer: React.FC = () => {

Rapor bulunamadı

- @@ -161,7 +162,7 @@ export const ReportViewer: React.FC = () => {

Aradığınız rapor mevcut değil veya silinmiş olabilir.

- @@ -234,7 +235,7 @@ export const ReportViewer: React.FC = () => {
{/* Header - Print edilmeyecek */}
-
+
diff --git a/ui/src/components/reports/TemplateCard.tsx b/ui/src/components/reports/TemplateCard.tsx index 93178100..8b46da4f 100644 --- a/ui/src/components/reports/TemplateCard.tsx +++ b/ui/src/components/reports/TemplateCard.tsx @@ -51,8 +51,8 @@ export const TemplateCard: React.FC = ({
{/* Footer with date and actions */} -
-
+
+

{new Date(template.lastModificationTime || template.creationTime).toLocaleString('tr-TR', { day: '2-digit', month: '2-digit', @@ -62,34 +62,35 @@ export const TemplateCard: React.FC = ({ })}

-
+
diff --git a/ui/src/routes/route.constant.ts b/ui/src/routes/route.constant.ts index ce5fb0f6..ce83b089 100644 --- a/ui/src/routes/route.constant.ts +++ b/ui/src/routes/route.constant.ts @@ -3,6 +3,9 @@ export const ROUTES_ENUM = { home: '/home', about: '/about', products: '/products', + checkout: '/checkout', + success: '/success', + payment: '/payment', services: '/services', demo: '/demo', blog: '/blog', diff --git a/ui/src/views/public/Checkout.tsx b/ui/src/views/public/Checkout.tsx index e6904c87..4a551b90 100644 --- a/ui/src/views/public/Checkout.tsx +++ b/ui/src/views/public/Checkout.tsx @@ -1,6 +1,7 @@ import { Cart } from '@/components/orders/Cart' import { TenantForm } from '@/components/orders/TenantForm' import { CustomTenantDto } from '@/proxy/config/models' +import { ROUTES_ENUM } from '@/routes/route.constant' import { CartState, clearCart, @@ -33,16 +34,13 @@ const Checkout: React.FC = () => { } const handleBackToCatalog = () => { - navigate('/') + navigate(ROUTES_ENUM.public.home) } - const handleCartClick = () => { - setIsCartOpen(true) - } const handleCheckout = () => { setIsCartOpen(false) - navigate('/checkout') + navigate(ROUTES_ENUM.public.checkout) } const handleUpdateQuantity = (id: string, quantity: number) => { diff --git a/ui/src/views/public/Products.tsx b/ui/src/views/public/Products.tsx index 8ecee516..92431cf0 100644 --- a/ui/src/views/public/Products.tsx +++ b/ui/src/views/public/Products.tsx @@ -2,6 +2,7 @@ import { BillingControls } from '@/components/orders/BillingControls' import { Cart } from '@/components/orders/Cart' import { ProductCatalog } from '@/components/orders/ProductCatalog' import { BillingCycle } from '@/proxy/order/models' +import { ROUTES_ENUM } from '@/routes/route.constant' import { CartState, clearCart, @@ -40,10 +41,10 @@ const Products: React.FC = () => { const handleNavigate = (section: string) => { switch (section) { case 'home': - navigate('/') + navigate(ROUTES_ENUM.protected.dashboard) break default: - navigate('/') + navigate(ROUTES_ENUM.public.home) } } diff --git a/ui/src/views/public/Success.tsx b/ui/src/views/public/Success.tsx index ea31242d..a55cd4ab 100644 --- a/ui/src/views/public/Success.tsx +++ b/ui/src/views/public/Success.tsx @@ -1,4 +1,5 @@ import { OrderSuccess } from '@/components/orders/OrderSuccess' +import { ROUTES_ENUM } from '@/routes/route.constant' import { useLocalization } from '@/utils/hooks/useLocalization' import React, { useState, useEffect } from 'react' import { Helmet } from 'react-helmet' @@ -17,12 +18,12 @@ const Success: React.FC = () => { // Clear order ID from local storage localStorage.removeItem('orderId') } else { - navigate('/') + navigate(ROUTES_ENUM.public.home) } }, [navigate]) const handleBackToShop = () => { - navigate('/') + navigate(ROUTES_ENUM.public.home) } if (!orderId) {