Container Modal problemleri

This commit is contained in:
Sedat ÖZTÜRK 2025-09-16 08:58:13 +03:00
parent 811a575ff7
commit 57796d1177
4 changed files with 635 additions and 710 deletions

View file

@ -82,7 +82,7 @@ define(['./workbox-a959eb95'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812" "revision": "3ca0b8505b4bec776b69afdba2768812"
}, { }, {
"url": "/index.html", "url": "/index.html",
"revision": "0.daul0044rt" "revision": "0.hml46tc2c78"
}], {}); }], {});
workbox.cleanupOutdatedCaches(); workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), { workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), {

View file

@ -26,6 +26,7 @@ import CheckNoteDetails from './CheckNoteDetails'
import CollectionDialog from './CollectionDialog' import CollectionDialog from './CollectionDialog'
import EndorsementDialog from './EndorsementDialog' import EndorsementDialog from './EndorsementDialog'
import Widget from '../../../components/common/Widget' import Widget from '../../../components/common/Widget'
import { Container } from '@/components/shared'
interface CheckNoteManagementProps { interface CheckNoteManagementProps {
checks: FiCheck[] checks: FiCheck[]
@ -662,6 +663,7 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
}) })
return ( return (
<Container>
<div className="space-y-2"> <div className="space-y-2">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -749,45 +751,6 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
</div> </div>
)} )}
{/* Modal Components */}
<CheckForm
check={editingCheck || undefined}
currentAccounts={currentAccounts}
onSave={handleSaveCheck}
onCancel={handleCloseDialogs}
isOpen={showCheckForm}
/>
<PromissoryNoteForm
note={editingNote || undefined}
currentAccounts={currentAccounts}
onSave={handleSaveNote}
onCancel={handleCloseDialogs}
isOpen={showNoteForm}
/>
{selectedItem && (
<CheckNoteDetails item={selectedItem} onClose={handleCloseDialogs} isOpen={showDetails} />
)}
{selectedItem && (
<CollectionDialog
item={selectedItem}
onConfirm={handleConfirmCollection}
onCancel={handleCloseDialogs}
isOpen={showCollectionDialog}
/>
)}
{selectedItem && (
<EndorsementDialog
item={selectedItem}
onConfirm={handleConfirmEndorsement}
onCancel={handleCloseDialogs}
isOpen={showEndorsementDialog}
/>
)}
{/* Tabs */} {/* Tabs */}
<div className="border-b border-gray-200"> <div className="border-b border-gray-200">
<nav className="-mb-px flex space-x-6"> <nav className="-mb-px flex space-x-6">
@ -833,7 +796,9 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
<select <select
value={selectedType} value={selectedType}
onChange={(e) => setSelectedType(e.target.value as CheckTypeEnum | NoteTypeEnum | 'all')} onChange={(e) =>
setSelectedType(e.target.value as CheckTypeEnum | NoteTypeEnum | 'all')
}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
> >
<option value="all">Tüm Türler</option> <option value="all">Tüm Türler</option>
@ -909,6 +874,46 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
</div> </div>
)} )}
</div> </div>
{/* Modal Components */}
<CheckForm
check={editingCheck || undefined}
currentAccounts={currentAccounts}
onSave={handleSaveCheck}
onCancel={handleCloseDialogs}
isOpen={showCheckForm}
/>
<PromissoryNoteForm
note={editingNote || undefined}
currentAccounts={currentAccounts}
onSave={handleSaveNote}
onCancel={handleCloseDialogs}
isOpen={showNoteForm}
/>
{selectedItem && (
<CheckNoteDetails item={selectedItem} onClose={handleCloseDialogs} isOpen={showDetails} />
)}
{selectedItem && (
<CollectionDialog
item={selectedItem}
onConfirm={handleConfirmCollection}
onCancel={handleCloseDialogs}
isOpen={showCollectionDialog}
/>
)}
{selectedItem && (
<EndorsementDialog
item={selectedItem}
onConfirm={handleConfirmEndorsement}
onCancel={handleCloseDialogs}
isOpen={showEndorsementDialog}
/>
)}
</Container>
) )
} }

View file

@ -1,24 +1,17 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import { import { FaUsers, FaPlus, FaSearch, FaEdit, FaEye, FaReceipt } from 'react-icons/fa'
FaUsers,
FaPlus,
FaSearch,
FaEdit,
FaEye,
FaReceipt,
} from "react-icons/fa";
import { import {
FiCurrentAccount, FiCurrentAccount,
AccountTypeEnum, AccountTypeEnum,
RiskGroupEnum, RiskGroupEnum,
FiCurrentAccountMovement, FiCurrentAccountMovement,
FiDocumentTypeEnum, FiDocumentTypeEnum,
} from "../../../types/fi"; } from '../../../types/fi'
import DataTable, { Column } from "../../../components/common/DataTable"; import DataTable, { Column } from '../../../components/common/DataTable'
import CurrentAccountForm from "./CurrentAccountForm"; import CurrentAccountForm from './CurrentAccountForm'
import CurrentAccountDetails from "./CurrentAccountDetails"; import CurrentAccountDetails from './CurrentAccountDetails'
import CurrentAccountMovementForm from "./CurrentAccountMovementForm"; import CurrentAccountMovementForm from './CurrentAccountMovementForm'
import Widget from "../../../components/common/Widget"; import Widget from '../../../components/common/Widget'
import { import {
getAccountTypeColor, getAccountTypeColor,
getAccountTypeText, getAccountTypeText,
@ -26,183 +19,155 @@ import {
getFiDocumentTypeText, getFiDocumentTypeText,
getRiskGroupColor, getRiskGroupColor,
getRiskGroupText, getRiskGroupText,
} from "../../../utils/erp"; } from '../../../utils/erp'
import { Container } from '@/components/shared'
interface CurrentAccountManagementProps { interface CurrentAccountManagementProps {
accounts: FiCurrentAccount[]; accounts: FiCurrentAccount[]
accountMovements: FiCurrentAccountMovement[]; accountMovements: FiCurrentAccountMovement[]
} }
const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
accounts, accounts,
accountMovements, accountMovements,
}) => { }) => {
const [activeTab, setActiveTab] = useState<"accounts" | "movements">( const [activeTab, setActiveTab] = useState<'accounts' | 'movements'>('accounts')
"accounts" const [searchTerm, setSearchTerm] = useState('')
); const [selectedType, setSelectedType] = useState<AccountTypeEnum | 'all'>('all')
const [searchTerm, setSearchTerm] = useState(""); const [selectedRiskGroup, setSelectedRiskGroup] = useState<RiskGroupEnum | 'all'>('all')
const [selectedType, setSelectedType] = useState<AccountTypeEnum | "all">( const [sortBy, setSortBy] = useState<'title' | 'balance' | 'lastTransaction'>('title')
"all" const [selectedAccount, setSelectedAccount] = useState<FiCurrentAccount | null>(null)
); const [showForm, setShowForm] = useState(false)
const [selectedRiskGroup, setSelectedRiskGroup] = useState< const [showDetails, setShowDetails] = useState(false)
RiskGroupEnum | "all" const [editingAccount, setEditingAccount] = useState<FiCurrentAccount | null>(null)
>("all");
const [sortBy, setSortBy] = useState<"title" | "balance" | "lastTransaction">(
"title"
);
const [selectedAccount, setSelectedAccount] =
useState<FiCurrentAccount | null>(null);
const [showForm, setShowForm] = useState(false);
const [showDetails, setShowDetails] = useState(false);
const [editingAccount, setEditingAccount] = useState<FiCurrentAccount | null>(
null
);
// Movement form states // Movement form states
const [showMovementForm, setShowMovementForm] = useState(false); const [showMovementForm, setShowMovementForm] = useState(false)
const [editingMovement, setEditingMovement] = const [editingMovement, setEditingMovement] = useState<FiCurrentAccountMovement | null>(null)
useState<FiCurrentAccountMovement | null>(null);
// Movement filters // Movement filters
const [movementSearchTerm, setMovementSearchTerm] = useState(""); const [movementSearchTerm, setMovementSearchTerm] = useState('')
const [selectedDocumentType, setSelectedDocumentType] = useState< const [selectedDocumentType, setSelectedDocumentType] = useState<FiDocumentTypeEnum | 'all'>(
FiDocumentTypeEnum | "all" 'all',
>("all"); )
const [movementSortBy, setMovementSortBy] = useState<"date" | "amount">( const [movementSortBy, setMovementSortBy] = useState<'date' | 'amount'>('date')
"date"
);
// Handler functions // Handler functions
const handleAdd = () => { const handleAdd = () => {
setEditingAccount(null); setEditingAccount(null)
setShowForm(true); setShowForm(true)
}; }
const handleEdit = (account: FiCurrentAccount) => { const handleEdit = (account: FiCurrentAccount) => {
setEditingAccount(account); setEditingAccount(account)
setShowForm(true); setShowForm(true)
}; }
const handleViewDetails = (account: FiCurrentAccount) => { const handleViewDetails = (account: FiCurrentAccount) => {
setSelectedAccount(account); setSelectedAccount(account)
setShowDetails(true); setShowDetails(true)
}; }
const handleViewMovements = (account: FiCurrentAccount) => { const handleViewMovements = (account: FiCurrentAccount) => {
setSelectedAccount(account); setSelectedAccount(account)
setActiveTab("movements"); setActiveTab('movements')
}; }
const handleSaveAccount = (accountData: Partial<FiCurrentAccount>) => { const handleSaveAccount = (accountData: Partial<FiCurrentAccount>) => {
// This would normally call the parent's save function // This would normally call the parent's save function
console.log("Saving account:", accountData); console.log('Saving account:', accountData)
setShowForm(false); setShowForm(false)
setEditingAccount(null); setEditingAccount(null)
}; }
const handleCloseForm = () => { const handleCloseForm = () => {
setShowForm(false); setShowForm(false)
setEditingAccount(null); setEditingAccount(null)
}; }
const handleCloseDetails = () => { const handleCloseDetails = () => {
setShowDetails(false); setShowDetails(false)
setSelectedAccount(null); setSelectedAccount(null)
}; }
const handleEditFromDetails = () => { const handleEditFromDetails = () => {
if (selectedAccount) { if (selectedAccount) {
setShowDetails(false); setShowDetails(false)
setEditingAccount(selectedAccount); setEditingAccount(selectedAccount)
setShowForm(true); setShowForm(true)
}
} }
};
const handleEditMovement = (movement: FiCurrentAccountMovement) => { const handleEditMovement = (movement: FiCurrentAccountMovement) => {
setEditingMovement(movement); setEditingMovement(movement)
setShowMovementForm(true); setShowMovementForm(true)
}; }
const handleSaveMovement = ( const handleSaveMovement = (movementData: Partial<FiCurrentAccountMovement>) => {
movementData: Partial<FiCurrentAccountMovement>
) => {
// This would normally call the parent's save function // This would normally call the parent's save function
console.log("Saving movement:", movementData); console.log('Saving movement:', movementData)
setShowMovementForm(false); setShowMovementForm(false)
setEditingMovement(null); setEditingMovement(null)
}; }
const handleCloseMovementForm = () => { const handleCloseMovementForm = () => {
setShowMovementForm(false); setShowMovementForm(false)
setEditingMovement(null); setEditingMovement(null)
}; }
const handleAddMovement = () => { const handleAddMovement = () => {
setEditingMovement(null); setEditingMovement(null)
setShowMovementForm(true); setShowMovementForm(true)
}; }
// Filter movements // Filter movements
const filteredMovements = accountMovements const filteredMovements = accountMovements
.filter((movement) => { .filter((movement) => {
if (selectedAccount && movement.accountId !== selectedAccount.id) { if (selectedAccount && movement.accountId !== selectedAccount.id) {
return false; return false
} }
if ( if (
movementSearchTerm && movementSearchTerm &&
!movement.description !movement.description.toLowerCase().includes(movementSearchTerm.toLowerCase()) &&
.toLowerCase() !movement.referenceNumber?.toLowerCase().includes(movementSearchTerm.toLowerCase())
.includes(movementSearchTerm.toLowerCase()) &&
!movement.referenceNumber
?.toLowerCase()
.includes(movementSearchTerm.toLowerCase())
) { ) {
return false; return false
} }
if ( if (selectedDocumentType !== 'all' && movement.documentType !== selectedDocumentType) {
selectedDocumentType !== "all" && return false
movement.documentType !== selectedDocumentType
) {
return false;
} }
return true; return true
}) })
.sort((a, b) => { .sort((a, b) => {
switch (movementSortBy) { switch (movementSortBy) {
case "date": case 'date':
return new Date(b.transactionDate).getTime() - new Date(a.transactionDate).getTime()
case 'amount':
return ( return (
new Date(b.transactionDate).getTime() - Math.abs(b.debitAmount || b.creditAmount) - Math.abs(a.debitAmount || a.creditAmount)
new Date(a.transactionDate).getTime() )
);
case "amount":
return (
Math.abs(b.debitAmount || b.creditAmount) -
Math.abs(a.debitAmount || a.creditAmount)
);
default: default:
return 0; return 0
} }
}); })
// Movement columns // Movement columns
const movementColumns: Column<FiCurrentAccountMovement>[] = [ const movementColumns: Column<FiCurrentAccountMovement>[] = [
{ {
key: "transactionDate", key: 'transactionDate',
header: "Tarih", header: 'Tarih',
sortable: true, sortable: true,
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<span className="text-sm"> <span className="text-sm">{movement.transactionDate.toLocaleDateString('tr-TR')}</span>
{movement.transactionDate.toLocaleDateString("tr-TR")}
</span>
), ),
}, },
{ {
key: "documentType", key: 'documentType',
header: "Belge Türü", header: 'Belge Türü',
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<span <span
className={`px-2 py-1 text-xs font-medium rounded-full ${getFiDocumentTypeColor( className={`px-2 py-1 text-xs font-medium rounded-full ${getFiDocumentTypeColor(
movement.documentType movement.documentType,
)}`} )}`}
> >
{getFiDocumentTypeText(movement.documentType)} {getFiDocumentTypeText(movement.documentType)}
@ -210,34 +175,32 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "referenceNumber", key: 'referenceNumber',
header: "Belge No", header: 'Belge No',
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<span className="font-mono text-sm"> <span className="font-mono text-sm">
{movement.referenceNumber || movement.documentNumber || "-"} {movement.referenceNumber || movement.documentNumber || '-'}
</span> </span>
), ),
}, },
{ {
key: "description", key: 'description',
header: "Açıklama", header: 'Açıklama',
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<div className="max-w-xs"> <div className="max-w-xs">
<div className="font-medium text-gray-900 truncate"> <div className="font-medium text-gray-900 truncate">{movement.description}</div>
{movement.description}
</div>
</div> </div>
), ),
}, },
{ {
key: "debitAmount", key: 'debitAmount',
header: "Borç", header: 'Borç',
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<div className="text-right"> <div className="text-right">
{movement.debitAmount > 0 ? ( {movement.debitAmount > 0 ? (
<span className="text-red-600 font-medium"> <span className="text-red-600 font-medium">
{movement.debitAmount.toLocaleString("tr-TR", { {movement.debitAmount.toLocaleString('tr-TR', {
style: "currency", style: 'currency',
currency: movement.currency, currency: movement.currency,
minimumFractionDigits: 2, minimumFractionDigits: 2,
})} })}
@ -249,14 +212,14 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "creditAmount", key: 'creditAmount',
header: "Alacak", header: 'Alacak',
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<div className="text-right"> <div className="text-right">
{movement.creditAmount > 0 ? ( {movement.creditAmount > 0 ? (
<span className="text-green-600 font-medium"> <span className="text-green-600 font-medium">
{movement.creditAmount.toLocaleString("tr-TR", { {movement.creditAmount.toLocaleString('tr-TR', {
style: "currency", style: 'currency',
currency: movement.currency, currency: movement.currency,
minimumFractionDigits: 2, minimumFractionDigits: 2,
})} })}
@ -268,33 +231,27 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "balance", key: 'balance',
header: "Bakiye", header: 'Bakiye',
render: (movement: FiCurrentAccountMovement) => { render: (movement: FiCurrentAccountMovement) => {
const isDebit = movement.balance > 0; const isDebit = movement.balance > 0
return ( return (
<div className="text-right"> <div className="text-right">
<span <span className={`font-medium ${isDebit ? 'text-red-600' : 'text-green-600'}`}>
className={`font-medium ${ {Math.abs(movement.balance).toLocaleString('tr-TR', {
isDebit ? "text-red-600" : "text-green-600" style: 'currency',
}`}
>
{Math.abs(movement.balance).toLocaleString("tr-TR", {
style: "currency",
currency: movement.currency, currency: movement.currency,
minimumFractionDigits: 2, minimumFractionDigits: 2,
})} })}
</span> </span>
<div className="text-xs text-gray-500"> <div className="text-xs text-gray-500">{isDebit ? 'Borçlu' : 'Alacaklı'}</div>
{isDebit ? "Borçlu" : "Alacaklı"}
</div> </div>
</div> )
);
}, },
}, },
{ {
key: "actions", key: 'actions',
header: "İşlemler", header: 'İşlemler',
render: (movement: FiCurrentAccountMovement) => ( render: (movement: FiCurrentAccountMovement) => (
<div className="flex gap-1"> <div className="flex gap-1">
<button <button
@ -307,86 +264,72 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
</div> </div>
), ),
}, },
]; ]
const filteredAccounts = accounts const filteredAccounts = accounts
.filter((account) => { .filter((account) => {
if ( if (
searchTerm && searchTerm &&
!account.businessParty?.name !account.businessParty?.name.toLowerCase().includes(searchTerm.toLowerCase()) &&
.toLowerCase()
.includes(searchTerm.toLowerCase()) &&
!account.accountCode.toLowerCase().includes(searchTerm.toLowerCase()) && !account.accountCode.toLowerCase().includes(searchTerm.toLowerCase()) &&
!account.taxNumber?.toLowerCase().includes(searchTerm.toLowerCase()) !account.taxNumber?.toLowerCase().includes(searchTerm.toLowerCase())
) { ) {
return false; return false
} }
if (selectedType !== "all" && account.type !== selectedType) { if (selectedType !== 'all' && account.type !== selectedType) {
return false; return false
} }
if ( if (selectedRiskGroup !== 'all' && account.riskGroup !== selectedRiskGroup) {
selectedRiskGroup !== "all" && return false
account.riskGroup !== selectedRiskGroup
) {
return false;
} }
return true; return true
}) })
.sort((a, b) => { .sort((a, b) => {
switch (sortBy) { switch (sortBy) {
case "title": case 'title':
return ( return a.businessParty?.name?.localeCompare(b.businessParty?.name || '') || 0
a.businessParty?.name?.localeCompare(b.businessParty?.name || "") || case 'balance':
0 return Math.abs(b.balance) - Math.abs(a.balance)
); case 'lastTransaction': {
case "balance": const aDate = a.lastTransactionDate ? new Date(a.lastTransactionDate).getTime() : 0
return Math.abs(b.balance) - Math.abs(a.balance); const bDate = b.lastTransactionDate ? new Date(b.lastTransactionDate).getTime() : 0
case "lastTransaction": { return bDate - aDate
const aDate = a.lastTransactionDate
? new Date(a.lastTransactionDate).getTime()
: 0;
const bDate = b.lastTransactionDate
? new Date(b.lastTransactionDate).getTime()
: 0;
return bDate - aDate;
} }
default: default:
return 0; return 0
} }
}); })
const formatBalance = (balance: number) => { const formatBalance = (balance: number) => {
const isDebit = balance > 0; const isDebit = balance > 0
const absBalance = Math.abs(balance); const absBalance = Math.abs(balance)
return { return {
amount: absBalance.toLocaleString("tr-TR", { amount: absBalance.toLocaleString('tr-TR', {
style: "currency", style: 'currency',
currency: "TRY", currency: 'TRY',
minimumFractionDigits: 2, minimumFractionDigits: 2,
}), }),
type: isDebit ? "Borçlu" : "Alacaklı", type: isDebit ? 'Borçlu' : 'Alacaklı',
isDebit, isDebit,
}; }
}; }
const columns: Column<FiCurrentAccount>[] = [ const columns: Column<FiCurrentAccount>[] = [
{ {
key: "accountCode", key: 'accountCode',
header: "Hesap Kodu", header: 'Hesap Kodu',
sortable: true, sortable: true,
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<span className="font-mono text-sm">{account.accountCode}</span> <span className="font-mono text-sm">{account.accountCode}</span>
), ),
}, },
{ {
key: "title", key: 'title',
header: "Ünvan", header: 'Ünvan',
sortable: true, sortable: true,
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<div> <div>
<div className="font-medium text-gray-900"> <div className="font-medium text-gray-900">{account.businessParty?.name}</div>
{account.businessParty?.name}
</div>
{account.contactPerson && ( {account.contactPerson && (
<div className="text-sm text-gray-500">{account.contactPerson}</div> <div className="text-sm text-gray-500">{account.contactPerson}</div>
)} )}
@ -394,12 +337,12 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "type", key: 'type',
header: "Tür", header: 'Tür',
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<span <span
className={`px-2 py-1 text-xs font-medium rounded-full ${getAccountTypeColor( className={`px-2 py-1 text-xs font-medium rounded-full ${getAccountTypeColor(
account.type account.type,
)}`} )}`}
> >
{getAccountTypeText(account.type)} {getAccountTypeText(account.type)}
@ -407,34 +350,32 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "balance", key: 'balance',
header: "Bakiye", header: 'Bakiye',
sortable: true, sortable: true,
render: (account: FiCurrentAccount) => { render: (account: FiCurrentAccount) => {
const balanceInfo = formatBalance(account.balance); const balanceInfo = formatBalance(account.balance)
return ( return (
<div className="text-right"> <div className="text-right">
<div <div
className={`font-medium ${ className={`font-medium ${balanceInfo.isDebit ? 'text-red-600' : 'text-green-600'}`}
balanceInfo.isDebit ? "text-red-600" : "text-green-600"
}`}
> >
{balanceInfo.amount} {balanceInfo.amount}
</div> </div>
<div className="text-xs text-gray-500">{balanceInfo.type}</div> <div className="text-xs text-gray-500">{balanceInfo.type}</div>
</div> </div>
); )
}, },
}, },
{ {
key: "creditLimit", key: 'creditLimit',
header: "Kredi Limiti", header: 'Kredi Limiti',
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<div className="text-right"> <div className="text-right">
<span className="text-sm text-gray-900"> <span className="text-sm text-gray-900">
{account.creditLimit.toLocaleString("tr-TR", { {account.creditLimit.toLocaleString('tr-TR', {
style: "currency", style: 'currency',
currency: "TRY", currency: 'TRY',
minimumFractionDigits: 0, minimumFractionDigits: 0,
})} })}
</span> </span>
@ -442,12 +383,12 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "riskGroup", key: 'riskGroup',
header: "Risk Grubu", header: 'Risk Grubu',
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<span <span
className={`px-2 py-1 text-xs font-medium rounded-full ${getRiskGroupColor( className={`px-2 py-1 text-xs font-medium rounded-full ${getRiskGroupColor(
account.riskGroup account.riskGroup,
)}`} )}`}
> >
{getRiskGroupText(account.riskGroup)} {getRiskGroupText(account.riskGroup)}
@ -455,33 +396,29 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
), ),
}, },
{ {
key: "contact", key: 'contact',
header: "İletişim", header: 'İletişim',
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<div className="text-sm"> <div className="text-sm">
{account.phone && ( {account.phone && <div className="text-gray-900">{account.phone}</div>}
<div className="text-gray-900">{account.phone}</div> {account.email && <div className="text-gray-500">{account.email}</div>}
)}
{account.email && (
<div className="text-gray-500">{account.email}</div>
)}
</div> </div>
), ),
}, },
{ {
key: "lastTransaction", key: 'lastTransaction',
header: "Son Hareket", header: 'Son Hareket',
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
{account.lastTransactionDate {account.lastTransactionDate
? new Date(account.lastTransactionDate).toLocaleDateString("tr-TR") ? new Date(account.lastTransactionDate).toLocaleDateString('tr-TR')
: "Hareket yok"} : 'Hareket yok'}
</div> </div>
), ),
}, },
{ {
key: "actions", key: 'actions',
header: "İşlemler", header: 'İşlemler',
render: (account: FiCurrentAccount) => ( render: (account: FiCurrentAccount) => (
<div className="flex gap-1"> <div className="flex gap-1">
<button <button
@ -509,37 +446,34 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
</div> </div>
), ),
}, },
]; ]
// Calculate statistics // Calculate statistics
const totalAccounts = accounts.length; const totalAccounts = accounts.length
const activeAccounts = accounts.filter((a) => a.isActive).length; const activeAccounts = accounts.filter((a) => a.isActive).length
const totalDebitBalance = accounts const totalDebitBalance = accounts
.filter((a) => a.balance > 0) .filter((a) => a.balance > 0)
.reduce((sum, a) => sum + a.balance, 0); .reduce((sum, a) => sum + a.balance, 0)
const totalCreditBalance = accounts const totalCreditBalance = accounts
.filter((a) => a.balance < 0) .filter((a) => a.balance < 0)
.reduce((sum, a) => sum + Math.abs(a.balance), 0); .reduce((sum, a) => sum + Math.abs(a.balance), 0)
// High risk accounts // High risk accounts
const highRiskAccounts = accounts.filter( const highRiskAccounts = accounts.filter(
(a) => (a) =>
a.riskGroup === RiskGroupEnum.High || a.riskGroup === RiskGroupEnum.High ||
a.riskGroup === RiskGroupEnum.Blocked || a.riskGroup === RiskGroupEnum.Blocked ||
Math.abs(a.balance) > a.creditLimit Math.abs(a.balance) > a.creditLimit,
); )
return ( return (
<Container>
<div className="space-y-2"> <div className="space-y-2">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<h2 className="text-2xl font-bold text-gray-900"> <h2 className="text-2xl font-bold text-gray-900">Cari Hesap Yönetimi</h2>
Cari Hesap Yönetimi <p className="text-gray-600">Müşteri ve tedarikçi cari hesaplarının yönetimi</p>
</h2>
<p className="text-gray-600">
Müşteri ve tedarikçi cari hesaplarının yönetimi
</p>
</div> </div>
<button <button
onClick={handleAdd} onClick={handleAdd}
@ -561,9 +495,9 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
/> />
<Widget <Widget
title="Toplam Borç" title="Toplam Borç"
value={totalDebitBalance.toLocaleString("tr-TR", { value={totalDebitBalance.toLocaleString('tr-TR', {
style: "currency", style: 'currency',
currency: "TRY", currency: 'TRY',
minimumFractionDigits: 0, minimumFractionDigits: 0,
})} })}
color="red" color="red"
@ -571,9 +505,9 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
/> />
<Widget <Widget
title="Toplam Alacak" title="Toplam Alacak"
value={totalCreditBalance.toLocaleString("tr-TR", { value={totalCreditBalance.toLocaleString('tr-TR', {
style: "currency", style: 'currency',
currency: "TRY", currency: 'TRY',
minimumFractionDigits: 0, minimumFractionDigits: 0,
})} })}
color="green" color="green"
@ -592,11 +526,11 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<div className="border-b border-gray-200"> <div className="border-b border-gray-200">
<nav className="-mb-px flex space-x-6 px-4"> <nav className="-mb-px flex space-x-6 px-4">
<button <button
onClick={() => setActiveTab("accounts")} onClick={() => setActiveTab('accounts')}
className={`py-3 px-1 border-b-2 font-medium text-sm ${ className={`py-3 px-1 border-b-2 font-medium text-sm ${
activeTab === "accounts" activeTab === 'accounts'
? "border-blue-500 text-blue-600" ? 'border-blue-500 text-blue-600'
: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300" : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`} }`}
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -605,11 +539,11 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
</div> </div>
</button> </button>
<button <button
onClick={() => setActiveTab("movements")} onClick={() => setActiveTab('movements')}
className={`py-3 px-1 border-b-2 font-medium text-sm ${ className={`py-3 px-1 border-b-2 font-medium text-sm ${
activeTab === "movements" activeTab === 'movements'
? "border-blue-500 text-blue-600" ? 'border-blue-500 text-blue-600'
: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300" : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`} }`}
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -621,7 +555,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
</div> </div>
<div className="p-4"> <div className="p-4">
{activeTab === "accounts" && ( {activeTab === 'accounts' && (
<div className="space-y-4"> <div className="space-y-4">
{/* Filters */} {/* Filters */}
<div className="flex gap-3 items-center"> <div className="flex gap-3 items-center">
@ -638,9 +572,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<select <select
value={selectedType} value={selectedType}
onChange={(e) => onChange={(e) => setSelectedType(e.target.value as AccountTypeEnum | 'all')}
setSelectedType(e.target.value as AccountTypeEnum | "all")
}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
> >
<option value="all">Tüm Türler</option> <option value="all">Tüm Türler</option>
@ -653,11 +585,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<select <select
value={selectedRiskGroup} value={selectedRiskGroup}
onChange={(e) => onChange={(e) => setSelectedRiskGroup(e.target.value as RiskGroupEnum | 'all')}
setSelectedRiskGroup(
e.target.value as RiskGroupEnum | "all"
)
}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
> >
<option value="all">Tüm Risk Grupları</option> <option value="all">Tüm Risk Grupları</option>
@ -671,9 +599,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<select <select
value={sortBy} value={sortBy}
onChange={(e) => onChange={(e) =>
setSortBy( setSortBy(e.target.value as 'title' | 'balance' | 'lastTransaction')
e.target.value as "title" | "balance" | "lastTransaction"
)
} }
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
> >
@ -695,15 +621,14 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
Cari hesap bulunamadı Cari hesap bulunamadı
</h3> </h3>
<p className="text-sm text-gray-500"> <p className="text-sm text-gray-500">
Yeni bir cari hesap ekleyin veya arama kriterlerinizi Yeni bir cari hesap ekleyin veya arama kriterlerinizi değiştirin.
değiştirin.
</p> </p>
</div> </div>
)} )}
</div> </div>
)} )}
{activeTab === "movements" && ( {activeTab === 'movements' && (
<div className="space-y-4"> <div className="space-y-4">
{/* Movement Header */} {/* Movement Header */}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -714,7 +639,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<p className="text-gray-600 text-sm"> <p className="text-gray-600 text-sm">
{selectedAccount {selectedAccount
? `${selectedAccount.businessParty?.name} (${selectedAccount.accountCode}) hesabının hareketleri` ? `${selectedAccount.businessParty?.name} (${selectedAccount.accountCode}) hesabının hareketleri`
: "Tüm cari hesap hareketleri"} : 'Tüm cari hesap hareketleri'}
</p> </p>
</div> </div>
<button <button
@ -751,9 +676,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<select <select
value={selectedDocumentType} value={selectedDocumentType}
onChange={(e) => onChange={(e) =>
setSelectedDocumentType( setSelectedDocumentType(e.target.value as FiDocumentTypeEnum | 'all')
e.target.value as FiDocumentTypeEnum | "all"
)
} }
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
> >
@ -767,9 +690,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
<select <select
value={movementSortBy} value={movementSortBy}
onChange={(e) => onChange={(e) => setMovementSortBy(e.target.value as 'date' | 'amount')}
setMovementSortBy(e.target.value as "date" | "amount")
}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
> >
<option value="date">Tarihe Göre</option> <option value="date">Tarihe Göre</option>
@ -785,9 +706,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
{filteredMovements.length === 0 && ( {filteredMovements.length === 0 && (
<div className="text-center py-10"> <div className="text-center py-10">
<FaReceipt className="w-12 h-12 text-gray-400 mx-auto mb-4" /> <FaReceipt className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<h3 className="text-base font-medium text-gray-900 mb-2"> <h3 className="text-base font-medium text-gray-900 mb-2">Hareket bulunamadı</h3>
Hareket bulunamadı
</h3>
<p className="text-sm text-gray-500"> <p className="text-sm text-gray-500">
Seçili kriterlere uygun hareket bulunmamaktadır. Seçili kriterlere uygun hareket bulunmamaktadır.
</p> </p>
@ -797,6 +716,7 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
)} )}
</div> </div>
</div> </div>
</div>
{/* Forms and Modals */} {/* Forms and Modals */}
{showForm && ( {showForm && (
@ -826,8 +746,8 @@ const CurrentAccountManagement: React.FC<CurrentAccountManagementProps> = ({
onSave={handleSaveMovement} onSave={handleSaveMovement}
/> />
)} )}
</div> </Container>
); )
}; }
export default CurrentAccountManagement; export default CurrentAccountManagement

View file

@ -573,6 +573,7 @@ const ActivityRecords: React.FC = () => {
<p className="text-gray-500">Arama kriterlerinizi değiştirmeyi deneyin.</p> <p className="text-gray-500">Arama kriterlerinizi değiştirmeyi deneyin.</p>
</div> </div>
)} )}
</div>
{/* Modals */} {/* Modals */}
<ActivityForm <ActivityForm
@ -589,7 +590,6 @@ const ActivityRecords: React.FC = () => {
onEdit={handleEditFromDetails} onEdit={handleEditFromDetails}
activity={selectedActivity} activity={selectedActivity}
/> />
</div>
</Container> </Container>
) )
} }