Enum ve static veriler düzenlendi.

This commit is contained in:
Sedat ÖZTÜRK 2025-09-17 12:46:58 +03:00
parent a86d0f9fd1
commit ca28fe8b5c
116 changed files with 4170 additions and 4649 deletions

View file

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

View file

@ -368,7 +368,7 @@ const EntityManager: React.FC = () => {
</p>
{!searchTerm && filterActive === 'all' && (
<Link
to={ROUTES_ENUM.protected.saas.developerKitEntitiesNew}
to={ROUTES_ENUM.protected.saas.developerKit.entitiesNew}
className="inline-flex items-center gap-2 bg-emerald-600 text-white px-4 py-2 rounded-lg hover:bg-emerald-700 transition-colors shadow-sm hover:shadow-md"
>
<FaPlus className="w-4 h-4" />

View file

@ -1,54 +1,51 @@
import { BankAccountTypeEnum } from "../types/fi";
import { BusinessParty, BusinessPartyStatusEnum, PartyType, PaymentTerms } from "../types/common";
import {
CustomerSegmentEnum,
CustomerTypeEnum,
} from "../types/crm";
import { SupplierTypeEnum, SupplierCardTypeEnum } from "../types/mm";
import { BankAccountTypeEnum } from '../types/fi'
import { BusinessParty, BusinessPartyStatusEnum, PartyType, PaymentTerms } from '../types/common'
import { CustomerSegmentEnum, CustomerTypeEnum } from '../types/crm'
import { SupplierTypeEnum, SupplierCardTypeEnum } from '../types/mm'
export const mockBusinessParties: BusinessParty[] = [
{
id: "1",
code: "SUP001",
supplierType: SupplierTypeEnum.Material,
name: "ABC Malzeme Ltd.",
id: '1',
code: 'SUP001',
supplierType: SupplierTypeEnum.Manufacturer,
name: 'ABC Malzeme Ltd.',
primaryContact: {
id: "2",
firstName: "Fatma",
lastName: "Demir",
fullName: "Fatma Demir",
title: "Genel Müdür",
department: "Yönetim",
email: "fatma.demir@uretim.com",
phone: "+90 312 555 0202",
mobile: "+90 532 555 0202",
id: '2',
firstName: 'Fatma',
lastName: 'Demir',
fullName: 'Fatma Demir',
title: 'Genel Müdür',
department: 'Yönetim',
email: 'fatma.demir@uretim.com',
phone: '+90 312 555 0202',
mobile: '+90 532 555 0202',
isPrimary: true,
isActive: true,
creationTime: new Date(),
lastModificationTime: new Date(),
},
email: "aliveli@gmail.com",
phone: "+90 212 555 1234",
email: 'aliveli@gmail.com',
phone: '+90 212 555 1234',
address: {
street: "İstiklal Cad. No:10",
city: "İstanbul",
state: "İstanbul",
postalCode: "34430",
country: "Türkiye",
street: 'İstiklal Cad. No:10',
city: 'İstanbul',
state: 'İstanbul',
postalCode: '34430',
country: 'Türkiye',
},
taxNumber: "1234567890",
taxNumber: '1234567890',
paymentTerms: PaymentTerms.Net30,
currency: "TRY",
cardNumber: "SC-2024-001",
currency: 'TRY',
cardNumber: 'SC-2024-001',
cardType: SupplierCardTypeEnum.Standard,
validFrom: new Date("2024-01-01"),
validTo: new Date("2024-12-31"),
validFrom: new Date('2024-01-01'),
validTo: new Date('2024-12-31'),
creditLimit: 500000,
isActive: true,
currentBalance: 120000,
discountRate: 5,
specialConditions: ["Toplu sipariş indirimi", "Öncelikli teslimat"],
lastOrderDate: new Date("2024-08-15"),
specialConditions: ['Toplu sipariş indirimi', 'Öncelikli teslimat'],
lastOrderDate: new Date('2024-08-15'),
performanceMetrics: {
deliveryPerformance: 95,
qualityRating: 90,
@ -56,21 +53,21 @@ export const mockBusinessParties: BusinessParty[] = [
responsiveness: 67,
complianceRating: 88,
overallScore: 100,
lastEvaluationDate: new Date("2024-08-01"),
lastEvaluationDate: new Date('2024-08-01'),
},
certifications: ["ISO 9001", "ISO 14001"],
certifications: ['ISO 9001', 'ISO 14001'],
bankAccounts: [
{
id: "BA001",
bankName: "Garanti BBVA",
accountNumber: "1234567890",
iban: "TR330006100519786457841326",
swiftCode: "TGBATRIS",
id: 'BA001',
bankName: 'Garanti BBVA',
accountNumber: '1234567890',
iban: 'TR330006100519786457841326',
swiftCode: 'TGBATRIS',
isDefault: true,
accountCode: "",
branchName: "",
accountCode: '',
branchName: '',
accountType: BankAccountTypeEnum.Current,
currency: "",
currency: '',
balance: 0,
overdraftLimit: 0,
dailyTransferLimit: 0,
@ -81,14 +78,14 @@ export const mockBusinessParties: BusinessParty[] = [
],
contacts: [
{
id: "C001",
firstName: "Ali",
lastName: "Veli",
fullName: "Ali Veli",
title: "Satınalma Müdürü",
email: "aliveli@gmail.com",
phone: "+90 212 555 1234",
department: "Satınalma",
id: 'C001',
firstName: 'Ali',
lastName: 'Veli',
fullName: 'Ali Veli',
title: 'Satınalma Müdürü',
email: 'aliveli@gmail.com',
phone: '+90 212 555 1234',
department: 'Satınalma',
isPrimary: true,
isActive: false,
creationTime: new Date(),
@ -100,47 +97,47 @@ export const mockBusinessParties: BusinessParty[] = [
partyType: PartyType.Supplier,
},
{
id: "2",
code: "SUP002",
supplierType: SupplierTypeEnum.Service,
name: "XYZ Teknoloji A.Ş.",
id: '2',
code: 'SUP002',
supplierType: SupplierTypeEnum.ServiceProvider,
name: 'XYZ Teknoloji A.Ş.',
primaryContact: {
id: "2",
firstName: "Fatma",
lastName: "Demir",
fullName: "Fatma Demir",
title: "Genel Müdür",
department: "Yönetim",
email: "fatma.demir@uretim.com",
phone: "+90 312 555 0202",
mobile: "+90 532 555 0202",
id: '2',
firstName: 'Fatma',
lastName: 'Demir',
fullName: 'Fatma Demir',
title: 'Genel Müdür',
department: 'Yönetim',
email: 'fatma.demir@uretim.com',
phone: '+90 312 555 0202',
mobile: '+90 532 555 0202',
isPrimary: true,
isActive: true,
creationTime: new Date(),
lastModificationTime: new Date(),
},
email: "aysedemir@gmail.com",
phone: "+90 216 555 5678",
email: 'aysedemir@gmail.com',
phone: '+90 216 555 5678',
address: {
street: "Barbaros Bulv. No:20",
city: "İstanbul",
state: "İstanbul",
postalCode: "34746",
country: "Türkiye",
street: 'Barbaros Bulv. No:20',
city: 'İstanbul',
state: 'İstanbul',
postalCode: '34746',
country: 'Türkiye',
},
taxNumber: "0987654321",
taxNumber: '0987654321',
paymentTerms: PaymentTerms.Net15,
currency: "TRY",
cardNumber: "SC-2024-002",
currency: 'TRY',
cardNumber: 'SC-2024-002',
cardType: SupplierCardTypeEnum.Premium,
validFrom: new Date("2024-02-01"),
validTo: new Date("2024-12-31"),
validFrom: new Date('2024-02-01'),
validTo: new Date('2024-12-31'),
creditLimit: 250000,
isActive: true,
currentBalance: 75000,
discountRate: 3,
specialConditions: ["Hızlı teslimat", "Kalite garantisi"],
lastOrderDate: new Date("2024-08-20"),
specialConditions: ['Hızlı teslimat', 'Kalite garantisi'],
lastOrderDate: new Date('2024-08-20'),
performanceMetrics: {
deliveryPerformance: 88,
qualityRating: 90,
@ -148,21 +145,21 @@ export const mockBusinessParties: BusinessParty[] = [
responsiveness: 87,
complianceRating: 91,
overallScore: 88,
lastEvaluationDate: new Date("2024-08-01"),
lastEvaluationDate: new Date('2024-08-01'),
},
certifications: ["ISO 9001"],
certifications: ['ISO 9001'],
bankAccounts: [
{
id: "BA002",
bankName: "İş Bankası",
accountNumber: "0987654321",
iban: "TR440006200519786457841327",
swiftCode: "ISBKTRIS",
id: 'BA002',
bankName: 'İş Bankası',
accountNumber: '0987654321',
iban: 'TR440006200519786457841327',
swiftCode: 'ISBKTRIS',
isDefault: true,
accountCode: "",
branchName: "",
accountCode: '',
branchName: '',
accountType: BankAccountTypeEnum.Current,
currency: "",
currency: '',
balance: 0,
overdraftLimit: 0,
dailyTransferLimit: 0,
@ -173,14 +170,14 @@ export const mockBusinessParties: BusinessParty[] = [
],
contacts: [
{
id: "C002",
firstName: "Ayşe",
lastName: "Demir",
fullName: "Ayşe Demir",
title: "Satış Müdürü",
email: "aysedemir@gmail.com",
phone: "+90 216 555 5678",
department: "Satış",
id: 'C002',
firstName: 'Ayşe',
lastName: 'Demir',
fullName: 'Ayşe Demir',
title: 'Satış Müdürü',
email: 'aysedemir@gmail.com',
phone: '+90 216 555 5678',
department: 'Satış',
isPrimary: true,
isActive: false,
creationTime: new Date(),
@ -192,47 +189,47 @@ export const mockBusinessParties: BusinessParty[] = [
partyType: PartyType.Supplier,
},
{
id: "3",
code: "SUP003",
supplierType: SupplierTypeEnum.Both,
name: "LMN Endüstri A.Ş.",
id: '3',
code: 'SUP003',
supplierType: SupplierTypeEnum.Manufacturer,
name: 'LMN Endüstri A.Ş.',
primaryContact: {
id: "2",
firstName: "Fatma",
lastName: "Demir",
fullName: "Fatma Demir",
title: "Genel Müdür",
department: "Yönetim",
email: "fatma.demir@uretim.com",
phone: "+90 312 555 0202",
mobile: "+90 532 555 0202",
id: '2',
firstName: 'Fatma',
lastName: 'Demir',
fullName: 'Fatma Demir',
title: 'Genel Müdür',
department: 'Yönetim',
email: 'fatma.demir@uretim.com',
phone: '+90 312 555 0202',
mobile: '+90 532 555 0202',
isPrimary: true,
isActive: true,
creationTime: new Date(),
lastModificationTime: new Date(),
},
email: "mehmetyilmaz@gmail.com",
phone: "+90 232 555 7890",
email: 'mehmetyilmaz@gmail.com',
phone: '+90 232 555 7890',
address: {
street: "Atatürk Cad. No:5",
city: "İzmir",
state: "İzmir",
postalCode: "35210",
country: "Türkiye",
street: 'Atatürk Cad. No:5',
city: 'İzmir',
state: 'İzmir',
postalCode: '35210',
country: 'Türkiye',
},
taxNumber: "1122334455",
taxNumber: '1122334455',
paymentTerms: PaymentTerms.Net45,
currency: "TRY",
cardNumber: "SC-2024-003",
currency: 'TRY',
cardNumber: 'SC-2024-003',
cardType: SupplierCardTypeEnum.Preferred,
validFrom: new Date("2024-03-01"),
validTo: new Date("2024-12-31"),
validFrom: new Date('2024-03-01'),
validTo: new Date('2024-12-31'),
creditLimit: 150000,
isActive: true,
currentBalance: 45000,
discountRate: 2,
specialConditions: ["Toplu sipariş indirimi"],
lastOrderDate: new Date("2024-08-18"),
specialConditions: ['Toplu sipariş indirimi'],
lastOrderDate: new Date('2024-08-18'),
performanceMetrics: {
deliveryPerformance: 82,
qualityRating: 85,
@ -240,21 +237,21 @@ export const mockBusinessParties: BusinessParty[] = [
responsiveness: 80,
complianceRating: 88,
overallScore: 85,
lastEvaluationDate: new Date("2024-07-15"),
lastEvaluationDate: new Date('2024-07-15'),
},
certifications: ["ISO 9001", "OHSAS 18001"],
certifications: ['ISO 9001', 'OHSAS 18001'],
bankAccounts: [
{
id: "BA003",
bankName: "Yapı Kredi",
accountNumber: "1122334455",
iban: "TR550006300519786457841328",
swiftCode: "YAPITRIS",
id: 'BA003',
bankName: 'Yapı Kredi',
accountNumber: '1122334455',
iban: 'TR550006300519786457841328',
swiftCode: 'YAPITRIS',
isDefault: true,
accountCode: "",
branchName: "",
accountCode: '',
branchName: '',
accountType: BankAccountTypeEnum.Current,
currency: "",
currency: '',
balance: 0,
overdraftLimit: 0,
dailyTransferLimit: 0,
@ -265,14 +262,14 @@ export const mockBusinessParties: BusinessParty[] = [
],
contacts: [
{
id: "C003",
firstName: "Mehmet",
lastName: "Yılmaz",
fullName: "Mehmet Yılmaz",
title: "Genel Müdür",
email: "mehmetyilmaz@gmail.com",
phone: "+90 232 555 7890",
department: "Yönetim",
id: 'C003',
firstName: 'Mehmet',
lastName: 'Yılmaz',
fullName: 'Mehmet Yılmaz',
title: 'Genel Müdür',
email: 'mehmetyilmaz@gmail.com',
phone: '+90 232 555 7890',
department: 'Yönetim',
isPrimary: true,
isActive: false,
creationTime: new Date(),
@ -284,47 +281,47 @@ export const mockBusinessParties: BusinessParty[] = [
partyType: PartyType.Supplier,
},
{
id: "4",
code: "SUP004",
supplierType: SupplierTypeEnum.Material,
name: "OPQ Ticaret Ltd.",
id: '4',
code: 'SUP004',
supplierType: SupplierTypeEnum.Distributor,
name: 'OPQ Ticaret Ltd.',
primaryContact: {
id: "2",
firstName: "Fatma",
lastName: "Demir",
fullName: "Fatma Demir",
title: "Genel Müdür",
department: "Yönetim",
email: "fatma.demir@uretim.com",
phone: "+90 312 555 0202",
mobile: "+90 532 555 0202",
id: '2',
firstName: 'Fatma',
lastName: 'Demir',
fullName: 'Fatma Demir',
title: 'Genel Müdür',
department: 'Yönetim',
email: 'fatma.demir@uretim.com',
phone: '+90 312 555 0202',
mobile: '+90 532 555 0202',
isPrimary: true,
isActive: true,
creationTime: new Date(),
lastModificationTime: new Date(),
},
email: "fatmacelik@gmail.com",
phone: "+90 312 555 3456",
email: 'fatmacelik@gmail.com',
phone: '+90 312 555 3456',
address: {
street: "Kızılay Meydanı No:15",
city: "Ankara",
state: "Ankara",
postalCode: "06690",
country: "Türkiye",
street: 'Kızılay Meydanı No:15',
city: 'Ankara',
state: 'Ankara',
postalCode: '06690',
country: 'Türkiye',
},
taxNumber: "6677889900",
taxNumber: '6677889900',
paymentTerms: PaymentTerms.Net30,
currency: "TRY",
cardNumber: "SC-2024-004",
currency: 'TRY',
cardNumber: 'SC-2024-004',
cardType: SupplierCardTypeEnum.Standard,
validFrom: new Date("2024-04-01"),
validTo: new Date("2024-12-31"),
validFrom: new Date('2024-04-01'),
validTo: new Date('2024-12-31'),
creditLimit: 100000,
isActive: false,
currentBalance: 30000,
discountRate: 4,
specialConditions: ["Öncelikli sipariş", "Hızlı teslimat"],
lastOrderDate: new Date("2024-06-30"),
specialConditions: ['Öncelikli sipariş', 'Hızlı teslimat'],
lastOrderDate: new Date('2024-06-30'),
performanceMetrics: {
deliveryPerformance: 75,
qualityRating: 78,
@ -332,21 +329,21 @@ export const mockBusinessParties: BusinessParty[] = [
responsiveness: 76,
complianceRating: 80,
overallScore: 78,
lastEvaluationDate: new Date("2024-07-01"),
lastEvaluationDate: new Date('2024-07-01'),
},
certifications: ["ISO 9001"],
certifications: ['ISO 9001'],
bankAccounts: [
{
id: "BA004",
bankName: "Halkbank",
accountNumber: "6677889900",
iban: "TR660006400519786457841329",
swiftCode: "HALKTRIS",
id: 'BA004',
bankName: 'Halkbank',
accountNumber: '6677889900',
iban: 'TR660006400519786457841329',
swiftCode: 'HALKTRIS',
isDefault: true,
accountCode: "",
branchName: "",
accountCode: '',
branchName: '',
accountType: BankAccountTypeEnum.Current,
currency: "",
currency: '',
balance: 0,
overdraftLimit: 0,
dailyTransferLimit: 0,
@ -357,14 +354,14 @@ export const mockBusinessParties: BusinessParty[] = [
],
contacts: [
{
id: "C004",
firstName: "Fatma",
lastName: "Çelik",
fullName: "Fatma Çelik",
title: "Finans Müdürü",
email: "fatmacelik@gmail.com",
phone: "+90 312 555 3456",
department: "Finans",
id: 'C004',
firstName: 'Fatma',
lastName: 'Çelik',
fullName: 'Fatma Çelik',
title: 'Finans Müdürü',
email: 'fatmacelik@gmail.com',
phone: '+90 312 555 3456',
department: 'Finans',
isPrimary: true,
isActive: false,
creationTime: new Date(),
@ -376,22 +373,22 @@ export const mockBusinessParties: BusinessParty[] = [
partyType: PartyType.Supplier,
},
{
id: "5",
code: "CUST-002",
name: "Üretim Ltd.",
id: '5',
code: 'CUST-002',
name: 'Üretim Ltd.',
customerType: CustomerTypeEnum.Company,
industry: "İmalat",
website: "www.uretim.com",
industry: 'İmalat',
website: 'www.uretim.com',
primaryContact: {
id: "2",
firstName: "Fatma",
lastName: "Demir",
fullName: "Fatma Demir",
title: "Genel Müdür",
department: "Yönetim",
email: "fatma.demir@uretim.com",
phone: "+90 312 555 0202",
mobile: "+90 532 555 0202",
id: '2',
firstName: 'Fatma',
lastName: 'Demir',
fullName: 'Fatma Demir',
title: 'Genel Müdür',
department: 'Yönetim',
email: 'fatma.demir@uretim.com',
phone: '+90 312 555 0202',
mobile: '+90 532 555 0202',
isPrimary: true,
isActive: true,
creationTime: new Date(),
@ -399,50 +396,50 @@ export const mockBusinessParties: BusinessParty[] = [
},
contacts: [],
address: {
street: "Sanayi Sitesi 5. Cadde No:25",
city: "Ankara",
state: "Ankara",
postalCode: "06000",
country: "Türkiye",
street: 'Sanayi Sitesi 5. Cadde No:25',
city: 'Ankara',
state: 'Ankara',
postalCode: '06000',
country: 'Türkiye',
},
taxNumber: "0987654321",
registrationNumber: "REG-002",
taxNumber: '0987654321',
registrationNumber: 'REG-002',
creditLimit: 500000,
paymentTerms: PaymentTerms.Net60,
currency: "TRY",
currency: 'TRY',
status: BusinessPartyStatusEnum.Active,
customerSegment: CustomerSegmentEnum.SMB,
assignedSalesRep: "REP-002",
teamId: "TEAM-001",
assignedSalesRep: 'REP-002',
teamId: 'TEAM-001',
totalRevenue: 850000,
lastOrderDate: new Date("2024-01-10"),
lastOrderDate: new Date('2024-01-10'),
averageOrderValue: 42500,
lifetimeValue: 1700000,
opportunities: [],
orders: [],
activities: [],
isActive: true,
creationTime: new Date("2023-09-20"),
lastModificationTime: new Date("2024-01-18"),
creationTime: new Date('2023-09-20'),
lastModificationTime: new Date('2024-01-18'),
partyType: PartyType.Customer,
},
{
id: "6",
code: "CUST-001",
name: "Teknoloji A.Ş.",
id: '6',
code: 'CUST-001',
name: 'Teknoloji A.Ş.',
customerType: CustomerTypeEnum.Company,
industry: "Teknoloji",
website: "www.teknoloji.com",
industry: 'Teknoloji',
website: 'www.teknoloji.com',
primaryContact: {
id: "1",
firstName: "Ali",
lastName: "Yılmaz",
fullName: "Ali Yılmaz",
title: "Satınalma Müdürü",
department: "Satınalma",
email: "ali.yilmaz@teknoloji.com",
phone: "+90 212 555 0201",
mobile: "+90 532 555 0201",
id: '1',
firstName: 'Ali',
lastName: 'Yılmaz',
fullName: 'Ali Yılmaz',
title: 'Satınalma Müdürü',
department: 'Satınalma',
email: 'ali.yilmaz@teknoloji.com',
phone: '+90 212 555 0201',
mobile: '+90 532 555 0201',
isPrimary: true,
isActive: true,
creationTime: new Date(),
@ -450,53 +447,53 @@ export const mockBusinessParties: BusinessParty[] = [
},
contacts: [],
address: {
street: "Teknoloji Caddesi No:100",
city: "İstanbul",
state: "İstanbul",
postalCode: "34000",
country: "Türkiye",
street: 'Teknoloji Caddesi No:100',
city: 'İstanbul',
state: 'İstanbul',
postalCode: '34000',
country: 'Türkiye',
},
taxNumber: "1234567890",
registrationNumber: "REG-001",
taxNumber: '1234567890',
registrationNumber: 'REG-001',
creditLimit: 1000000,
paymentTerms: PaymentTerms.Net30,
currency: "TRY",
currency: 'TRY',
status: BusinessPartyStatusEnum.Active,
customerSegment: CustomerSegmentEnum.Enterprise,
assignedSalesRep: "REP-001",
teamId: "TEAM-001",
assignedSalesRep: 'REP-001',
teamId: 'TEAM-001',
totalRevenue: 2500000,
lastOrderDate: new Date("2024-01-15"),
lastOrderDate: new Date('2024-01-15'),
averageOrderValue: 125000,
lifetimeValue: 5000000,
opportunities: [],
orders: [],
activities: [],
isActive: true,
creationTime: new Date("2023-06-15"),
lastModificationTime: new Date("2024-01-20"),
creationTime: new Date('2023-06-15'),
lastModificationTime: new Date('2024-01-20'),
partyType: PartyType.Customer,
},
];
]
export const mockBusinessPartyNew: BusinessParty = {
id: "",
code: "",
supplierType: SupplierTypeEnum.Both,
name: "",
email: "",
phone: "",
id: '',
code: '',
supplierType: SupplierTypeEnum.ServiceProvider,
name: '',
email: '',
phone: '',
address: {
street: "",
city: "",
state: "",
postalCode: "",
country: "",
street: '',
city: '',
state: '',
postalCode: '',
country: '',
},
taxNumber: "",
taxNumber: '',
paymentTerms: PaymentTerms.Cash,
currency: "TRY",
cardNumber: "",
currency: 'TRY',
cardNumber: '',
cardType: SupplierCardTypeEnum.Standard,
validTo: new Date(),
validFrom: new Date(),
@ -521,4 +518,4 @@ export const mockBusinessPartyNew: BusinessParty = {
creationTime: new Date(),
lastModificationTime: new Date(),
partyType: PartyType.Supplier,
};
}

View file

@ -1,44 +1,44 @@
import { FiCheck, CheckStatusEnum, CheckTypeEnum } from "../types/fi";
import { mockCurrentAccounts } from "./mockCurrentAccounts";
import { FiCheck, CheckStatusEnum, TypeEnum } from '../types/fi'
import { mockCurrentAccounts } from './mockCurrentAccounts'
export const mockChecks: FiCheck[] = [
{
id: "1",
checkNumber: "CHK-001",
bankName: "İş Bankası",
branchName: "Levent Şubesi",
accountNumber: "1234567890",
type: CheckTypeEnum.Received,
drawerName: "XYZ Müşteri A.Ş.",
payeeName: "ABC Şirket",
issueDate: new Date("2024-01-15"),
dueDate: new Date("2024-02-15"),
id: '1',
checkNumber: 'CHK-001',
bankName: 'İş Bankası',
branchName: 'Levent Şubesi',
accountNumber: '1234567890',
type: TypeEnum.Received,
drawerName: 'XYZ Müşteri A.Ş.',
payeeName: 'ABC Şirket',
issueDate: new Date('2024-01-15'),
dueDate: new Date('2024-02-15'),
amount: 25000,
currency: "TRY",
currency: 'TRY',
status: CheckStatusEnum.InHand,
currentAccountId: "1",
currentAccount: mockCurrentAccounts.find((ca) => ca.id === "1"),
creationTime: new Date("2024-01-15"),
lastModificationTime: new Date("2024-01-15"),
currentAccountId: '1',
currentAccount: mockCurrentAccounts.find((ca) => ca.id === '1'),
creationTime: new Date('2024-01-15'),
lastModificationTime: new Date('2024-01-15'),
},
{
id: "2",
checkNumber: "CHK-002",
bankName: "Garanti BBVA",
branchName: "Şişli Şubesi",
accountNumber: "9876543210",
type: CheckTypeEnum.Issued,
drawerName: "ABC Şirket",
payeeName: "Tedarikçi Ltd.",
issueDate: new Date("2024-01-10"),
dueDate: new Date("2024-02-10"),
id: '2',
checkNumber: 'CHK-002',
bankName: 'Garanti BBVA',
branchName: 'Şişli Şubesi',
accountNumber: '9876543210',
type: TypeEnum.Issued,
drawerName: 'ABC Şirket',
payeeName: 'Tedarikçi Ltd.',
issueDate: new Date('2024-01-10'),
dueDate: new Date('2024-02-10'),
amount: 15000,
currency: "TRY",
currency: 'TRY',
status: CheckStatusEnum.Deposited,
bankingDate: new Date("2024-01-20"),
currentAccountId: "2",
currentAccount: mockCurrentAccounts.find((ca) => ca.id === "2"),
creationTime: new Date("2024-01-10"),
lastModificationTime: new Date("2024-01-20"),
bankingDate: new Date('2024-01-20'),
currentAccountId: '2',
currentAccount: mockCurrentAccounts.find((ca) => ca.id === '2'),
creationTime: new Date('2024-01-10'),
lastModificationTime: new Date('2024-01-20'),
},
];
]

View file

@ -1,80 +1,80 @@
import { PsProjectCostTracking } from "../types/ps";
import { ProjectCostTrackingStatus, PsProjectCostTracking } from '../types/ps'
export const mockProjectCostTracking: PsProjectCostTracking[] = [
{
id: "1",
projectId: "1",
projectName: "ERP Sistemi Geliştirme",
projectCode: "PRJ-2024-001",
plannedBudget: 500000,
actualCost: 325000,
remainingBudget: 175000,
plannedStartDate: new Date("2024-01-15"),
plannedEndDate: new Date("2024-12-31"),
actualStartDate: new Date("2024-01-20"),
actualEndDate: undefined,
plannedDuration: 351,
actualDuration: 300,
progress: 65,
status: "ON_TRACK",
currency: "TRY",
lastUpdated: new Date("2024-11-25"),
},
{
id: "2",
projectId: "2",
projectName: "Mobil Uygulama Geliştirme",
projectCode: "PRJ-2024-002",
plannedBudget: 250000,
actualCost: 200000,
remainingBudget: 50000,
plannedStartDate: new Date("2024-03-01"),
plannedEndDate: new Date("2024-08-31"),
actualStartDate: new Date("2024-03-15"),
actualEndDate: undefined,
plannedDuration: 184,
actualDuration: 200,
progress: 80,
status: "AT_RISK",
currency: "TRY",
lastUpdated: new Date("2024-11-20"),
},
{
id: "3",
projectId: "3",
projectName: "Web Sitesi Yenileme",
projectCode: "PRJ-2024-003",
plannedBudget: 150000,
actualCost: 180000,
remainingBudget: -30000,
plannedStartDate: new Date("2024-02-01"),
plannedEndDate: new Date("2024-06-30"),
actualStartDate: new Date("2024-02-10"),
actualEndDate: new Date("2024-07-15"),
plannedDuration: 150,
actualDuration: 156,
progress: 100,
status: "COMPLETED",
currency: "TRY",
lastUpdated: new Date("2024-07-15"),
},
{
id: "4",
projectId: "4",
projectName: "Veri Analizi Platformu",
projectCode: "PRJ-2024-004",
plannedBudget: 400000,
actualCost: 120000,
remainingBudget: 280000,
plannedStartDate: new Date("2024-06-01"),
plannedEndDate: new Date("2024-12-31"),
actualStartDate: new Date("2024-06-15"),
actualEndDate: undefined,
plannedDuration: 214,
actualDuration: 163,
progress: 30,
status: "DELAYED",
currency: "TRY",
lastUpdated: new Date("2024-11-22"),
},
];
{
id: '1',
projectId: '1',
projectName: 'ERP Sistemi Geliştirme',
projectCode: 'PRJ-2024-001',
plannedBudget: 500000,
actualCost: 325000,
remainingBudget: 175000,
plannedStartDate: new Date('2024-01-15'),
plannedEndDate: new Date('2024-12-31'),
actualStartDate: new Date('2024-01-20'),
actualEndDate: undefined,
plannedDuration: 351,
actualDuration: 300,
progress: 65,
status: ProjectCostTrackingStatus.OnTrack,
currency: 'TRY',
lastUpdated: new Date('2024-11-25'),
},
{
id: '2',
projectId: '2',
projectName: 'Mobil Uygulama Geliştirme',
projectCode: 'PRJ-2024-002',
plannedBudget: 250000,
actualCost: 200000,
remainingBudget: 50000,
plannedStartDate: new Date('2024-03-01'),
plannedEndDate: new Date('2024-08-31'),
actualStartDate: new Date('2024-03-15'),
actualEndDate: undefined,
plannedDuration: 184,
actualDuration: 200,
progress: 80,
status: ProjectCostTrackingStatus.AtRisk,
currency: 'TRY',
lastUpdated: new Date('2024-11-20'),
},
{
id: '3',
projectId: '3',
projectName: 'Web Sitesi Yenileme',
projectCode: 'PRJ-2024-003',
plannedBudget: 150000,
actualCost: 180000,
remainingBudget: -30000,
plannedStartDate: new Date('2024-02-01'),
plannedEndDate: new Date('2024-06-30'),
actualStartDate: new Date('2024-02-10'),
actualEndDate: new Date('2024-07-15'),
plannedDuration: 150,
actualDuration: 156,
progress: 100,
status: ProjectCostTrackingStatus.Completed,
currency: 'TRY',
lastUpdated: new Date('2024-07-15'),
},
{
id: '4',
projectId: '4',
projectName: 'Veri Analizi Platformu',
projectCode: 'PRJ-2024-004',
plannedBudget: 400000,
actualCost: 120000,
remainingBudget: 280000,
plannedStartDate: new Date('2024-06-01'),
plannedEndDate: new Date('2024-12-31'),
actualStartDate: new Date('2024-06-15'),
actualEndDate: undefined,
plannedDuration: 214,
actualDuration: 163,
progress: 30,
status: ProjectCostTrackingStatus.Delayed,
currency: 'TRY',
lastUpdated: new Date('2024-11-22'),
},
]

View file

@ -1,180 +1,164 @@
import { PhaseStatusEnum, PsProjectPhase } from "../types/ps";
import { mockMaintenanceTeams } from "./mockMaintenanceTeams";
import { mockProjects } from "./mockProjects";
import { PhaseCategoryEnum, PhaseStatusEnum, PsProjectPhase } from '../types/ps'
import { mockMaintenanceTeams } from './mockMaintenanceTeams'
import { mockProjects } from './mockProjects'
export const mockProjectPhases: PsProjectPhase[] = [
{
id: "1",
code: "PH-001",
name: "Analiz ve Tasarım",
description: "Sistem analizi ve tasarım dokümantasyonu hazırlanması",
projectId: "1",
project: mockProjects.find((p) => p.id === "1")!,
id: '1',
code: 'PH-001',
name: 'Analiz ve Tasarım',
description: 'Sistem analizi ve tasarım dokümantasyonu hazırlanması',
projectId: '1',
project: mockProjects.find((p) => p.id === '1')!,
status: PhaseStatusEnum.Completed,
startDate: new Date("2024-01-15"),
endDate: new Date("2024-02-28"),
actualStartDate: new Date("2024-01-15"),
actualEndDate: new Date("2024-02-25"),
startDate: new Date('2024-01-15'),
endDate: new Date('2024-02-28'),
actualStartDate: new Date('2024-01-15'),
actualEndDate: new Date('2024-02-25'),
budget: 150000,
actualCost: 145000,
progress: 100,
milestones: 4,
completedMilestones: 4,
assignedTeams: [
mockMaintenanceTeams.find((t) => t.id === "1")!.name,
mockMaintenanceTeams.find((t) => t.id === "2")!.name,
mockMaintenanceTeams.find((t) => t.id === '1')!.name,
mockMaintenanceTeams.find((t) => t.id === '2')!.name,
],
deliverables: [
"Sistem Analiz Raporu",
"Teknik Tasarım Dokümanı",
"UI/UX Tasarımları",
],
risks: ["Gereksinim değişiklikleri"],
category: "Planning",
deliverables: ['Sistem Analiz Raporu', 'Teknik Tasarım Dokümanı', 'UI/UX Tasarımları'],
risks: ['Gereksinim değişiklikleri'],
category: PhaseCategoryEnum.Planning,
sequence: 0,
tasks: [],
isActive: false,
},
{
id: "2",
code: "PH-002",
name: "Geliştirme - Faz 1",
description: "Backend altyapısı ve temel modüllerin geliştirilmesi",
projectId: "1",
project: mockProjects.find((p) => p.id === "1")!,
id: '2',
code: 'PH-002',
name: 'Geliştirme - Faz 1',
description: 'Backend altyapısı ve temel modüllerin geliştirilmesi',
projectId: '1',
project: mockProjects.find((p) => p.id === '1')!,
status: PhaseStatusEnum.Cancelled,
startDate: new Date("2024-03-01"),
endDate: new Date("2024-05-15"),
actualStartDate: new Date("2024-03-01"),
actualEndDate: new Date("2024-05-10"),
startDate: new Date('2024-03-01'),
endDate: new Date('2024-05-15'),
actualStartDate: new Date('2024-03-01'),
actualEndDate: new Date('2024-05-10'),
budget: 400000,
actualCost: 280000,
progress: 70,
milestones: 6,
completedMilestones: 4,
assignedTeams: [
mockMaintenanceTeams.find((t) => t.id === "1")!.name,
mockMaintenanceTeams.find((t) => t.id === "2")!.name,
mockMaintenanceTeams.find((t) => t.id === '1')!.name,
mockMaintenanceTeams.find((t) => t.id === '2')!.name,
],
deliverables: ["API Framework", "Veritabanı Şeması", "Güvenlik Modülü"],
risks: ["Performans sorunları", "Üçüncü parti entegrasyon gecikmeleri"],
category: "Development",
deliverables: ['API Framework', 'Veritabanı Şeması', 'Güvenlik Modülü'],
risks: ['Performans sorunları', 'Üçüncü parti entegrasyon gecikmeleri'],
category: PhaseCategoryEnum.Development,
sequence: 0,
tasks: [],
isActive: false,
},
{
id: "3",
code: "PH-003",
name: "Geliştirme - Faz 2",
description: "Frontend geliştirme ve kullanıcı arayüzleri",
projectId: "1",
project: mockProjects.find((p) => p.id === "1")!,
id: '3',
code: 'PH-003',
name: 'Geliştirme - Faz 2',
description: 'Frontend geliştirme ve kullanıcı arayüzleri',
projectId: '1',
project: mockProjects.find((p) => p.id === '1')!,
status: PhaseStatusEnum.NotStarted,
startDate: new Date("2024-04-15"),
endDate: new Date("2024-07-30"),
startDate: new Date('2024-04-15'),
endDate: new Date('2024-07-30'),
budget: 350000,
actualCost: 0,
progress: 0,
milestones: 5,
completedMilestones: 0,
assignedTeams: [
mockMaintenanceTeams.find((t) => t.id === "1")!.name,
mockMaintenanceTeams.find((t) => t.id === "2")!.name,
mockMaintenanceTeams.find((t) => t.id === '1')!.name,
mockMaintenanceTeams.find((t) => t.id === '2')!.name,
],
deliverables: [
"React Bileşenleri",
"Responsive Tasarım",
"Mobil Uyumluluk",
],
risks: ["Tarayıcı uyumluluk sorunları", "Performans optimizasyonu"],
category: "Development",
deliverables: ['React Bileşenleri', 'Responsive Tasarım', 'Mobil Uyumluluk'],
risks: ['Tarayıcı uyumluluk sorunları', 'Performans optimizasyonu'],
category: PhaseCategoryEnum.Development,
sequence: 0,
tasks: [],
isActive: false,
},
{
id: "4",
code: "PH-004",
name: "Test ve Kalite Güvence",
description: "Kapsamlı test süreçleri ve kalite kontrolleri",
projectId: "2",
project: mockProjects.find((p) => p.id === "2")!,
id: '4',
code: 'PH-004',
name: 'Test ve Kalite Güvence',
description: 'Kapsamlı test süreçleri ve kalite kontrolleri',
projectId: '2',
project: mockProjects.find((p) => p.id === '2')!,
status: PhaseStatusEnum.NotStarted,
startDate: new Date("2024-07-01"),
endDate: new Date("2024-09-15"),
startDate: new Date('2024-07-01'),
endDate: new Date('2024-09-15'),
budget: 120000,
actualCost: 0,
progress: 0,
milestones: 3,
completedMilestones: 0,
assignedTeams: [
mockMaintenanceTeams.find((t) => t.id === "3")!.name,
mockMaintenanceTeams.find((t) => t.id === "4")!.name,
mockMaintenanceTeams.find((t) => t.id === '3')!.name,
mockMaintenanceTeams.find((t) => t.id === '4')!.name,
],
deliverables: [
"Test Senaryoları",
"Otomatik Test Süitleri",
"Kalite Raporu",
],
risks: ["Kritik hataların geç tespit edilmesi"],
category: "Testing",
deliverables: ['Test Senaryoları', 'Otomatik Test Süitleri', 'Kalite Raporu'],
risks: ['Kritik hataların geç tespit edilmesi'],
category: PhaseCategoryEnum.Testing,
sequence: 0,
tasks: [],
isActive: false,
},
{
id: "5",
code: "PH-005",
name: "Deployment ve Go-Live",
description: "Üretime alma ve kullanıcı eğitimleri",
projectId: "2",
project: mockProjects.find((p) => p.id === "2")!,
id: '5',
code: 'PH-005',
name: 'Deployment ve Go-Live',
description: 'Üretime alma ve kullanıcı eğitimleri',
projectId: '2',
project: mockProjects.find((p) => p.id === '2')!,
status: PhaseStatusEnum.NotStarted,
startDate: new Date("2024-09-15"),
endDate: new Date("2024-10-31"),
startDate: new Date('2024-09-15'),
endDate: new Date('2024-10-31'),
budget: 80000,
actualCost: 0,
progress: 0,
milestones: 2,
completedMilestones: 0,
assignedTeams: [
mockMaintenanceTeams.find((t) => t.id === "2")!.name,
mockMaintenanceTeams.find((t) => t.id === "4")!.name,
mockMaintenanceTeams.find((t) => t.id === '2')!.name,
mockMaintenanceTeams.find((t) => t.id === '4')!.name,
],
deliverables: [
"Prodüksiyon Ortamı",
"Kullanıcı Eğitimleri",
"Dokümentasyon",
],
risks: ["Sistem kesintileri", "Kullanıcı adaptasyon sorunları"],
category: "Deployment",
deliverables: ['Prodüksiyon Ortamı', 'Kullanıcı Eğitimleri', 'Dokümentasyon'],
risks: ['Sistem kesintileri', 'Kullanıcı adaptasyon sorunları'],
category: PhaseCategoryEnum.Deployment,
sequence: 0,
tasks: [],
isActive: false,
},
{
id: "6",
code: "PH-006",
name: "Mobil UI Tasarımı",
description: "Mobil uygulama kullanıcı arayüzü tasarımı",
projectId: "2",
project: mockProjects.find((p) => p.id === "2")!,
id: '6',
code: 'PH-006',
name: 'Mobil UI Tasarımı',
description: 'Mobil uygulama kullanıcı arayüzü tasarımı',
projectId: '2',
project: mockProjects.find((p) => p.id === '2')!,
status: PhaseStatusEnum.OnHold,
startDate: new Date("2024-03-01"),
endDate: new Date("2024-04-15"),
actualStartDate: new Date("2024-03-05"),
startDate: new Date('2024-03-01'),
endDate: new Date('2024-04-15'),
actualStartDate: new Date('2024-03-05'),
budget: 75000,
actualCost: 25000,
progress: 35,
milestones: 3,
completedMilestones: 1,
assignedTeams: [mockMaintenanceTeams.find((t) => t.id === "1")!.name],
deliverables: ["Wireframe'ler", "Mobil Tasarım Kılavuzu", "Prototype"],
risks: ["Platformlar arası tutarlılık sorunları"],
category: "Design",
assignedTeams: [mockMaintenanceTeams.find((t) => t.id === '1')!.name],
deliverables: ["Wireframe'ler", 'Mobil Tasarım Kılavuzu', 'Prototype'],
risks: ['Platformlar arası tutarlılık sorunları'],
category: PhaseCategoryEnum.Design,
sequence: 0,
tasks: [],
isActive: false,
},
];
]

View file

@ -1,40 +1,40 @@
import { NoteStatusEnum, NoteTypeEnum, PromissoryNote } from "../types/fi";
import { mockCurrentAccounts } from "./mockCurrentAccounts";
import { NoteStatusEnum, PromissoryNote, TypeEnum } from '../types/fi'
import { mockCurrentAccounts } from './mockCurrentAccounts'
export const mockPromissoryNotes: PromissoryNote[] = [
{
id: "1",
noteNumber: "NOT-001",
type: NoteTypeEnum.Received,
drawerName: "Müşteri A.Ş.",
payeeName: "ABC Şirket",
issueDate: new Date("2024-01-20"),
dueDate: new Date("2024-03-20"),
id: '1',
noteNumber: 'NOT-001',
type: TypeEnum.Received,
drawerName: 'Müşteri A.Ş.',
payeeName: 'ABC Şirket',
issueDate: new Date('2024-01-20'),
dueDate: new Date('2024-03-20'),
amount: 50000,
currency: "TRY",
currency: 'TRY',
status: NoteStatusEnum.InHand,
location: "Ana Kasa",
currentAccountId: "1",
currentAccount: mockCurrentAccounts.find((acc) => acc.id === "1"),
creationTime: new Date("2024-01-20"),
lastModificationTime: new Date("2024-01-20"),
location: 'Ana Kasa',
currentAccountId: '1',
currentAccount: mockCurrentAccounts.find((acc) => acc.id === '1'),
creationTime: new Date('2024-01-20'),
lastModificationTime: new Date('2024-01-20'),
},
{
id: "2",
noteNumber: "NOT-002",
type: NoteTypeEnum.Issued,
drawerName: "ABC Şirket",
payeeName: "Kefil A.Ş.",
issueDate: new Date("2024-01-05"),
dueDate: new Date("2024-03-05"),
id: '2',
noteNumber: 'NOT-002',
type: TypeEnum.Issued,
drawerName: 'ABC Şirket',
payeeName: 'Kefil A.Ş.',
issueDate: new Date('2024-01-05'),
dueDate: new Date('2024-03-05'),
amount: 30000,
currency: "TRY",
currency: 'TRY',
status: NoteStatusEnum.Collected,
location: "Banka",
collectionDate: new Date("2024-01-25"),
currentAccountId: "2",
currentAccount: mockCurrentAccounts.find((acc) => acc.id === "2"),
creationTime: new Date("2024-01-05"),
lastModificationTime: new Date("2024-01-25"),
location: 'Banka',
collectionDate: new Date('2024-01-25'),
currentAccountId: '2',
currentAccount: mockCurrentAccounts.find((acc) => acc.id === '2'),
creationTime: new Date('2024-01-05'),
lastModificationTime: new Date('2024-01-25'),
},
];
]

View file

@ -0,0 +1,28 @@
import { PmMachineType } from '../types/pm'
export const mockWorkCenterMachineTypes: PmMachineType[] = [
{
id: '1',
code: 'CNC',
name: 'CNC Makineleri',
isActive: true,
},
{
id: '2',
code: 'COMP',
name: 'Kompresörler',
isActive: true,
},
{
id: '3',
code: 'CONV',
name: 'Konveyörler',
isActive: true,
},
{
id: '4',
code: 'WELD',
name: 'Kaynak Makineleri',
isActive: true,
},
]

View file

@ -1,42 +1,39 @@
import {
CriticalityLevelEnum,
PmWorkCenter,
WorkCenterStatusEnum,
} from "../types/pm";
import { mockWorkCenterTypes } from "./mockWorkCenterTypes";
import { CriticalityLevelEnum, PmWorkCenter, WorkCenterStatusEnum } from '../types/pm'
import { mockWorkCenterMachineTypes } from './mockWorkCenterMachineTypes'
import { mockWorkCenterTypes } from './mockWorkCenterTypes'
export const mockWorkCenters: PmWorkCenter[] = [
{
id: "1",
code: "CNC-001",
name: "CNC Torna Tezgahı",
description: "Yüksek hassasiyetli CNC torna tezgahı",
workCenterId: "1",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "1")!,
manufacturer: "HAAS Automation",
model: "ST-30",
serialNumber: "SN123456789",
installationDate: new Date("2022-03-15"),
warrantyExpiry: new Date("2025-03-15"),
location: "Atölye A - Hat 1",
departmentId: "1",
id: '1',
code: 'CNC-001',
name: 'CNC Torna Tezgahı',
description: 'Yüksek hassasiyetli CNC torna tezgahı',
workCenterId: '1',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '1')!,
manufacturer: 'HAAS Automation',
model: 'ST-30',
serialNumber: 'SN123456789',
installationDate: new Date('2022-03-15'),
warrantyExpiry: new Date('2025-03-15'),
location: 'Atölye A - Hat 1',
departmentId: '1',
status: WorkCenterStatusEnum.Operational,
criticality: CriticalityLevelEnum.High,
specifications: [
{
id: "SPEC001",
workCenterId: "EQP001",
specificationName: "Max Çap",
specificationValue: "300",
unit: "mm",
id: 'SPEC001',
workCenterId: 'EQP001',
specificationName: 'Max Çap',
specificationValue: '300',
unit: 'mm',
isRequired: true,
},
{
id: "SPEC002",
workCenterId: "EQP001",
specificationName: "Motor Gücü",
specificationValue: "15",
unit: "kW",
id: 'SPEC002',
workCenterId: 'EQP001',
specificationName: 'Motor Gücü',
specificationValue: '15',
unit: 'kW',
isRequired: true,
},
],
@ -44,44 +41,45 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2022-03-15"),
lastModificationTime: new Date("2024-01-15"),
creationTime: new Date('2022-03-15'),
lastModificationTime: new Date('2024-01-15'),
capacity: 8,
costPerHour: 75,
setupTime: 15,
machineType: "CNC",
machineTypeId: '1',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '1')!,
},
{
id: "2",
code: "COMP-001",
name: "Hava Kompresörü",
description: "Endüstriyel hava kompresörü sistemi",
workCenterId: "2",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "2")!,
manufacturer: "Atlas Copco",
model: "GA55VSD+",
serialNumber: "AC987654321",
installationDate: new Date("2021-08-20"),
warrantyExpiry: new Date("2024-08-20"),
location: "Kompresör Odası",
departmentId: "2",
id: '2',
code: 'COMP-001',
name: 'Hava Kompresörü',
description: 'Endüstriyel hava kompresörü sistemi',
workCenterId: '2',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '2')!,
manufacturer: 'Atlas Copco',
model: 'GA55VSD+',
serialNumber: 'AC987654321',
installationDate: new Date('2021-08-20'),
warrantyExpiry: new Date('2024-08-20'),
location: 'Kompresör Odası',
departmentId: '2',
status: WorkCenterStatusEnum.UnderMaintenance,
criticality: CriticalityLevelEnum.Critical,
specifications: [
{
id: "SPEC003",
workCenterId: "EQP002",
specificationName: "Basınç",
specificationValue: "8.5",
unit: "bar",
id: 'SPEC003',
workCenterId: 'EQP002',
specificationName: 'Basınç',
specificationValue: '8.5',
unit: 'bar',
isRequired: true,
},
{
id: "SPEC004",
workCenterId: "EQP002",
specificationName: "Kapasite",
specificationValue: "55",
unit: "kW",
id: 'SPEC004',
workCenterId: 'EQP002',
specificationName: 'Kapasite',
specificationValue: '55',
unit: 'kW',
isRequired: true,
},
],
@ -89,43 +87,44 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2021-08-20"),
lastModificationTime: new Date("2024-02-01"),
creationTime: new Date('2021-08-20'),
lastModificationTime: new Date('2024-02-01'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '2',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '2')!,
capacity: 8,
},
{
id: "3",
code: "CONV-001",
name: "Konveyör Sistemi",
description: "Ana hat konveyör sistemi",
workCenterId: "3",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "3")!,
manufacturer: "Siemens",
model: "SIMATIC S7-1500",
serialNumber: "SM112233445",
installationDate: new Date("2020-11-10"),
location: "Ana Üretim Hattı",
departmentId: "3",
id: '3',
code: 'CONV-001',
name: 'Konveyör Sistemi',
description: 'Ana hat konveyör sistemi',
workCenterId: '3',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '3')!,
manufacturer: 'Siemens',
model: 'SIMATIC S7-1500',
serialNumber: 'SM112233445',
installationDate: new Date('2020-11-10'),
location: 'Ana Üretim Hattı',
departmentId: '3',
status: WorkCenterStatusEnum.OutOfOrder,
criticality: CriticalityLevelEnum.Medium,
specifications: [
{
id: "SPEC005",
workCenterId: "EQP003",
specificationName: "Hız",
specificationValue: "2.5",
unit: "m/s",
id: 'SPEC005',
workCenterId: 'EQP003',
specificationName: 'Hız',
specificationValue: '2.5',
unit: 'm/s',
isRequired: true,
},
{
id: "SPEC006",
workCenterId: "EQP003",
specificationName: "Yük Kapasitesi",
specificationValue: "500",
unit: "kg",
id: 'SPEC006',
workCenterId: 'EQP003',
specificationName: 'Yük Kapasitesi',
specificationValue: '500',
unit: 'kg',
isRequired: true,
},
],
@ -133,44 +132,45 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2020-11-10"),
lastModificationTime: new Date("2024-02-05"),
creationTime: new Date('2020-11-10'),
lastModificationTime: new Date('2024-02-05'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '3',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '3')!,
capacity: 8,
},
{
id: "4",
code: "KELD-001",
name: "Kaynak Makinesi",
description: "Otomatik robot kaynak sistemi",
workCenterId: "4",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "4")!,
manufacturer: "KUKA",
model: "KR 60-3",
serialNumber: "KU556677889",
installationDate: new Date("2023-01-15"),
warrantyExpiry: new Date("2026-01-15"),
location: "Kaynak Atölyesi",
departmentId: "4",
id: '4',
code: 'KELD-001',
name: 'Kaynak Makinesi',
description: 'Otomatik robot kaynak sistemi',
workCenterId: '4',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '4')!,
manufacturer: 'KUKA',
model: 'KR 60-3',
serialNumber: 'KU556677889',
installationDate: new Date('2023-01-15'),
warrantyExpiry: new Date('2026-01-15'),
location: 'Kaynak Atölyesi',
departmentId: '4',
status: WorkCenterStatusEnum.Operational,
criticality: CriticalityLevelEnum.High,
specifications: [
{
id: "SPEC007",
workCenterId: "EQP004",
specificationName: "Erişim Mesafesi",
specificationValue: "2033",
unit: "mm",
id: 'SPEC007',
workCenterId: 'EQP004',
specificationName: 'Erişim Mesafesi',
specificationValue: '2033',
unit: 'mm',
isRequired: true,
},
{
id: "SPEC008",
workCenterId: "EQP004",
specificationName: "Taşıma Kapasitesi",
specificationValue: "60",
unit: "kg",
id: 'SPEC008',
workCenterId: 'EQP004',
specificationName: 'Taşıma Kapasitesi',
specificationValue: '60',
unit: 'kg',
isRequired: true,
},
],
@ -178,44 +178,45 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2023-01-15"),
lastModificationTime: new Date("2024-01-20"),
creationTime: new Date('2023-01-15'),
lastModificationTime: new Date('2024-01-20'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '3',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '3')!,
capacity: 8,
},
{
id: "5",
code: "WELL-001",
name: "Yıkama Makinesi",
description: "Otomatik robot kaynak sistemi",
workCenterId: "4",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "4")!,
manufacturer: "KUKA",
model: "KR 60-3",
serialNumber: "KU556677889",
installationDate: new Date("2023-01-15"),
warrantyExpiry: new Date("2026-01-15"),
location: "Kaynak Atölyesi",
departmentId: "4",
id: '5',
code: 'WELL-001',
name: 'Yıkama Makinesi',
description: 'Otomatik robot kaynak sistemi',
workCenterId: '4',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '4')!,
manufacturer: 'KUKA',
model: 'KR 60-3',
serialNumber: 'KU556677889',
installationDate: new Date('2023-01-15'),
warrantyExpiry: new Date('2026-01-15'),
location: 'Kaynak Atölyesi',
departmentId: '4',
status: WorkCenterStatusEnum.Operational,
criticality: CriticalityLevelEnum.High,
specifications: [
{
id: "SPEC007",
workCenterId: "EQP004",
specificationName: "Erişim Mesafesi",
specificationValue: "2033",
unit: "mm",
id: 'SPEC007',
workCenterId: 'EQP004',
specificationName: 'Erişim Mesafesi',
specificationValue: '2033',
unit: 'mm',
isRequired: true,
},
{
id: "SPEC008",
workCenterId: "EQP004",
specificationName: "Taşıma Kapasitesi",
specificationValue: "60",
unit: "kg",
id: 'SPEC008',
workCenterId: 'EQP004',
specificationName: 'Taşıma Kapasitesi',
specificationValue: '60',
unit: 'kg',
isRequired: true,
},
],
@ -223,44 +224,45 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2023-01-15"),
lastModificationTime: new Date("2024-01-20"),
creationTime: new Date('2023-01-15'),
lastModificationTime: new Date('2024-01-20'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '4',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '4')!,
capacity: 8,
},
{
id: "6",
code: "KELD-001",
name: "Ram Makinesi",
description: "Otomatik robot kaynak sistemi",
workCenterId: "4",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "4")!,
manufacturer: "KUKA",
model: "KR 60-3",
serialNumber: "KU556677889",
installationDate: new Date("2023-01-15"),
warrantyExpiry: new Date("2026-01-15"),
location: "Kaynak Atölyesi",
departmentId: "4",
id: '6',
code: 'KELD-001',
name: 'Ram Makinesi',
description: 'Otomatik robot kaynak sistemi',
workCenterId: '4',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '4')!,
manufacturer: 'KUKA',
model: 'KR 60-3',
serialNumber: 'KU556677889',
installationDate: new Date('2023-01-15'),
warrantyExpiry: new Date('2026-01-15'),
location: 'Kaynak Atölyesi',
departmentId: '4',
status: WorkCenterStatusEnum.Operational,
criticality: CriticalityLevelEnum.High,
specifications: [
{
id: "SPEC007",
workCenterId: "EQP004",
specificationName: "Erişim Mesafesi",
specificationValue: "2033",
unit: "mm",
id: 'SPEC007',
workCenterId: 'EQP004',
specificationName: 'Erişim Mesafesi',
specificationValue: '2033',
unit: 'mm',
isRequired: true,
},
{
id: "SPEC008",
workCenterId: "EQP004",
specificationName: "Taşıma Kapasitesi",
specificationValue: "60",
unit: "kg",
id: 'SPEC008',
workCenterId: 'EQP004',
specificationName: 'Taşıma Kapasitesi',
specificationValue: '60',
unit: 'kg',
isRequired: true,
},
],
@ -268,44 +270,45 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2023-01-15"),
lastModificationTime: new Date("2024-01-20"),
creationTime: new Date('2023-01-15'),
lastModificationTime: new Date('2024-01-20'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '4',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '4')!,
capacity: 8,
},
{
id: "7",
code: "WEID-001",
name: "Sarma Makinesi",
description: "Otomatik robot kaynak sistemi",
workCenterId: "4",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "4")!,
manufacturer: "KUKA",
model: "KR 60-3",
serialNumber: "KU556677889",
installationDate: new Date("2023-01-15"),
warrantyExpiry: new Date("2026-01-15"),
location: "Kaynak Atölyesi",
departmentId: "4",
id: '7',
code: 'WEID-001',
name: 'Sarma Makinesi',
description: 'Otomatik robot kaynak sistemi',
workCenterId: '4',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '4')!,
manufacturer: 'KUKA',
model: 'KR 60-3',
serialNumber: 'KU556677889',
installationDate: new Date('2023-01-15'),
warrantyExpiry: new Date('2026-01-15'),
location: 'Kaynak Atölyesi',
departmentId: '4',
status: WorkCenterStatusEnum.Operational,
criticality: CriticalityLevelEnum.High,
specifications: [
{
id: "SPEC007",
workCenterId: "EQP004",
specificationName: "Erişim Mesafesi",
specificationValue: "2033",
unit: "mm",
id: 'SPEC007',
workCenterId: 'EQP004',
specificationName: 'Erişim Mesafesi',
specificationValue: '2033',
unit: 'mm',
isRequired: true,
},
{
id: "SPEC008",
workCenterId: "EQP004",
specificationName: "Taşıma Kapasitesi",
specificationValue: "60",
unit: "kg",
id: 'SPEC008',
workCenterId: 'EQP004',
specificationName: 'Taşıma Kapasitesi',
specificationValue: '60',
unit: 'kg',
isRequired: true,
},
],
@ -313,44 +316,45 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2023-01-15"),
lastModificationTime: new Date("2024-01-20"),
creationTime: new Date('2023-01-15'),
lastModificationTime: new Date('2024-01-20'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '1',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '1')!,
capacity: 8,
},
{
id: "8",
code: "KEL-001",
name: "Robot Kaynak Makinesi",
description: "Otomatik robot kaynak sistemi",
workCenterId: "4",
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === "4")!,
manufacturer: "KUKA",
model: "KR 60-3",
serialNumber: "KU556677889",
installationDate: new Date("2023-01-15"),
warrantyExpiry: new Date("2026-01-15"),
location: "Kaynak Atölyesi",
departmentId: "4",
id: '8',
code: 'KEL-001',
name: 'Robot Kaynak Makinesi',
description: 'Otomatik robot kaynak sistemi',
workCenterId: '4',
workCenterType: mockWorkCenterTypes.find((wct) => wct.code === '4')!,
manufacturer: 'KUKA',
model: 'KR 60-3',
serialNumber: 'KU556677889',
installationDate: new Date('2023-01-15'),
warrantyExpiry: new Date('2026-01-15'),
location: 'Kaynak Atölyesi',
departmentId: '4',
status: WorkCenterStatusEnum.Operational,
criticality: CriticalityLevelEnum.High,
specifications: [
{
id: "SPEC007",
workCenterId: "EQP004",
specificationName: "Erişim Mesafesi",
specificationValue: "2033",
unit: "mm",
id: 'SPEC007',
workCenterId: 'EQP004',
specificationName: 'Erişim Mesafesi',
specificationValue: '2033',
unit: 'mm',
isRequired: true,
},
{
id: "SPEC008",
workCenterId: "EQP004",
specificationName: "Taşıma Kapasitesi",
specificationValue: "60",
unit: "kg",
id: 'SPEC008',
workCenterId: 'EQP004',
specificationName: 'Taşıma Kapasitesi',
specificationValue: '60',
unit: 'kg',
isRequired: true,
},
],
@ -358,11 +362,12 @@ export const mockWorkCenters: PmWorkCenter[] = [
workOrders: [],
downTimeHistory: [],
isActive: true,
creationTime: new Date("2023-01-15"),
lastModificationTime: new Date("2024-01-20"),
creationTime: new Date('2023-01-15'),
lastModificationTime: new Date('2024-01-20'),
costPerHour: 85,
setupTime: 20,
machineType: "CNC",
machineTypeId: '1',
machineType: mockWorkCenterMachineTypes.find((mt) => mt.id === '1')!,
capacity: 8,
},
];
]

View file

@ -42,7 +42,7 @@ export interface BusinessParty {
partyType: PartyType
primaryContact?: Contact
contacts?: Contact[]
industry?: string
industry?: BusinessPartyIndustryEnum
email?: string
phone?: string
website?: string
@ -77,6 +77,21 @@ export interface BusinessParty {
bankAccounts?: BankAccount[]
}
export enum BusinessPartyIndustryEnum {
// İş Ortağı Endüstrisi
Technology = 'TECHNOLOGY', // Teknoloji
Healthcare = 'HEALTHCARE', // Sağlık
Finance = 'FINANCE', // Finans
Retail = 'RETAIL', // Perakende
Manufacturing = 'MANUFACTURING', // Üretim
Education = 'EDUCATION', // Eğitim
Construction = 'CONSTRUCTION', // İnşaat
Hospitality = 'HOSPITALITY', // Konaklama
Transportation = 'TRANSPORTATION', // Ulaşım
RealEstate = 'REAL_ESTATE', // Emlak
Other = 'OTHER', // Diğer
}
export enum BusinessPartyStatusEnum {
// İş Ortağı Durumu
Prospect = 'PROSPECT', // Potansiyel

View file

@ -205,7 +205,7 @@ export interface FiCheck {
amount: number
currency: string
status: CheckStatusEnum
type: CheckTypeEnum
type: TypeEnum
bankingDate?: Date
collectionDate?: Date
endorsedTo?: string
@ -227,7 +227,7 @@ export interface PromissoryNote {
amount: number
currency: string
status: NoteStatusEnum
type: NoteTypeEnum // Received or Issued
type: TypeEnum // Received or Issued
collectionDate?: Date
endorsedTo?: string
location?: string
@ -321,7 +321,7 @@ export enum CheckStatusEnum {
Cancelled = 'CANCELLED', // İPTAL EDİLDİ
}
export enum CheckTypeEnum {
export enum TypeEnum {
Received = 'RECEIVED', // ALINAN
Issued = 'ISSUED', // VERİLEN
}
@ -334,11 +334,6 @@ export enum NoteStatusEnum {
Cancelled = 'CANCELLED', // İPTAL EDİLDİ
}
export enum NoteTypeEnum {
Received = 'RECEIVED', // Alınan
Issued = 'ISSUED', // Verilen
}
export enum WaybillTypeEnum {
Outgoing = 'outgoing', // Çıkış İrsaliyesi
Incoming = 'incoming', // Giriş İrsaliyesi

View file

@ -758,3 +758,20 @@ export enum QuestionTypeEnum {
YesNo = 'YES_NO', // Evet/Hayır
Scale = 'SCALE', // Ölçek (1-10 gibi)
}
export const getQuestionTypeText = (type: QuestionTypeEnum) => {
switch (type) {
case QuestionTypeEnum.Rating:
return 'Puanlama'
case QuestionTypeEnum.MultipleChoice:
return 'Çoktan Seçmeli'
case QuestionTypeEnum.Text:
return 'Metin'
case QuestionTypeEnum.YesNo:
return 'Evet/Hayır'
case QuestionTypeEnum.Scale:
return 'Ölçek'
default:
return 'Bilinmeyen'
}
}

View file

@ -559,9 +559,11 @@ export enum OrderStatusEnum {
export enum SupplierTypeEnum {
// Tedarikçi Türü
Material = 'MATERIAL', // Malzeme
Service = 'SERVICE', // Hizmet
Both = 'BOTH', // Her ikisi
Manufacturer = 'MANUFACTURER', // Üretici
Distributor = 'DISTRIBUTOR', // Distribütör
Wholesaler = 'WHOLESALER', // Toptancı
ServiceProvider = 'SERVICE_PROVIDER', // Hizmet Sağlayıcı
Other = 'OTHER', // Diğer
}
export enum RequisitionStatusEnum {

View file

@ -29,7 +29,8 @@ export interface PmWorkCenter {
capacity: number
costPerHour: number
setupTime: number
machineType: string
machineTypeId: string
machineType?: PmMachineType
isActive: boolean
creationTime: Date
lastModificationTime: Date
@ -45,6 +46,14 @@ export interface PmWorkCenterType {
isActive: boolean
}
export interface PmMachineType {
// Makina Türü
id: string
code: string
name: string
isActive: boolean
}
export interface PmWorkCenterSpecification {
// İş Merkezi / Ekipman Özelliği
id: string

View file

@ -55,7 +55,7 @@ export interface PsProjectPhase {
assignedTeams: string[]
deliverables: string[]
risks: string[]
category: string
category: PhaseCategoryEnum
}
export interface PsProjectTask {
@ -172,7 +172,7 @@ export interface PsProjectCostTracking {
plannedDuration: number // days
actualDuration?: number // days
progress: number // percentage
status: 'ON_TRACK' | 'AT_RISK' | 'DELAYED' | 'COMPLETED'
status: ProjectCostTrackingStatus
currency: string
lastUpdated: Date
}
@ -255,6 +255,15 @@ export enum ProjectStatusEnum {
Cancelled = 'CANCELLED', // İptal Edildi
}
export enum PhaseCategoryEnum {
// Category of Phase
Planning = 'PLANNING', // Planlama
Development = 'EXECUTION', // Yürütme
Testing = 'MONITORING', // İzleme
Deployment = 'CLOSURE', // Kapanış
Design = 'OTHER', // Diğer
}
export enum PhaseStatusEnum {
// Faz Durumu
NotStarted = 'NOT_STARTED', // Başlanmadı
@ -354,3 +363,11 @@ export enum PsDocumentTypeEnum {
Manual = 'MANUAL', // Kılavuz
Other = 'OTHER', // Diğer
}
export enum ProjectCostTrackingStatus {
// Proje Maliyet Takibi Durumu
OnTrack = 'ON_TRACK', // Planında
AtRisk = 'AT_RISK', // Riskte
Delayed = 'DELAYED', // Gecikmiş
Completed = 'COMPLETED', // Tamamlandı
}

File diff suppressed because it is too large Load diff

View file

@ -1,159 +1,151 @@
import React, { useState, useEffect } from "react";
import { FaSave, FaTimes, FaBuilding } from "react-icons/fa";
import { BankAccountTypeEnum } from "../../../types/fi";
import { BankAccount } from "../../../types/common";
import React, { useState, useEffect } from 'react'
import { FaSave, FaTimes, FaBuilding } from 'react-icons/fa'
import { BankAccountTypeEnum } from '../../../types/fi'
import { BankAccount } from '../../../types/common'
import { getBankAccountTypeText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface BankAccountFormProps {
account?: BankAccount;
isOpen: boolean;
onClose: () => void;
onSave: (account: Partial<BankAccount>) => void;
account?: BankAccount
isOpen: boolean
onClose: () => void
onSave: (account: Partial<BankAccount>) => void
}
const BankAccountForm: React.FC<BankAccountFormProps> = ({
account,
isOpen,
onClose,
onSave,
}) => {
const BankAccountForm: React.FC<BankAccountFormProps> = ({ account, isOpen, onClose, onSave }) => {
const [formData, setFormData] = useState<Partial<BankAccount>>({
accountCode: "",
bankName: "",
branchName: "",
accountNumber: "",
iban: "",
accountCode: '',
bankName: '',
branchName: '',
accountNumber: '',
iban: '',
accountType: BankAccountTypeEnum.Current,
currency: "TRY",
currency: 'TRY',
balance: 0,
overdraftLimit: 0,
dailyTransferLimit: 0,
contactPerson: "",
phone: "",
contactPerson: '',
phone: '',
isActive: true,
});
})
const [errors, setErrors] = useState<Record<string, string>>({});
const [errors, setErrors] = useState<Record<string, string>>({})
useEffect(() => {
if (account) {
setFormData(account);
setFormData(account)
} else {
setFormData({
accountCode: "",
bankName: "",
branchName: "",
accountNumber: "",
iban: "",
accountCode: '',
bankName: '',
branchName: '',
accountNumber: '',
iban: '',
accountType: BankAccountTypeEnum.Current,
currency: "TRY",
currency: 'TRY',
balance: 0,
overdraftLimit: 0,
dailyTransferLimit: 0,
contactPerson: "",
phone: "",
contactPerson: '',
phone: '',
isActive: true,
});
})
}
setErrors({});
}, [account, isOpen]);
setErrors({})
}, [account, isOpen])
const validateForm = () => {
const newErrors: Record<string, string> = {};
const newErrors: Record<string, string> = {}
if (!formData.accountCode?.trim()) {
newErrors.accountCode = "Hesap kodu gereklidir";
newErrors.accountCode = 'Hesap kodu gereklidir'
}
if (!formData.bankName?.trim()) {
newErrors.bankName = "Banka adı gereklidir";
newErrors.bankName = 'Banka adı gereklidir'
}
if (!formData.branchName?.trim()) {
newErrors.branchName = "Şube adı gereklidir";
newErrors.branchName = 'Şube adı gereklidir'
}
if (!formData.accountNumber?.trim()) {
newErrors.accountNumber = "Hesap numarası gereklidir";
newErrors.accountNumber = 'Hesap numarası gereklidir'
}
if (!formData.iban?.trim()) {
newErrors.iban = "IBAN gereklidir";
newErrors.iban = 'IBAN gereklidir'
} else if (formData.iban.length < 26) {
newErrors.iban = "IBAN geçerli formatta olmalıdır";
newErrors.iban = 'IBAN geçerli formatta olmalıdır'
}
if (!formData.currency?.trim()) {
newErrors.currency = "Para birimi gereklidir";
newErrors.currency = 'Para birimi gereklidir'
}
if (
formData.dailyTransferLimit !== undefined &&
formData.dailyTransferLimit < 0
) {
newErrors.dailyTransferLimit = "Günlük transfer limiti negatif olamaz";
if (formData.dailyTransferLimit !== undefined && formData.dailyTransferLimit < 0) {
newErrors.dailyTransferLimit = 'Günlük transfer limiti negatif olamaz'
}
if (formData.overdraftLimit !== undefined && formData.overdraftLimit < 0) {
newErrors.overdraftLimit = "Kredi limiti negatif olamaz";
newErrors.overdraftLimit = 'Kredi limiti negatif olamaz'
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (validateForm()) {
onSave(formData);
onSave(formData)
}
};
}
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
) => {
const { name, value, type } = e.target;
const parsedValue = type === "number" ? parseFloat(value) || 0 : value;
const { name, value, type } = e.target
const parsedValue = type === 'number' ? parseFloat(value) || 0 : value
setFormData((prev) => ({
...prev,
[name]: parsedValue,
}));
}))
// Clear error when user starts typing
if (errors[name]) {
setErrors((prev) => ({
...prev,
[name]: "",
}));
[name]: '',
}))
}
};
}
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, checked } = e.target;
const { name, checked } = e.target
setFormData((prev) => ({
...prev,
[name]: checked,
}));
};
}))
}
const handleIbanChange = (e: React.ChangeEvent<HTMLInputElement>) => {
let value = e.target.value;
let value = e.target.value
// Sadece harf ve rakam kalsın
value = value.replace(/[^A-Za-z0-9]/g, "");
value = value.replace(/[^A-Za-z0-9]/g, '')
// 4 karakterde bir boşluk ekle
value = value.replace(/(.{4})/g, "$1 ").trim();
value = value.replace(/(.{4})/g, '$1 ').trim()
setFormData({
...formData,
iban: value,
});
};
})
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
@ -162,7 +154,7 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
<div className="flex items-center gap-2.5">
<FaBuilding className="w-5 h-5 text-blue-600" />
<h2 className="text-lg font-semibold text-gray-900">
{account ? "Banka Hesabını Düzenle" : "Yeni Banka Hesabı"}
{account ? 'Banka Hesabını Düzenle' : 'Yeni Banka Hesabı'}
</h2>
</div>
<button
@ -182,80 +174,67 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Hesap Kodu *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Hesap Kodu *</label>
<input
type="text"
name="accountCode"
value={formData.accountCode || ""}
value={formData.accountCode || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.accountCode ? "border-red-500" : "border-gray-300"
errors.accountCode ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Örn: BANKA001"
/>
{errors.accountCode && (
<p className="text-red-500 text-xs mt-1">
{errors.accountCode}
</p>
<p className="text-red-500 text-xs mt-1">{errors.accountCode}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Banka Adı *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Banka Adı *</label>
<input
type="text"
name="bankName"
value={formData.bankName || ""}
value={formData.bankName || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.bankName ? "border-red-500" : "border-gray-300"
errors.bankName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Örn: İş Bankası"
/>
{errors.bankName && (
<p className="text-red-500 text-xs mt-1">{errors.bankName}</p>
)}
{errors.bankName && <p className="text-red-500 text-xs mt-1">{errors.bankName}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Şube Adı *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Şube Adı *</label>
<input
type="text"
name="branchName"
value={formData.branchName || ""}
value={formData.branchName || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.branchName ? "border-red-500" : "border-gray-300"
errors.branchName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Örn: Levent Şubesi"
/>
{errors.branchName && (
<p className="text-red-500 text-xs mt-1">
{errors.branchName}
</p>
<p className="text-red-500 text-xs mt-1">{errors.branchName}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Hesap Türü
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Hesap Türü</label>
<select
name="accountType"
value={formData.accountType || BankAccountTypeEnum.Current}
onChange={handleInputChange}
className="w-full 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={BankAccountTypeEnum.Current}>Vadesiz</option>
<option value={BankAccountTypeEnum.Deposit}>Vadeli</option>
<option value={BankAccountTypeEnum.Credit}>Kredi</option>
<option value={BankAccountTypeEnum.Foreign}>Döviz</option>
{Object.values(BankAccountTypeEnum).map((type) => (
<option key={type} value={type}>
{getBankAccountTypeText(type)}
</option>
))}
</select>
</div>
@ -265,20 +244,19 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
</label>
<select
name="currency"
value={formData.currency || "TRY"}
value={formData.currency || 'TRY'}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.currency ? "border-red-500" : "border-gray-300"
errors.currency ? 'border-red-500' : 'border-gray-300'
}`}
>
<option value="TRY">TRY - Türk Lirası</option>
<option value="USD">USD - Amerikan Doları</option>
<option value="EUR">EUR - Euro</option>
<option value="GBP">GBP - İngiliz Sterlini</option>
{mockCurrencies.map((cur) => (
<option key={cur.value} value={cur.value}>
{cur.value} - {cur.label}
</option>
))}
</select>
{errors.currency && (
<p className="text-red-500 text-xs mt-1">{errors.currency}</p>
)}
{errors.currency && <p className="text-red-500 text-xs mt-1">{errors.currency}</p>}
</div>
</div>
@ -295,38 +273,32 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
<input
type="text"
name="accountNumber"
value={formData.accountNumber || ""}
value={formData.accountNumber || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.accountNumber ? "border-red-500" : "border-gray-300"
errors.accountNumber ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="1234567890"
/>
{errors.accountNumber && (
<p className="text-red-500 text-xs mt-1">
{errors.accountNumber}
</p>
<p className="text-red-500 text-xs mt-1">{errors.accountNumber}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
IBAN *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">IBAN *</label>
<input
type="text"
name="iban"
value={formData.iban || ""}
value={formData.iban || ''}
onChange={handleIbanChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono ${
errors.iban ? "border-red-500" : "border-gray-300"
errors.iban ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="TR12 0006 4000 0011 2345 6789 01"
maxLength={34}
/>
{errors.iban && (
<p className="text-red-500 text-xs mt-1">{errors.iban}</p>
)}
{errors.iban && <p className="text-red-500 text-xs mt-1">{errors.iban}</p>}
</div>
<div>
@ -344,24 +316,20 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Kredi Limiti
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Kredi Limiti</label>
<input
type="number"
name="overdraftLimit"
value={formData.overdraftLimit || 0}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.overdraftLimit ? "border-red-500" : "border-gray-300"
errors.overdraftLimit ? 'border-red-500' : 'border-gray-300'
}`}
step="0.01"
min="0"
/>
{errors.overdraftLimit && (
<p className="text-red-500 text-xs mt-1">
{errors.overdraftLimit}
</p>
<p className="text-red-500 text-xs mt-1">{errors.overdraftLimit}</p>
)}
</div>
@ -375,17 +343,13 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
value={formData.dailyTransferLimit || 0}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.dailyTransferLimit
? "border-red-500"
: "border-gray-300"
errors.dailyTransferLimit ? 'border-red-500' : 'border-gray-300'
}`}
step="0.01"
min="0"
/>
{errors.dailyTransferLimit && (
<p className="text-red-500 text-xs mt-1">
{errors.dailyTransferLimit}
</p>
<p className="text-red-500 text-xs mt-1">{errors.dailyTransferLimit}</p>
)}
</div>
</div>
@ -404,7 +368,7 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
<input
type="text"
name="contactPerson"
value={formData.contactPerson || ""}
value={formData.contactPerson || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Ad Soyad"
@ -412,13 +376,11 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Telefon
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Telefon</label>
<input
type="tel"
name="phone"
value={formData.phone || ""}
value={formData.phone || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="+90 212 555 1234"
@ -434,9 +396,7 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
onChange={handleCheckboxChange}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label className="ml-2 block text-sm text-gray-700">
Hesap aktif
</label>
<label className="ml-2 block text-sm text-gray-700">Hesap aktif</label>
</div>
</div>
</div>
@ -455,13 +415,13 @@ const BankAccountForm: React.FC<BankAccountFormProps> = ({
className="flex items-center gap-2 px-3 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
<FaSave className="w-4 h-4" />
{account ? "Güncelle" : "Kaydet"}
{account ? 'Güncelle' : 'Kaydet'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default BankAccountForm;
export default BankAccountForm

View file

@ -1,20 +1,15 @@
import React, { useState, useEffect } from "react";
import { FaCreditCard, FaSave, FaTimes } from "react-icons/fa";
import {
FiCheck,
CheckTypeEnum,
CheckStatusEnum,
FiCurrentAccount,
} from "../../../types/fi";
import React, { useState, useEffect } from 'react'
import { FaCreditCard, FaSave, FaTimes } from 'react-icons/fa'
import { FiCheck, TypeEnum, CheckStatusEnum, FiCurrentAccount } from '../../../types/fi'
import { getCheckStatusText, getTypeText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface CheckFormProps {
check?: FiCheck;
currentAccounts: FiCurrentAccount[];
onSave: (
check: Omit<FiCheck, "id" | "creationTime" | "lastModificationTime">
) => void;
onCancel: () => void;
isOpen: boolean;
check?: FiCheck
currentAccounts: FiCurrentAccount[]
onSave: (check: Omit<FiCheck, 'id' | 'creationTime' | 'lastModificationTime'>) => void
onCancel: () => void
isOpen: boolean
}
const CheckForm: React.FC<CheckFormProps> = ({
@ -25,23 +20,23 @@ const CheckForm: React.FC<CheckFormProps> = ({
isOpen,
}) => {
const [formData, setFormData] = useState({
checkNumber: "",
bankName: "",
branchName: "",
accountNumber: "",
drawerName: "",
payeeName: "",
currentAccountId: "",
issueDate: new Date().toISOString().split("T")[0],
dueDate: new Date().toISOString().split("T")[0],
checkNumber: '',
bankName: '',
branchName: '',
accountNumber: '',
drawerName: '',
payeeName: '',
currentAccountId: '',
issueDate: new Date().toISOString().split('T')[0],
dueDate: new Date().toISOString().split('T')[0],
amount: 0,
currency: "TRY",
currency: 'TRY',
status: CheckStatusEnum.InHand,
type: CheckTypeEnum.Received,
notes: "",
});
type: TypeEnum.Received,
notes: '',
})
const [errors, setErrors] = useState<Record<string, string>>({});
const [errors, setErrors] = useState<Record<string, string>>({})
useEffect(() => {
if (check) {
@ -52,64 +47,64 @@ const CheckForm: React.FC<CheckFormProps> = ({
accountNumber: check.accountNumber,
drawerName: check.drawerName,
payeeName: check.payeeName,
currentAccountId: check.currentAccountId || "",
issueDate: new Date(check.issueDate).toISOString().split("T")[0],
dueDate: new Date(check.dueDate).toISOString().split("T")[0],
currentAccountId: check.currentAccountId || '',
issueDate: new Date(check.issueDate).toISOString().split('T')[0],
dueDate: new Date(check.dueDate).toISOString().split('T')[0],
amount: check.amount,
currency: check.currency,
status: check.status,
type: check.type,
notes: check.notes || "",
});
notes: check.notes || '',
})
} else {
setFormData({
checkNumber: "",
bankName: "",
branchName: "",
accountNumber: "",
drawerName: "",
payeeName: "",
currentAccountId: "",
issueDate: new Date().toISOString().split("T")[0],
dueDate: new Date().toISOString().split("T")[0],
checkNumber: '',
bankName: '',
branchName: '',
accountNumber: '',
drawerName: '',
payeeName: '',
currentAccountId: '',
issueDate: new Date().toISOString().split('T')[0],
dueDate: new Date().toISOString().split('T')[0],
amount: 0,
currency: "TRY",
currency: 'TRY',
status: CheckStatusEnum.InHand,
type: CheckTypeEnum.Received,
notes: "",
});
type: TypeEnum.Received,
notes: '',
})
}
setErrors({});
}, [check, isOpen]);
setErrors({})
}, [check, isOpen])
const validateForm = () => {
const newErrors: Record<string, string> = {};
const newErrors: Record<string, string> = {}
if (!formData.checkNumber.trim()) {
newErrors.checkNumber = "Çek numarası gereklidir";
newErrors.checkNumber = 'Çek numarası gereklidir'
}
if (!formData.bankName.trim()) {
newErrors.bankName = "Banka adı gereklidir";
newErrors.bankName = 'Banka adı gereklidir'
}
if (!formData.drawerName.trim()) {
newErrors.drawerName = "Keşideci adı gereklidir";
newErrors.drawerName = 'Keşideci adı gereklidir'
}
if (!formData.payeeName.trim()) {
newErrors.payeeName = "Lehtar adı gereklidir";
newErrors.payeeName = 'Lehtar adı gereklidir'
}
if (formData.amount <= 0) {
newErrors.amount = "Tutar 0'dan büyük olmalıdır";
newErrors.amount = "Tutar 0'dan büyük olmalıdır"
}
if (new Date(formData.dueDate) < new Date(formData.issueDate)) {
newErrors.dueDate = "Vade tarihi düzenleme tarihinden sonra olmalıdır";
newErrors.dueDate = 'Vade tarihi düzenleme tarihinden sonra olmalıdır'
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (validateForm()) {
const checkData = {
...formData,
@ -118,22 +113,22 @@ const CheckForm: React.FC<CheckFormProps> = ({
currentAccount: formData.currentAccountId
? currentAccounts.find((acc) => acc.id === formData.currentAccountId)
: undefined,
};
onSave(checkData);
}
onSave(checkData)
}
};
}
const handleInputChange = (
field: string,
value: string | number | CheckTypeEnum | CheckStatusEnum
value: string | number | TypeEnum | CheckStatusEnum,
) => {
setFormData((prev) => ({ ...prev, [field]: value }));
setFormData((prev) => ({ ...prev, [field]: value }))
if (errors[field]) {
setErrors((prev) => ({ ...prev, [field]: "" }));
setErrors((prev) => ({ ...prev, [field]: '' }))
}
};
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
@ -142,13 +137,10 @@ const CheckForm: React.FC<CheckFormProps> = ({
<div className="flex items-center gap-2.5">
<FaCreditCard className="w-5 h-5 text-blue-600" />
<h2 className="text-lg font-semibold text-gray-900">
{check ? "Çek Düzenle" : "Yeni Çek"}
{check ? 'Çek Düzenle' : 'Yeni Çek'}
</h2>
</div>
<button
onClick={onCancel}
className="p-2 hover:bg-gray-100 rounded-md"
>
<button onClick={onCancel} className="p-2 hover:bg-gray-100 rounded-md">
<FaTimes className="w-5 h-5 text-gray-500" />
</button>
</div>
@ -157,102 +149,76 @@ const CheckForm: React.FC<CheckFormProps> = ({
{/* Çek Bilgileri */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Çek Numarası *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Çek Numarası *</label>
<input
type="text"
value={formData.checkNumber}
onChange={(e) =>
handleInputChange("checkNumber", e.target.value)
}
onChange={(e) => handleInputChange('checkNumber', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.checkNumber ? "border-red-500" : "border-gray-300"
errors.checkNumber ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Çek numarasını giriniz"
/>
{errors.checkNumber && (
<p className="text-red-500 text-xs mt-1">
{errors.checkNumber}
</p>
<p className="text-red-500 text-xs mt-1">{errors.checkNumber}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Tür *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Tür *</label>
<select
value={formData.type}
onChange={(e) =>
handleInputChange("type", e.target.value as CheckTypeEnum)
}
onChange={(e) => handleInputChange('type', e.target.value as TypeEnum)}
className="w-full 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={CheckTypeEnum.Received}>Alınan Çek</option>
<option value={CheckTypeEnum.Issued}>Verilen Çek</option>
{Object.values(TypeEnum).map((type) => (
<option key={type} value={type}>
{getTypeText(type)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Durum
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Durum</label>
<select
value={formData.status}
onChange={(e) =>
handleInputChange("status", e.target.value as CheckStatusEnum)
}
onChange={(e) => handleInputChange('status', e.target.value as CheckStatusEnum)}
className="w-full 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={CheckStatusEnum.InHand}>Elde</option>
<option value={CheckStatusEnum.Deposited}>
Bankaya Verildi
</option>
<option value={CheckStatusEnum.Collected}>Tahsil Edildi</option>
<option value={CheckStatusEnum.Bounced}>Karşılıksız</option>
<option value={CheckStatusEnum.Endorsed}>Ciro Edildi</option>
<option value={CheckStatusEnum.Cancelled}>İptal</option>
{Object.values(CheckStatusEnum).map((status) => (
<option key={status} value={status}>
{getCheckStatusText(status)}
</option>
))}
</select>
</div>
</div>
{/* Banka Bilgileri */}
<div className="bg-gray-50 p-3 rounded-lg">
<h3 className="text-base font-medium text-gray-900 mb-3">
Banka Bilgileri
</h3>
<h3 className="text-base font-medium text-gray-900 mb-3">Banka Bilgileri</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Banka Adı *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Banka Adı *</label>
<input
type="text"
value={formData.bankName}
onChange={(e) =>
handleInputChange("bankName", e.target.value)
}
onChange={(e) => handleInputChange('bankName', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.bankName ? "border-red-500" : "border-gray-300"
errors.bankName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Banka adını giriniz"
/>
{errors.bankName && (
<p className="text-red-500 text-xs mt-1">{errors.bankName}</p>
)}
{errors.bankName && <p className="text-red-500 text-xs mt-1">{errors.bankName}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Şube Adı
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Şube Adı</label>
<input
type="text"
value={formData.branchName}
onChange={(e) =>
handleInputChange("branchName", e.target.value)
}
onChange={(e) => handleInputChange('branchName', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Şube adını giriniz"
/>
@ -265,9 +231,7 @@ const CheckForm: React.FC<CheckFormProps> = ({
<input
type="text"
value={formData.accountNumber}
onChange={(e) =>
handleInputChange("accountNumber", e.target.value)
}
onChange={(e) => handleInputChange('accountNumber', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Hesap numarasını giriniz"
/>
@ -277,63 +241,45 @@ const CheckForm: React.FC<CheckFormProps> = ({
{/* Taraf Bilgileri */}
<div className="bg-gray-50 p-3 rounded-lg">
<h3 className="text-base font-medium text-gray-900 mb-3">
Taraf Bilgileri
</h3>
<h3 className="text-base font-medium text-gray-900 mb-3">Taraf Bilgileri</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Keşideci *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Keşideci *</label>
<input
type="text"
value={formData.drawerName}
onChange={(e) =>
handleInputChange("drawerName", e.target.value)
}
onChange={(e) => handleInputChange('drawerName', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.drawerName ? "border-red-500" : "border-gray-300"
errors.drawerName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Keşideci adını giriniz"
/>
{errors.drawerName && (
<p className="text-red-500 text-xs mt-1">
{errors.drawerName}
</p>
<p className="text-red-500 text-xs mt-1">{errors.drawerName}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Lehtar *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Lehtar *</label>
<input
type="text"
value={formData.payeeName}
onChange={(e) =>
handleInputChange("payeeName", e.target.value)
}
onChange={(e) => handleInputChange('payeeName', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.payeeName ? "border-red-500" : "border-gray-300"
errors.payeeName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Lehtar adını giriniz"
/>
{errors.payeeName && (
<p className="text-red-500 text-xs mt-1">
{errors.payeeName}
</p>
<p className="text-red-500 text-xs mt-1">{errors.payeeName}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Cari Hesap
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Cari Hesap</label>
<select
value={formData.currentAccountId}
onChange={(e) =>
handleInputChange("currentAccountId", e.target.value)
}
onChange={(e) => handleInputChange('currentAccountId', e.target.value)}
className="w-full 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="">Cari hesap seçiniz</option>
@ -350,39 +296,33 @@ const CheckForm: React.FC<CheckFormProps> = ({
{/* Tutar ve Tarih Bilgileri */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Tutar *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Tutar *</label>
<input
type="number"
step="0.01"
min="0"
value={formData.amount}
onChange={(e) =>
handleInputChange("amount", parseFloat(e.target.value) || 0)
}
onChange={(e) => handleInputChange('amount', parseFloat(e.target.value) || 0)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.amount ? "border-red-500" : "border-gray-300"
errors.amount ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="0.00"
/>
{errors.amount && (
<p className="text-red-500 text-xs mt-1">{errors.amount}</p>
)}
{errors.amount && <p className="text-red-500 text-xs mt-1">{errors.amount}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Para Birimi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Para Birimi</label>
<select
value={formData.currency}
onChange={(e) => handleInputChange("currency", e.target.value)}
onChange={(e) => handleInputChange('currency', e.target.value)}
className="w-full 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="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -393,37 +333,31 @@ const CheckForm: React.FC<CheckFormProps> = ({
<input
type="date"
value={formData.issueDate}
onChange={(e) => handleInputChange("issueDate", e.target.value)}
onChange={(e) => handleInputChange('issueDate', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Vade Tarihi *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Vade Tarihi *</label>
<input
type="date"
value={formData.dueDate}
onChange={(e) => handleInputChange("dueDate", e.target.value)}
onChange={(e) => handleInputChange('dueDate', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.dueDate ? "border-red-500" : "border-gray-300"
errors.dueDate ? 'border-red-500' : 'border-gray-300'
}`}
/>
{errors.dueDate && (
<p className="text-red-500 text-xs mt-1">{errors.dueDate}</p>
)}
{errors.dueDate && <p className="text-red-500 text-xs mt-1">{errors.dueDate}</p>}
</div>
</div>
{/* Notlar */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Notlar
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Notlar</label>
<textarea
value={formData.notes}
onChange={(e) => handleInputChange("notes", e.target.value)}
onChange={(e) => handleInputChange('notes', e.target.value)}
rows={3}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Ek notlar..."
@ -444,13 +378,13 @@ const CheckForm: React.FC<CheckFormProps> = ({
className="flex items-center gap-2 px-4 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
<FaSave className="w-4 h-4" />
{check ? "Güncelle" : "Kaydet"}
{check ? 'Güncelle' : 'Kaydet'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default CheckForm;
export default CheckForm

View file

@ -1,4 +1,4 @@
import React from "react";
import React from 'react'
import {
FaCreditCard,
FaFileAlt,
@ -7,113 +7,84 @@ import {
FaUser,
FaMoneyBillWave,
FaInfoCircle,
} from "react-icons/fa";
} from 'react-icons/fa'
import {
FiCheck,
PromissoryNote,
CheckStatusEnum,
NoteStatusEnum,
CheckTypeEnum,
NoteTypeEnum,
} from "../../../types/fi";
TypeEnum,
} from '../../../types/fi'
import {
getCheckStatusColor,
getCheckStatusText,
getNoteStatusColor,
getNoteStatusText,
} from '@/utils/erp'
interface CheckNoteDetailsProps {
item: FiCheck | PromissoryNote;
onClose: () => void;
isOpen: boolean;
item: FiCheck | PromissoryNote
onClose: () => void
isOpen: boolean
}
const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
item,
onClose,
isOpen,
}) => {
if (!isOpen) return null;
const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({ item, onClose, isOpen }) => {
if (!isOpen) return null
const isCheck = "checkNumber" in item;
const isCheck = 'checkNumber' in item
const formatCurrency = (amount: number) => {
return amount.toLocaleString("tr-TR", {
style: "currency",
currency: "TRY",
return amount.toLocaleString('tr-TR', {
style: 'currency',
currency: 'TRY',
minimumFractionDigits: 2,
});
};
})
}
const getStatusLabel = (status: CheckStatusEnum | NoteStatusEnum) => {
if (isCheck) {
const statusLabels = {
[CheckStatusEnum.InHand]: "Elde",
[CheckStatusEnum.Deposited]: "Bankaya Verildi",
[CheckStatusEnum.Collected]: "Tahsil Edildi",
[CheckStatusEnum.Bounced]: "Karşılıksız",
[CheckStatusEnum.Endorsed]: "Ciro Edildi",
[CheckStatusEnum.Cancelled]: "İptal",
};
return statusLabels[status as CheckStatusEnum];
return getCheckStatusText(status as CheckStatusEnum)
} else {
const statusLabels = {
[NoteStatusEnum.InHand]: "Elde",
[NoteStatusEnum.Collected]: "Tahsil Edildi",
[NoteStatusEnum.Overdue]: "Vadesi Geçmiş",
[NoteStatusEnum.Endorsed]: "Ciro Edildi",
[NoteStatusEnum.Cancelled]: "İptal",
};
return statusLabels[status as NoteStatusEnum];
return getNoteStatusText(status as NoteStatusEnum)
}
};
}
const getStatusColor = (status: CheckStatusEnum | NoteStatusEnum) => {
if (isCheck) {
const statusColors = {
[CheckStatusEnum.InHand]: "bg-blue-100 text-blue-800",
[CheckStatusEnum.Deposited]: "bg-yellow-100 text-yellow-800",
[CheckStatusEnum.Collected]: "bg-green-100 text-green-800",
[CheckStatusEnum.Bounced]: "bg-red-100 text-red-800",
[CheckStatusEnum.Endorsed]: "bg-purple-100 text-purple-800",
[CheckStatusEnum.Cancelled]: "bg-gray-100 text-gray-800",
};
return statusColors[status as CheckStatusEnum];
return getCheckStatusColor(status as CheckStatusEnum)
} else {
const statusColors = {
[NoteStatusEnum.InHand]: "bg-blue-100 text-blue-800",
[NoteStatusEnum.Collected]: "bg-green-100 text-green-800",
[NoteStatusEnum.Overdue]: "bg-red-100 text-red-800",
[NoteStatusEnum.Endorsed]: "bg-purple-100 text-purple-800",
[NoteStatusEnum.Cancelled]: "bg-gray-100 text-gray-800",
};
return statusColors[status as NoteStatusEnum];
return getNoteStatusColor(status as NoteStatusEnum)
}
};
}
const getTypeLabel = (type: CheckTypeEnum | NoteTypeEnum) => {
if (type === CheckTypeEnum.Received || type === NoteTypeEnum.Received) {
return "Alınan";
} else if (type === CheckTypeEnum.Issued || type === NoteTypeEnum.Issued) {
return "Verilen";
const getTypeLabel = (type: TypeEnum) => {
if (type === TypeEnum.Received) {
return 'Alınan'
} else if (type === TypeEnum.Issued) {
return 'Verilen'
}
return "Bilinmeyen";
};
return 'Bilinmeyen'
}
const getTypeColor = (type: CheckTypeEnum | NoteTypeEnum) => {
if (type === CheckTypeEnum.Received || type === NoteTypeEnum.Received) {
return "bg-green-100 text-green-800";
} else if (type === CheckTypeEnum.Issued || type === NoteTypeEnum.Issued) {
return "bg-orange-100 text-orange-800";
const getTypeColor = (type: TypeEnum) => {
if (type === TypeEnum.Received) {
return 'bg-green-100 text-green-800'
} else if (type === TypeEnum.Issued) {
return 'bg-orange-100 text-orange-800'
}
return "bg-gray-100 text-gray-800";
};
return 'bg-gray-100 text-gray-800'
}
const getDaysUntilDue = (dueDate: Date) => {
const today = new Date();
const due = new Date(dueDate);
const diffTime = due.getTime() - today.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
};
const today = new Date()
const due = new Date(dueDate)
const diffTime = due.getTime() - today.getTime()
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
return diffDays
}
const daysUntilDue = getDaysUntilDue(item.dueDate);
const isOverdue = daysUntilDue < 0;
const isDueSoon = daysUntilDue <= 7 && daysUntilDue >= 0;
const daysUntilDue = getDaysUntilDue(item.dueDate)
const isOverdue = daysUntilDue < 0
const isDueSoon = daysUntilDue <= 7 && daysUntilDue >= 0
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
@ -127,19 +98,14 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
)}
<div>
<h2 className="text-lg font-semibold text-gray-900">
{isCheck ? "Çek Detayları" : "Senet Detayları"}
{isCheck ? 'Çek Detayları' : 'Senet Detayları'}
</h2>
<p className="text-sm text-gray-600">
{isCheck
? (item as FiCheck).checkNumber
: (item as PromissoryNote).noteNumber}
{isCheck ? (item as FiCheck).checkNumber : (item as PromissoryNote).noteNumber}
</p>
</div>
</div>
<button
onClick={onClose}
className="p-2 hover:bg-gray-100 rounded-md"
>
<button onClick={onClose} className="p-2 hover:bg-gray-100 rounded-md">
<FaTimes className="w-5 h-5 text-gray-500" />
</button>
</div>
@ -149,15 +115,13 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
<div className="flex items-center gap-3">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getStatusColor(
item.status
item.status,
)}`}
>
{getStatusLabel(item.status)}
</span>
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getTypeColor(
item.type
)}`}
className={`px-2 py-1 text-xs font-medium rounded-full ${getTypeColor(item.type)}`}
>
{getTypeLabel(item.type)}
</span>
@ -183,13 +147,9 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
</h3>
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-gray-600">
{isCheck ? "Çek No:" : "Senet No:"}
</span>
<span className="text-gray-600">{isCheck ? 'Çek No:' : 'Senet No:'}</span>
<span className="font-medium">
{isCheck
? (item as FiCheck).checkNumber
: (item as PromissoryNote).noteNumber}
{isCheck ? (item as FiCheck).checkNumber : (item as PromissoryNote).noteNumber}
</span>
</div>
<div className="flex justify-between">
@ -205,9 +165,7 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
{!isCheck && (item as PromissoryNote).location && (
<div className="flex justify-between">
<span className="text-gray-600">Konum:</span>
<span className="font-medium">
{(item as PromissoryNote).location}
</span>
<span className="font-medium">{(item as PromissoryNote).location}</span>
</div>
)}
</div>
@ -223,35 +181,29 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
<div className="flex justify-between">
<span className="text-gray-600">Düzenleme Tarihi:</span>
<span className="font-medium">
{new Date(item.issueDate).toLocaleDateString("tr-TR")}
{new Date(item.issueDate).toLocaleDateString('tr-TR')}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Vade Tarihi:</span>
<span
className={`font-medium ${
isOverdue
? "text-red-600"
: isDueSoon
? "text-orange-600"
: "text-gray-900"
isOverdue ? 'text-red-600' : isDueSoon ? 'text-orange-600' : 'text-gray-900'
}`}
>
{new Date(item.dueDate).toLocaleDateString("tr-TR")}
{new Date(item.dueDate).toLocaleDateString('tr-TR')}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Oluşturma Tarihi:</span>
<span className="font-medium">
{new Date(item.creationTime).toLocaleDateString("tr-TR")}
{new Date(item.creationTime).toLocaleDateString('tr-TR')}
</span>
</div>
<div className="flex justify-between">
<span className="text-gray-600">Son Güncelleme:</span>
<span className="font-medium">
{new Date(item.lastModificationTime).toLocaleDateString(
"tr-TR"
)}
{new Date(item.lastModificationTime).toLocaleDateString('tr-TR')}
</span>
</div>
</div>
@ -267,24 +219,16 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 text-sm">
<div>
<span className="text-gray-600 block text-sm">
Banka Adı:
</span>
<span className="font-medium">
{(item as FiCheck).bankName}
</span>
<span className="text-gray-600 block text-sm">Banka Adı:</span>
<span className="font-medium">{(item as FiCheck).bankName}</span>
</div>
<div>
<span className="text-gray-600 block text-sm">Şube Adı:</span>
<span className="font-medium">
{(item as FiCheck).branchName}
</span>
<span className="font-medium">{(item as FiCheck).branchName}</span>
</div>
<div>
<span className="text-gray-600 block text-sm">Hesap No:</span>
<span className="font-medium">
{(item as FiCheck).accountNumber}
</span>
<span className="font-medium">{(item as FiCheck).accountNumber}</span>
</div>
</div>
</div>
@ -308,12 +252,9 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
</div>
{item.currentAccount && (
<div className="mt-3 p-2 bg-blue-50 rounded-lg text-sm">
<span className="text-gray-600 block text-sm">
Bağlı Cari Hesap:
</span>
<span className="text-gray-600 block text-sm">Bağlı Cari Hesap:</span>
<span className="font-medium text-blue-600">
{item.currentAccount.accountCode} -{" "}
{item.currentAccount.accountCode}
{item.currentAccount.accountCode} - {item.currentAccount.accountCode}
</span>
</div>
)}
@ -330,9 +271,7 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
<div className="flex justify-between items-center p-3 bg-yellow-50 rounded-lg">
<span className="text-gray-700">Bankaya Verilme Tarihi:</span>
<span className="font-medium">
{new Date((item as FiCheck).bankingDate!).toLocaleDateString(
"tr-TR"
)}
{new Date((item as FiCheck).bankingDate!).toLocaleDateString('tr-TR')}
</span>
</div>
)}
@ -340,35 +279,27 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
<div className="flex justify-between items-center p-3 bg-green-50 rounded-lg">
<span className="text-gray-700">Tahsil Tarihi:</span>
<span className="font-medium">
{new Date(item.collectionDate).toLocaleDateString("tr-TR")}
{new Date(item.collectionDate).toLocaleDateString('tr-TR')}
</span>
</div>
)}
{item.endorsedTo && (
<div className="flex justify-between items-center p-3 bg-purple-50 rounded-lg">
<span className="text-gray-700">
Ciro Edildiği Kişi/Kuruluş:
</span>
<span className="text-gray-700">Ciro Edildiği Kişi/Kuruluş:</span>
<span className="font-medium">{item.endorsedTo}</span>
</div>
)}
{(!isCheck || !(item as FiCheck).bankingDate) &&
!item.collectionDate &&
!item.endorsedTo && (
<p className="text-gray-500 italic">Henüz işlem yapılmamış</p>
)}
!item.endorsedTo && <p className="text-gray-500 italic">Henüz işlem yapılmamış</p>}
</div>
</div>
{/* Notlar */}
{item.notes && (
<div className="bg-gray-50 p-3 rounded-lg">
<h3 className="text-base font-medium text-gray-900 mb-2">
Notlar
</h3>
<p className="text-sm text-gray-700 whitespace-pre-wrap">
{item.notes}
</p>
<h3 className="text-base font-medium text-gray-900 mb-2">Notlar</h3>
<p className="text-sm text-gray-700 whitespace-pre-wrap">{item.notes}</p>
</div>
)}
</div>
@ -384,7 +315,7 @@ const CheckNoteDetails: React.FC<CheckNoteDetailsProps> = ({
</div>
</div>
</div>
);
};
)
}
export default CheckNoteDetails;
export default CheckNoteDetails

View file

@ -15,8 +15,7 @@ import {
PromissoryNote,
CheckStatusEnum,
NoteStatusEnum,
CheckTypeEnum,
NoteTypeEnum,
TypeEnum,
FiCurrentAccount,
} from '../../../types/fi'
import DataTable, { Column } from '../../../components/common/DataTable'
@ -71,7 +70,7 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
const [searchTerm, setSearchTerm] = useState('')
const [selectedCheckStatus, setSelectedCheckStatus] = useState<CheckStatusEnum | 'all'>('all')
const [selectedNoteStatus, setSelectedNoteStatus] = useState<NoteStatusEnum | 'all'>('all')
const [selectedType, setSelectedType] = useState<CheckTypeEnum | NoteTypeEnum | 'all'>('all')
const [selectedType, setSelectedType] = useState<TypeEnum | 'all'>('all')
const [sortBy, setSortBy] = useState<'dueDate' | 'amount' | 'issueDate'>('dueDate')
// Dialog states
@ -242,19 +241,19 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
}
})
const getTypeLabel = (type: CheckTypeEnum | NoteTypeEnum) => {
if (type === CheckTypeEnum.Received || type === NoteTypeEnum.Received) {
const getTypeLabel = (type: TypeEnum) => {
if (type === TypeEnum.Received) {
return 'Alınan'
} else if (type === CheckTypeEnum.Issued || type === NoteTypeEnum.Issued) {
} else if (type === TypeEnum.Issued) {
return 'Verilen'
}
return 'Bilinmeyen'
}
const getTypeColor = (type: CheckTypeEnum | NoteTypeEnum) => {
if (type === CheckTypeEnum.Received || type === NoteTypeEnum.Received) {
const getTypeColor = (type: TypeEnum) => {
if (type === TypeEnum.Received) {
return 'bg-green-100 text-green-800'
} else if (type === CheckTypeEnum.Issued || type === NoteTypeEnum.Issued) {
} else if (type === TypeEnum.Issued) {
return 'bg-orange-100 text-orange-800'
}
return 'bg-gray-100 text-gray-800'
@ -593,11 +592,11 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
const totalNoteAmount = promissoryNotes.reduce((sum, note) => sum + note.amount, 0)
const receivedCheckAmount = checks
.filter((c) => c.type === CheckTypeEnum.Received && c.status !== CheckStatusEnum.Collected)
.filter((c) => c.type === TypeEnum.Received && c.status !== CheckStatusEnum.Collected)
.reduce((sum, c) => sum + c.amount, 0)
const receivedNoteAmount = promissoryNotes
.filter((n) => n.type === NoteTypeEnum.Received && n.status !== NoteStatusEnum.Collected)
.filter((n) => n.type === TypeEnum.Received && n.status !== NoteStatusEnum.Collected)
.reduce((sum, n) => sum + n.amount, 0)
// Due items
@ -756,9 +755,7 @@ const CheckNoteManagement: React.FC<CheckNoteManagementProps> = ({
<select
value={selectedType}
onChange={(e) =>
setSelectedType(e.target.value as CheckTypeEnum | NoteTypeEnum | 'all')
}
onChange={(e) => setSelectedType(e.target.value as TypeEnum | '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"
>
<option value="all">Tüm Türler</option>

View file

@ -1,24 +1,15 @@
import React, { useState, useEffect } from "react";
import {
FaTimes,
FaUser,
FaBuilding,
FaCreditCard,
FaPhoneAlt,
} from "react-icons/fa";
import {
FiCurrentAccount,
AccountTypeEnum,
RiskGroupEnum,
} from "../../../types/fi";
import { mockBusinessParties } from "../../../mocks/mockBusinessParties";
import { getAccountTypeText, getRiskGroupText } from "../../../utils/erp";
import React, { useState, useEffect } from 'react'
import { FaTimes, FaUser, FaBuilding, FaCreditCard, FaPhoneAlt } from 'react-icons/fa'
import { FiCurrentAccount, AccountTypeEnum, RiskGroupEnum } from '../../../types/fi'
import { mockBusinessParties } from '../../../mocks/mockBusinessParties'
import { getAccountTypeText, getRiskGroupText } from '../../../utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface CurrentAccountFormProps {
account?: FiCurrentAccount;
isOpen: boolean;
onClose: () => void;
onSave: (account: Partial<FiCurrentAccount>) => void;
account?: FiCurrentAccount
isOpen: boolean
onClose: () => void
onSave: (account: Partial<FiCurrentAccount>) => void
}
const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
@ -29,26 +20,26 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
}) => {
const [formData, setFormData] = useState<
Partial<FiCurrentAccount> & {
id?: string;
id?: string
}
>({
accountCode: "",
businessPartyId: "",
accountCode: '',
businessPartyId: '',
type: AccountTypeEnum.Customer,
contactPerson: "",
phone: "",
email: "",
address: "",
taxNumber: "",
taxOffice: "",
contactPerson: '',
phone: '',
email: '',
address: '',
taxNumber: '',
taxOffice: '',
creditLimit: 0,
currency: "TRY",
currency: 'TRY',
riskGroup: RiskGroupEnum.Low,
paymentTerm: 30,
isActive: true,
});
})
const [errors, setErrors] = useState<Record<string, string>>({});
const [errors, setErrors] = useState<Record<string, string>>({})
useEffect(() => {
if (account) {
@ -56,100 +47,95 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
...account,
creditLimit: account.creditLimit || 0,
paymentTerm: account.paymentTerm || 30,
});
})
} else {
setFormData({
accountCode: "",
businessPartyId: "",
accountCode: '',
businessPartyId: '',
type: AccountTypeEnum.Customer,
contactPerson: "",
phone: "",
email: "",
address: "",
taxNumber: "",
taxOffice: "",
contactPerson: '',
phone: '',
email: '',
address: '',
taxNumber: '',
taxOffice: '',
creditLimit: 0,
currency: "TRY",
currency: 'TRY',
riskGroup: RiskGroupEnum.Low,
paymentTerm: 30,
isActive: true,
});
})
}
setErrors({});
}, [account, isOpen]);
setErrors({})
}, [account, isOpen])
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
) => {
const { name, value, type } = e.target;
let parsedValue: string | number | boolean = value;
const { name, value, type } = e.target
let parsedValue: string | number | boolean = value
if (type === "number") {
parsedValue = value === "" ? 0 : parseFloat(value);
} else if (type === "checkbox") {
parsedValue = (e.target as HTMLInputElement).checked;
if (type === 'number') {
parsedValue = value === '' ? 0 : parseFloat(value)
} else if (type === 'checkbox') {
parsedValue = (e.target as HTMLInputElement).checked
}
setFormData((prev) => ({
...prev,
[name]: parsedValue,
}));
}))
// Clear error when user starts typing
if (errors[name]) {
setErrors((prev) => ({
...prev,
[name]: "",
}));
[name]: '',
}))
}
};
}
const validateForm = () => {
const newErrors: Record<string, string> = {};
const newErrors: Record<string, string> = {}
if (!formData.accountCode?.trim()) {
newErrors.accountCode = "Hesap kodu zorunludur";
newErrors.accountCode = 'Hesap kodu zorunludur'
}
if (!formData.businessPartyId?.trim()) {
newErrors.businessPartyId = "Ünvan zorunludur";
newErrors.businessPartyId = 'Ünvan zorunludur'
}
if (formData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
newErrors.email = "Geçerli bir e-posta adresi giriniz";
newErrors.email = 'Geçerli bir e-posta adresi giriniz'
}
if (formData.creditLimit && formData.creditLimit < 0) {
newErrors.creditLimit = "Kredi limiti negatif olamaz";
newErrors.creditLimit = 'Kredi limiti negatif olamaz'
}
if (formData.paymentTerm && formData.paymentTerm < 0) {
newErrors.paymentTerm = "Ödeme vadesi negatif olamaz";
newErrors.paymentTerm = 'Ödeme vadesi negatif olamaz'
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (validateForm()) {
onSave(formData);
onClose();
onSave(formData)
onClose()
}
};
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg w-full max-w-3xl max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between p-4 border-b">
<h2 className="text-lg font-semibold text-gray-900">
{account ? "Cari Hesap Düzenle" : "Yeni Cari Hesap"}
{account ? 'Cari Hesap Düzenle' : 'Yeni Cari Hesap'}
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600"
>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
<FaTimes className="w-5 h-5" />
</button>
</div>
@ -164,34 +150,28 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Hesap Kodu *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Hesap Kodu *</label>
<input
type="text"
name="accountCode"
value={formData.accountCode || ""}
value={formData.accountCode || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.accountCode ? "border-red-500" : "border-gray-300"
errors.accountCode ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="CA001"
/>
{errors.accountCode && (
<p className="text-red-500 text-xs mt-1">
{errors.accountCode}
</p>
<p className="text-red-500 text-xs mt-1">{errors.accountCode}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Ünvan *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Ünvan *</label>
<select
name="businessPartyId"
value={formData.businessPartyId || ""}
value={formData.businessPartyId || ''}
onChange={handleInputChange}
className="mt-1 block w-full border border-gray-300 rounded-md px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500"
required
@ -203,15 +183,11 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
</option>
))}
</select>
{errors.title && (
<p className="text-red-500 text-xs mt-1">{errors.title}</p>
)}
{errors.title && <p className="text-red-500 text-xs mt-1">{errors.title}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Hesap Türü
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Hesap Türü</label>
<select
name="type"
value={formData.type}
@ -227,13 +203,11 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Yetkili Kişi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Yetkili Kişi</label>
<input
type="text"
name="contactPerson"
value={formData.contactPerson || ""}
value={formData.contactPerson || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Yetkili kişi adı"
@ -249,13 +223,11 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Telefon
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Telefon</label>
<input
type="text"
name="phone"
value={formData.phone || ""}
value={formData.phone || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="+90 212 555 1234"
@ -263,31 +235,25 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
E-posta
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">E-posta</label>
<input
type="email"
name="email"
value={formData.email || ""}
value={formData.email || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.email ? "border-red-500" : "border-gray-300"
errors.email ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="info@company.com"
/>
{errors.email && (
<p className="text-red-500 text-xs mt-1">{errors.email}</p>
)}
{errors.email && <p className="text-red-500 text-xs mt-1">{errors.email}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Adres
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Adres</label>
<textarea
name="address"
value={formData.address || ""}
value={formData.address || ''}
onChange={handleInputChange}
rows={3}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
@ -303,7 +269,7 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
<input
type="text"
name="taxNumber"
value={formData.taxNumber || ""}
value={formData.taxNumber || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="1234567890"
@ -317,7 +283,7 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
<input
type="text"
name="taxOffice"
value={formData.taxOffice || ""}
value={formData.taxOffice || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Beylikdüzü V.D."
@ -346,14 +312,12 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
min="0"
step="0.01"
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.creditLimit ? "border-red-500" : "border-gray-300"
errors.creditLimit ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="0.00"
/>
{errors.creditLimit && (
<p className="text-red-500 text-xs mt-1">
{errors.creditLimit}
</p>
<p className="text-red-500 text-xs mt-1">{errors.creditLimit}</p>
)}
</div>
@ -367,19 +331,18 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
onChange={handleInputChange}
className="w-full 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="TRY">TRY - Türk Lirası</option>
<option value="USD">USD - Amerikan Doları</option>
<option value="EUR">EUR - Euro</option>
<option value="GBP">GBP - İngiliz Sterlini</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Risk Grubu
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Risk Grubu</label>
<select
name="riskGroup"
value={formData.riskGroup}
@ -405,14 +368,12 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
onChange={handleInputChange}
min="0"
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.paymentTerm ? "border-red-500" : "border-gray-300"
errors.paymentTerm ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="30"
/>
{errors.paymentTerm && (
<p className="text-red-500 text-xs mt-1">
{errors.paymentTerm}
</p>
<p className="text-red-500 text-xs mt-1">{errors.paymentTerm}</p>
)}
</div>
</div>
@ -433,9 +394,7 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
onChange={handleInputChange}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label className="ml-2 block text-sm text-gray-700">
Aktif hesap
</label>
<label className="ml-2 block text-sm text-gray-700">Aktif hesap</label>
</div>
</div>
</div>
@ -453,13 +412,13 @@ const CurrentAccountForm: React.FC<CurrentAccountFormProps> = ({
type="submit"
className="px-4 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
{account ? "Güncelle" : "Ekle"}
{account ? 'Güncelle' : 'Ekle'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default CurrentAccountForm;
export default CurrentAccountForm

View file

@ -1,18 +1,15 @@
import React, { useState, useEffect } from "react";
import { FaTimes, FaFileInvoice, FaMoneyBill } from "react-icons/fa";
import {
FiCurrentAccountMovement,
FiDocumentTypeEnum,
FiCurrentAccount,
} from "../../../types/fi";
import { getFiDocumentTypeText } from "../../../utils/erp";
import React, { useState, useEffect } from 'react'
import { FaTimes, FaFileInvoice, FaMoneyBill } from 'react-icons/fa'
import { FiCurrentAccountMovement, FiDocumentTypeEnum, FiCurrentAccount } from '../../../types/fi'
import { getFiDocumentTypeText } from '../../../utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface CurrentAccountMovementFormProps {
movement?: FiCurrentAccountMovement;
accounts: FiCurrentAccount[];
isOpen: boolean;
onClose: () => void;
onSave: (movement: Partial<FiCurrentAccountMovement>) => void;
movement?: FiCurrentAccountMovement
accounts: FiCurrentAccount[]
isOpen: boolean
onClose: () => void
onSave: (movement: Partial<FiCurrentAccountMovement>) => void
}
const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
@ -24,22 +21,22 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
}) => {
const [formData, setFormData] = useState<
Partial<FiCurrentAccountMovement> & {
id?: string;
id?: string
}
>({
accountId: "",
accountId: '',
transactionDate: new Date(),
description: "",
referenceNumber: "",
description: '',
referenceNumber: '',
documentType: FiDocumentTypeEnum.Invoice,
documentNumber: "",
documentNumber: '',
debitAmount: 0,
creditAmount: 0,
balance: 0,
currency: "TRY",
});
currency: 'TRY',
})
const [errors, setErrors] = useState<Record<string, string>>({});
const [errors, setErrors] = useState<Record<string, string>>({})
useEffect(() => {
if (movement) {
@ -48,111 +45,100 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
debitAmount: movement.debitAmount || 0,
creditAmount: movement.creditAmount || 0,
balance: movement.balance || 0,
});
})
} else {
setFormData({
accountId: "",
accountId: '',
transactionDate: new Date(),
description: "",
referenceNumber: "",
description: '',
referenceNumber: '',
documentType: FiDocumentTypeEnum.Invoice,
documentNumber: "",
documentNumber: '',
debitAmount: 0,
creditAmount: 0,
balance: 0,
currency: "TRY",
});
currency: 'TRY',
})
}
setErrors({});
}, [movement, isOpen]);
setErrors({})
}, [movement, isOpen])
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
) => {
const { name, value, type } = e.target;
let parsedValue: string | number | Date = value;
const { name, value, type } = e.target
let parsedValue: string | number | Date = value
if (type === "number") {
parsedValue = value === "" ? 0 : parseFloat(value);
} else if (type === "date") {
parsedValue = new Date(value);
if (type === 'number') {
parsedValue = value === '' ? 0 : parseFloat(value)
} else if (type === 'date') {
parsedValue = new Date(value)
}
setFormData((prev) => ({
...prev,
[name]: parsedValue,
}));
}))
// Clear error when user starts typing
if (errors[name]) {
setErrors((prev) => ({
...prev,
[name]: "",
}));
[name]: '',
}))
}
};
}
const validateForm = () => {
const newErrors: Record<string, string> = {};
const newErrors: Record<string, string> = {}
if (!formData.accountId) {
newErrors.accountId = "Cari hesap seçimi zorunludur";
newErrors.accountId = 'Cari hesap seçimi zorunludur'
}
if (!formData.description?.trim()) {
newErrors.description = "Açıklama zorunludur";
newErrors.description = 'Açıklama zorunludur'
}
if (!formData.transactionDate) {
newErrors.transactionDate = "İşlem tarihi zorunludur";
newErrors.transactionDate = 'İşlem tarihi zorunludur'
}
if (
(formData.debitAmount || 0) === 0 &&
(formData.creditAmount || 0) === 0
) {
newErrors.amount = "Borç veya alacak tutarından biri girilmelidir";
if ((formData.debitAmount || 0) === 0 && (formData.creditAmount || 0) === 0) {
newErrors.amount = 'Borç veya alacak tutarından biri girilmelidir'
}
if ((formData.debitAmount || 0) > 0 && (formData.creditAmount || 0) > 0) {
newErrors.amount = "Borç ve alacak tutarı aynı anda girilemez";
newErrors.amount = 'Borç ve alacak tutarı aynı anda girilemez'
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (validateForm()) {
// Calculate balance based on debit/credit amounts
const balance =
(formData.debitAmount || 0) - (formData.creditAmount || 0);
const balance = (formData.debitAmount || 0) - (formData.creditAmount || 0)
const movementData = {
...formData,
balance,
creationTime: movement?.creationTime || new Date(),
};
}
onSave(movementData);
onClose();
onSave(movementData)
onClose()
}
};
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg w-full max-w-2xl max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between p-4 border-b">
<h2 className="text-lg font-semibold text-gray-900">
{movement
? "Cari Hesap Hareketi Düzenle"
: "Yeni Cari Hesap Hareketi"}
{movement ? 'Cari Hesap Hareketi Düzenle' : 'Yeni Cari Hesap Hareketi'}
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600"
>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
<FaTimes className="w-5 h-5" />
</button>
</div>
@ -167,15 +153,13 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Cari Hesap *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Cari Hesap *</label>
<select
name="accountId"
value={formData.accountId || ""}
value={formData.accountId || ''}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.accountId ? "border-red-500" : "border-gray-300"
errors.accountId ? 'border-red-500' : 'border-gray-300'
}`}
>
<option value="">Cari hesap seçiniz</option>
@ -186,9 +170,7 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
))}
</select>
{errors.accountId && (
<p className="text-red-500 text-xs mt-1">
{errors.accountId}
</p>
<p className="text-red-500 text-xs mt-1">{errors.accountId}</p>
)}
</div>
@ -201,29 +183,21 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
name="transactionDate"
value={
formData.transactionDate
? new Date(formData.transactionDate)
.toISOString()
.split("T")[0]
: ""
? new Date(formData.transactionDate).toISOString().split('T')[0]
: ''
}
onChange={handleInputChange}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.transactionDate
? "border-red-500"
: "border-gray-300"
errors.transactionDate ? 'border-red-500' : 'border-gray-300'
}`}
/>
{errors.transactionDate && (
<p className="text-red-500 text-xs mt-1">
{errors.transactionDate}
</p>
<p className="text-red-500 text-xs mt-1">{errors.transactionDate}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Belge Türü
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Belge Türü</label>
<select
name="documentType"
value={formData.documentType}
@ -246,7 +220,7 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
<input
type="text"
name="referenceNumber"
value={formData.referenceNumber || ""}
value={formData.referenceNumber || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="REF001"
@ -254,13 +228,11 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Belge No
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Belge No</label>
<input
type="text"
name="documentNumber"
value={formData.documentNumber || ""}
value={formData.documentNumber || ''}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="DOC001"
@ -277,9 +249,7 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Borç Tutarı
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Borç Tutarı</label>
<input
type="number"
name="debitAmount"
@ -309,19 +279,18 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Para Birimi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Para Birimi</label>
<select
name="currency"
value={formData.currency}
onChange={handleInputChange}
className="w-full 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="TRY">TRY - Türk Lirası</option>
<option value="USD">USD - Amerikan Doları</option>
<option value="EUR">EUR - Euro</option>
<option value="GBP">GBP - İngiliz Sterlini</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -333,37 +302,34 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
<div className="p-2 bg-blue-50 border border-blue-200 rounded-md">
<p className="text-blue-800 text-sm">
<strong>Hesaplanan Bakiye:</strong>{" "}
{(
(formData.debitAmount || 0) - (formData.creditAmount || 0)
).toLocaleString("tr-TR", {
style: "currency",
currency: formData.currency || "TRY",
minimumFractionDigits: 2,
})}
<strong>Hesaplanan Bakiye:</strong>{' '}
{((formData.debitAmount || 0) - (formData.creditAmount || 0)).toLocaleString(
'tr-TR',
{
style: 'currency',
currency: formData.currency || 'TRY',
minimumFractionDigits: 2,
},
)}
</p>
</div>
</div>
{/* Açıklama */}
<div className="md:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1">
ıklama *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">ıklama *</label>
<textarea
name="description"
value={formData.description || ""}
value={formData.description || ''}
onChange={handleInputChange}
rows={3}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.description ? "border-red-500" : "border-gray-300"
errors.description ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Hareket açıklaması"
/>
{errors.description && (
<p className="text-red-500 text-xs mt-1">
{errors.description}
</p>
<p className="text-red-500 text-xs mt-1">{errors.description}</p>
)}
</div>
</div>
@ -381,13 +347,13 @@ const CurrentAccountMovementForm: React.FC<CurrentAccountMovementFormProps> = ({
type="submit"
className="px-4 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
{movement ? "Güncelle" : "Ekle"}
{movement ? 'Güncelle' : 'Ekle'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default CurrentAccountMovementForm;
export default CurrentAccountMovementForm

View file

@ -1,31 +1,27 @@
import React, { useState, useEffect } from "react";
import { FaSave, FaTimes, FaPlus, FaTrash, FaFileAlt } from "react-icons/fa";
import React, { useState, useEffect } from 'react'
import { FaSave, FaTimes, FaPlus, FaTrash, FaFileAlt } from 'react-icons/fa'
import {
FiInvoice,
FiInvoiceItem,
InvoiceTypeEnum,
InvoiceStatusEnum,
PaymentStatusEnum,
} from "../../../types/fi";
import { mockCurrentAccounts } from "../../../mocks/mockCurrentAccounts";
} from '../../../types/fi'
import { mockCurrentAccounts } from '../../../mocks/mockCurrentAccounts'
import { getInvoiceTypeText } from '@/utils/erp'
interface InvoiceFormProps {
invoice?: FiInvoice;
onSave: (invoice: Partial<FiInvoice>) => void;
onCancel: () => void;
isVisible: boolean;
invoice?: FiInvoice
onSave: (invoice: Partial<FiInvoice>) => void
onCancel: () => void
isVisible: boolean
}
const InvoiceForm: React.FC<InvoiceFormProps> = ({
invoice,
onSave,
onCancel,
isVisible,
}) => {
const InvoiceForm: React.FC<InvoiceFormProps> = ({ invoice, onSave, onCancel, isVisible }) => {
const [formData, setFormData] = useState<Partial<FiInvoice>>({
invoiceNumber: "",
invoiceNumber: '',
invoiceType: InvoiceTypeEnum.Sales,
currentAccountId: "",
currentAccountId: '',
invoiceDate: new Date(),
dueDate: new Date(),
deliveryDate: new Date(),
@ -35,22 +31,22 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
totalAmount: 0,
paidAmount: 0,
remainingAmount: 0,
currency: "TRY",
currency: 'TRY',
status: InvoiceStatusEnum.Draft,
paymentStatus: PaymentStatusEnum.Unpaid,
items: [],
waybillNumber: "",
notes: "",
});
waybillNumber: '',
notes: '',
})
const [newItem, setNewItem] = useState<Partial<FiInvoiceItem>>({
description: "",
description: '',
quantity: 1,
unitPrice: 0,
taxRate: 18,
discountRate: 0,
unit: "Adet",
});
unit: 'Adet',
})
useEffect(() => {
if (invoice) {
@ -58,18 +54,17 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
...invoice,
invoiceDate: new Date(invoice.invoiceDate),
dueDate: new Date(invoice.dueDate),
deliveryDate: invoice.deliveryDate
? new Date(invoice.deliveryDate)
: new Date(),
});
deliveryDate: invoice.deliveryDate ? new Date(invoice.deliveryDate) : new Date(),
})
} else {
// Generate new invoice number
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const invoiceNumber = `FT${year}${month}${String(
Math.floor(Math.random() * 10000)
).padStart(4, "0")}`;
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const invoiceNumber = `FT${year}${month}${String(Math.floor(Math.random() * 10000)).padStart(
4,
'0',
)}`
setFormData((prev) => ({
...prev,
@ -77,58 +72,50 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
invoiceDate: now,
dueDate: new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000), // 30 days
deliveryDate: now,
}));
}))
}
}, [invoice]);
}, [invoice])
const calculateItemTotal = (item: Partial<FiInvoiceItem>) => {
const subtotal = (item.quantity || 0) * (item.unitPrice || 0);
const discountAmount = subtotal * ((item.discountRate || 0) / 100);
const taxableAmount = subtotal - discountAmount;
const taxAmount = taxableAmount * ((item.taxRate || 0) / 100);
return taxableAmount + taxAmount;
};
const subtotal = (item.quantity || 0) * (item.unitPrice || 0)
const discountAmount = subtotal * ((item.discountRate || 0) / 100)
const taxableAmount = subtotal - discountAmount
const taxAmount = taxableAmount * ((item.taxRate || 0) / 100)
return taxableAmount + taxAmount
}
const calculateInvoiceTotals = (items: FiInvoiceItem[]) => {
const subtotal = items.reduce(
(sum, item) => sum + item.quantity * item.unitPrice,
0
);
const discountAmount = items.reduce(
(sum, item) => sum + item.discountAmount,
0
);
const taxAmount = items.reduce((sum, item) => sum + item.taxAmount, 0);
const totalAmount = items.reduce((sum, item) => sum + item.lineTotal, 0);
const subtotal = items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0)
const discountAmount = items.reduce((sum, item) => sum + item.discountAmount, 0)
const taxAmount = items.reduce((sum, item) => sum + item.taxAmount, 0)
const totalAmount = items.reduce((sum, item) => sum + item.lineTotal, 0)
return {
subtotal,
discountAmount,
taxAmount,
totalAmount,
};
};
}
}
const handleAddItem = () => {
if (!newItem.description || !newItem.quantity || !newItem.unitPrice) {
alert("Lütfen ürün bilgilerini doldurun");
return;
alert('Lütfen ürün bilgilerini doldurun')
return
}
const item: FiInvoiceItem = {
id: Date.now().toString(),
invoiceId: formData.id || "",
invoiceId: formData.id || '',
description: newItem.description!,
quantity: newItem.quantity!,
unitPrice: newItem.unitPrice!,
unit: newItem.unit || "Adet",
unit: newItem.unit || 'Adet',
taxRate: newItem.taxRate || 18,
discountRate: newItem.discountRate || 0,
lineTotal: calculateItemTotal(newItem),
discountAmount:
(newItem.quantity || 0) *
(newItem.unitPrice || 0) *
((newItem.discountRate || 0) / 100),
(newItem.quantity || 0) * (newItem.unitPrice || 0) * ((newItem.discountRate || 0) / 100),
taxAmount:
((newItem.quantity || 0) * (newItem.unitPrice || 0) -
(newItem.quantity || 0) *
@ -136,50 +123,49 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
((newItem.discountRate || 0) / 100)) *
((newItem.taxRate || 0) / 100),
netAmount: calculateItemTotal(newItem),
};
}
const updatedItems = [...(formData.items || []), item];
const totals = calculateInvoiceTotals(updatedItems);
const updatedItems = [...(formData.items || []), item]
const totals = calculateInvoiceTotals(updatedItems)
setFormData((prev) => ({
...prev,
items: updatedItems,
...totals,
remainingAmount: totals.totalAmount - (prev.paidAmount || 0),
}));
}))
setNewItem({
description: "",
description: '',
quantity: 1,
unitPrice: 0,
taxRate: 18,
discountRate: 0,
unit: "Adet",
});
};
unit: 'Adet',
})
}
const handleRemoveItem = (itemId: string) => {
const updatedItems =
formData.items?.filter((item) => item.id !== itemId) || [];
const totals = calculateInvoiceTotals(updatedItems);
const updatedItems = formData.items?.filter((item) => item.id !== itemId) || []
const totals = calculateInvoiceTotals(updatedItems)
setFormData((prev) => ({
...prev,
items: updatedItems,
...totals,
remainingAmount: totals.totalAmount - (prev.paidAmount || 0),
}));
};
}))
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (!formData.currentAccountId) {
alert("Lütfen cari hesap seçin");
return;
alert('Lütfen cari hesap seçin')
return
}
if (!formData.items?.length) {
alert("Lütfen en az bir ürün ekleyin");
return;
alert('Lütfen en az bir ürün ekleyin')
return
}
onSave({
@ -187,18 +173,18 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
id: invoice?.id || Date.now().toString(),
creationTime: invoice?.creationTime || new Date(),
lastModificationTime: new Date(),
});
};
})
}
const formatCurrency = (amount: number) => {
return amount.toLocaleString("tr-TR", {
style: "currency",
currency: "TRY",
return amount.toLocaleString('tr-TR', {
style: 'currency',
currency: 'TRY',
minimumFractionDigits: 2,
});
};
})
}
if (!isVisible) return null;
if (!isVisible) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
@ -208,7 +194,7 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
<div className="flex items-center gap-2.5">
<FaFileAlt className="w-5 h-5 text-blue-600" />
<h2 className="text-lg font-semibold text-gray-900">
{invoice ? "Fatura Düzenle" : "Yeni Fatura"}
{invoice ? 'Fatura Düzenle' : 'Yeni Fatura'}
</h2>
</div>
<button
@ -224,24 +210,18 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
{/* Basic Information */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Fatura No
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Fatura No</label>
<input
type="text"
value={formData.invoiceNumber}
onChange={(e) =>
setFormData({ ...formData, invoiceNumber: e.target.value })
}
onChange={(e) => setFormData({ ...formData, invoiceNumber: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Fatura Türü
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Fatura Türü</label>
<select
value={formData.invoiceType}
onChange={(e) =>
@ -252,36 +232,29 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
}
className="w-full 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={InvoiceTypeEnum.Sales}>Satış</option>
<option value={InvoiceTypeEnum.Purchase}>Alış</option>
<option value={InvoiceTypeEnum.Return}>İade</option>
<option value={InvoiceTypeEnum.Proforma}>Proforma</option>
{Object.values(InvoiceTypeEnum).map((type) => (
<option key={type} value={type}>
{getInvoiceTypeText(type)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
İrsaliye No
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">İrsaliye No</label>
<input
type="text"
value={formData.waybillNumber || ""}
onChange={(e) =>
setFormData({ ...formData, waybillNumber: e.target.value })
}
value={formData.waybillNumber || ''}
onChange={(e) => setFormData({ ...formData, waybillNumber: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Cari Hesap
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Cari Hesap</label>
<select
value={formData.currentAccountId}
onChange={(e) =>
setFormData({ ...formData, currentAccountId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, currentAccountId: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
>
@ -295,12 +268,10 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Fatura Tarihi
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Fatura Tarihi</label>
<input
type="date"
value={formData.invoiceDate?.toISOString().split("T")[0]}
value={formData.invoiceDate?.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -313,12 +284,10 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Vade Tarihi
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Vade Tarihi</label>
<input
type="date"
value={formData.dueDate?.toISOString().split("T")[0]}
value={formData.dueDate?.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -333,9 +302,7 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
{/* Invoice Items */}
<div className="mb-6">
<h3 className="text-base font-semibold text-gray-900 mb-3">
Fatura Kalemleri
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">Fatura Kalemleri</h3>
{/* Add New Item */}
<div className="bg-gray-50 p-3 rounded-lg mb-3">
@ -346,21 +313,17 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
</label>
<input
type="text"
value={newItem.description || ""}
onChange={(e) =>
setNewItem({ ...newItem, description: e.target.value })
}
value={newItem.description || ''}
onChange={(e) => setNewItem({ ...newItem, description: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Ürün/Hizmet açıklaması"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Miktar
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Miktar</label>
<input
type="number"
value={newItem.quantity || ""}
value={newItem.quantity || ''}
onChange={(e) =>
setNewItem({
...newItem,
@ -378,7 +341,7 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
</label>
<input
type="number"
value={newItem.unitPrice || ""}
value={newItem.unitPrice || ''}
onChange={(e) =>
setNewItem({
...newItem,
@ -391,11 +354,9 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
KDV (%)
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">KDV (%)</label>
<select
value={newItem.taxRate || 18}
value={newItem.taxRate || 20}
onChange={(e) =>
setNewItem({
...newItem,
@ -408,6 +369,7 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
<option value={1}>1%</option>
<option value={8}>8%</option>
<option value={18}>18%</option>
<option value={20}>20%</option>
</select>
</div>
<div className="flex items-end">
@ -452,18 +414,14 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
<tbody className="divide-y divide-gray-200">
{formData.items.map((item) => (
<tr key={item.id} className="text-sm">
<td className="px-3 py-2 text-gray-900">
{item.description}
</td>
<td className="px-3 py-2 text-gray-900">{item.description}</td>
<td className="px-3 py-2 text-gray-900 text-right">
{item.quantity.toLocaleString("tr-TR")}
{item.quantity.toLocaleString('tr-TR')}
</td>
<td className="px-3 py-2 text-gray-900 text-right">
{formatCurrency(item.unitPrice)}
</td>
<td className="px-3 py-2 text-gray-900 text-right">
%{item.taxRate}
</td>
<td className="px-3 py-2 text-gray-900 text-right">%{item.taxRate}</td>
<td className="px-3 py-2 text-gray-900 text-right font-medium">
{formatCurrency(item.lineTotal)}
</td>
@ -488,14 +446,10 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
<div className="bg-gray-50 p-4 rounded-lg mb-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Notlar
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Notlar</label>
<textarea
value={formData.notes || ""}
onChange={(e) =>
setFormData({ ...formData, notes: e.target.value })
}
value={formData.notes || ''}
onChange={(e) => setFormData({ ...formData, notes: e.target.value })}
rows={4}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Fatura ile ilgili notlar..."
@ -504,9 +458,7 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
<div className="space-y-2 text-sm">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">Ara Toplam:</span>
<span className="font-medium">
{formatCurrency(formData.subtotal || 0)}
</span>
<span className="font-medium">{formatCurrency(formData.subtotal || 0)}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">İndirim:</span>
@ -516,15 +468,11 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">KDV:</span>
<span className="font-medium">
{formatCurrency(formData.taxAmount || 0)}
</span>
<span className="font-medium">{formatCurrency(formData.taxAmount || 0)}</span>
</div>
<div className="border-t pt-3">
<div className="flex justify-between items-center">
<span className="text-base font-semibold text-gray-900">
Genel Toplam:
</span>
<span className="text-base font-semibold text-gray-900">Genel Toplam:</span>
<span className="text-base font-bold text-blue-600">
{formatCurrency(formData.totalAmount || 0)}
</span>
@ -548,13 +496,13 @@ const InvoiceForm: React.FC<InvoiceFormProps> = ({
className="px-4 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-2"
>
<FaSave className="w-4 h-4" />
{invoice ? "Güncelle" : "Kaydet"}
{invoice ? 'Güncelle' : 'Kaydet'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default InvoiceForm;
export default InvoiceForm

View file

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState } from 'react'
import {
FaPlus,
FaSearch,
@ -8,15 +8,10 @@ import {
FaFileAlt,
FaEdit,
FaSave,
} from "react-icons/fa";
import {
FiInvoice,
InvoiceTypeEnum,
InvoiceStatusEnum,
PaymentStatusEnum,
} from "../../../types/fi";
import DataTable, { Column } from "../../../components/common/DataTable";
import Widget from "../../../components/common/Widget";
} from 'react-icons/fa'
import { FiInvoice, InvoiceTypeEnum, InvoiceStatusEnum, PaymentStatusEnum } from '../../../types/fi'
import DataTable, { Column } from '../../../components/common/DataTable'
import Widget from '../../../components/common/Widget'
import {
getInvoiceTypeColor,
getInvoiceTypeText,
@ -24,15 +19,15 @@ import {
getInvoiceStatusText,
getPaymentStatusColor,
getPaymentStatusText,
} from "../../../utils/erp";
} from '../../../utils/erp'
interface InvoiceManagementProps {
invoices: FiInvoice[];
onAdd: () => void;
onEdit: (invoice: FiInvoice) => void;
onConvertFromWaybill: () => void;
onCreatePayment: (invoice: FiInvoice) => void;
onViewDetails: (invoice: FiInvoice) => void;
invoices: FiInvoice[]
onAdd: () => void
onEdit: (invoice: FiInvoice) => void
onConvertFromWaybill: () => void
onCreatePayment: (invoice: FiInvoice) => void
onViewDetails: (invoice: FiInvoice) => void
}
const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
@ -43,103 +38,85 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
onCreatePayment,
onViewDetails,
}) => {
const [searchTerm, setSearchTerm] = useState("");
const [selectedType, setSelectedType] = useState<InvoiceTypeEnum | "all">(
"all"
);
const [selectedStatus, setSelectedStatus] = useState<
InvoiceStatusEnum | "all"
>("all");
const [selectedPaymentStatus, setSelectedPaymentStatus] = useState<
PaymentStatusEnum | "all"
>("all");
const [sortBy, setSortBy] = useState<"date" | "amount" | "dueDate">("date");
const [searchTerm, setSearchTerm] = useState('')
const [selectedType, setSelectedType] = useState<InvoiceTypeEnum | 'all'>('all')
const [selectedStatus, setSelectedStatus] = useState<InvoiceStatusEnum | 'all'>('all')
const [selectedPaymentStatus, setSelectedPaymentStatus] = useState<PaymentStatusEnum | 'all'>(
'all',
)
const [sortBy, setSortBy] = useState<'date' | 'amount' | 'dueDate'>('date')
const filteredInvoices = invoices
.filter((invoice) => {
if (
searchTerm &&
!invoice.invoiceNumber
.toLowerCase()
.includes(searchTerm.toLowerCase()) &&
!invoice.currentAccount?.accountCode
?.toLowerCase()
.includes(searchTerm.toLowerCase()) &&
!invoice.invoiceNumber.toLowerCase().includes(searchTerm.toLowerCase()) &&
!invoice.currentAccount?.accountCode?.toLowerCase().includes(searchTerm.toLowerCase()) &&
!invoice.waybillNumber?.toLowerCase().includes(searchTerm.toLowerCase())
) {
return false;
return false
}
if (selectedType !== "all" && invoice.invoiceType !== selectedType) {
return false;
if (selectedType !== 'all' && invoice.invoiceType !== selectedType) {
return false
}
if (selectedStatus !== "all" && invoice.status !== selectedStatus) {
return false;
if (selectedStatus !== 'all' && invoice.status !== selectedStatus) {
return false
}
if (
selectedPaymentStatus !== "all" &&
invoice.paymentStatus !== selectedPaymentStatus
) {
return false;
if (selectedPaymentStatus !== 'all' && invoice.paymentStatus !== selectedPaymentStatus) {
return false
}
return true;
return true
})
.sort((a, b) => {
switch (sortBy) {
case "date":
return (
new Date(b.invoiceDate).getTime() -
new Date(a.invoiceDate).getTime()
);
case "amount":
return b.totalAmount - a.totalAmount;
case "dueDate":
return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime();
case 'date':
return new Date(b.invoiceDate).getTime() - new Date(a.invoiceDate).getTime()
case 'amount':
return b.totalAmount - a.totalAmount
case 'dueDate':
return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime()
default:
return 0;
return 0
}
});
})
const getDaysUntilDue = (dueDate: Date) => {
const today = new Date();
const due = new Date(dueDate);
const diffTime = due.getTime() - today.getTime();
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
};
const today = new Date()
const due = new Date(dueDate)
const diffTime = due.getTime() - today.getTime()
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
return diffDays
}
const formatCurrency = (amount: number) => {
return amount.toLocaleString("tr-TR", {
style: "currency",
currency: "TRY",
return amount.toLocaleString('tr-TR', {
style: 'currency',
currency: 'TRY',
minimumFractionDigits: 2,
});
};
})
}
const columns: Column<FiInvoice>[] = [
{
key: "invoiceNumber",
header: "Fatura No",
key: 'invoiceNumber',
header: 'Fatura No',
sortable: true,
render: (invoice: FiInvoice) => (
<div>
<div className="font-medium text-gray-900">
{invoice.invoiceNumber}
</div>
<div className="font-medium text-gray-900">{invoice.invoiceNumber}</div>
{invoice.waybillNumber && (
<div className="text-sm text-gray-500">
İrs: {invoice.waybillNumber}
</div>
<div className="text-sm text-gray-500">İrs: {invoice.waybillNumber}</div>
)}
</div>
),
},
{
key: "type",
header: "Tür",
key: 'type',
header: 'Tür',
render: (invoice: FiInvoice) => (
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getInvoiceTypeColor(
invoice.invoiceType
invoice.invoiceType,
)}`}
>
{getInvoiceTypeText(invoice.invoiceType)}
@ -147,61 +124,54 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
),
},
{
key: "currentAccount",
header: "Cari Hesap",
key: 'currentAccount',
header: 'Cari Hesap',
render: (invoice: FiInvoice) => (
<div>
<div className="font-medium text-gray-900">
{invoice.currentAccount?.accountCode || "Bilinmeyen"}
{invoice.currentAccount?.accountCode || 'Bilinmeyen'}
</div>
</div>
),
},
{
key: "dates",
header: "Tarihler",
key: 'dates',
header: 'Tarihler',
render: (invoice: FiInvoice) => {
const daysUntilDue = getDaysUntilDue(invoice.dueDate);
const daysUntilDue = getDaysUntilDue(invoice.dueDate)
return (
<div className="text-sm">
<div className="flex items-center gap-1">
<FaCalendar className="w-3 h-3 text-gray-400" />
<span>
Fatura:{" "}
{new Date(invoice.invoiceDate).toLocaleDateString("tr-TR")}
</span>
<span>Fatura: {new Date(invoice.invoiceDate).toLocaleDateString('tr-TR')}</span>
</div>
<div className="flex items-center gap-1">
<FaClock className="w-3 h-3 text-gray-400" />
<span
className={
daysUntilDue < 0
? "text-red-600"
? 'text-red-600'
: daysUntilDue <= 7
? "text-orange-600"
: "text-gray-600"
? 'text-orange-600'
: 'text-gray-600'
}
>
Vade: {new Date(invoice.dueDate).toLocaleDateString("tr-TR")}
Vade: {new Date(invoice.dueDate).toLocaleDateString('tr-TR')}
</span>
</div>
{daysUntilDue < 0 && (
<div className="text-xs text-red-600">
{Math.abs(daysUntilDue)} gün gecikme
</div>
<div className="text-xs text-red-600">{Math.abs(daysUntilDue)} gün gecikme</div>
)}
</div>
);
)
},
},
{
key: "amounts",
header: "Tutarlar",
key: 'amounts',
header: 'Tutarlar',
render: (invoice: FiInvoice) => (
<div className="text-right">
<div className="font-medium text-gray-900">
{formatCurrency(invoice.totalAmount)}
</div>
<div className="font-medium text-gray-900">{formatCurrency(invoice.totalAmount)}</div>
{invoice.paidAmount > 0 && (
<div className="text-sm text-green-600">
Ödenen: {formatCurrency(invoice.paidAmount)}
@ -216,13 +186,13 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
),
},
{
key: "status",
header: "Durum",
key: 'status',
header: 'Durum',
render: (invoice: FiInvoice) => (
<div className="space-y-1">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getInvoiceStatusColor(
invoice.status
invoice.status,
)}`}
>
{getInvoiceStatusText(invoice.status)}
@ -230,7 +200,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<br />
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getPaymentStatusColor(
invoice.paymentStatus
invoice.paymentStatus,
)}`}
>
{getPaymentStatusText(invoice.paymentStatus)}
@ -239,8 +209,8 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
),
},
{
key: "actions",
header: "İşlemler",
key: 'actions',
header: 'İşlemler',
render: (invoice: FiInvoice) => (
<div className="flex gap-1">
{invoice.paymentStatus !== PaymentStatusEnum.Paid && (
@ -269,37 +239,33 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
</div>
),
},
];
]
// Calculate statistics
const totalInvoices = invoices.length;
const totalInvoices = invoices.length
const totalSalesAmount = invoices
.filter((i) => i.invoiceType === InvoiceTypeEnum.Sales)
.reduce((sum, i) => sum + i.totalAmount, 0);
.reduce((sum, i) => sum + i.totalAmount, 0)
const totalPurchaseAmount = invoices
.filter((i) => i.invoiceType === InvoiceTypeEnum.Purchase)
.reduce((sum, i) => sum + i.totalAmount, 0);
.reduce((sum, i) => sum + i.totalAmount, 0)
const totalUnpaidAmount = invoices
.filter((i) => i.paymentStatus !== PaymentStatusEnum.Paid)
.reduce((sum, i) => sum + i.remainingAmount, 0);
.reduce((sum, i) => sum + i.remainingAmount, 0)
// Overdue invoices
const overdueInvoices = invoices.filter(
(i) =>
i.paymentStatus !== PaymentStatusEnum.Paid &&
new Date(i.dueDate) < new Date()
);
(i) => i.paymentStatus !== PaymentStatusEnum.Paid && new Date(i.dueDate) < new Date(),
)
// Payment status distribution
const paymentDistribution = Object.values(PaymentStatusEnum).map(
(status) => ({
status,
count: invoices.filter((i) => i.paymentStatus === status).length,
amount: invoices
.filter((i) => i.paymentStatus === status)
.reduce((sum, i) => sum + i.totalAmount, 0),
})
);
const paymentDistribution = Object.values(PaymentStatusEnum).map((status) => ({
status,
count: invoices.filter((i) => i.paymentStatus === status).length,
amount: invoices
.filter((i) => i.paymentStatus === status)
.reduce((sum, i) => sum + i.totalAmount, 0),
}))
// Invoice type distribution
const typeDistribution = Object.values(InvoiceTypeEnum).map((type) => ({
@ -308,7 +274,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
amount: invoices
.filter((i) => i.invoiceType === type)
.reduce((sum, i) => sum + i.totalAmount, 0),
}));
}))
return (
<div className="space-y-2">
@ -316,9 +282,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold text-gray-900">Fatura Yönetimi</h2>
<p className="text-gray-600">
Alış ve satış faturaları yönetimi
</p>
<p className="text-gray-600">Alış ve satış faturaları yönetimi</p>
</div>
<div className="flex gap-2 text-sm">
<button
@ -340,12 +304,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
{/* Stats Cards */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Widget
title="Toplam Fatura"
value={totalInvoices}
color="blue"
icon="FaFileAlt"
/>
<Widget title="Toplam Fatura" value={totalInvoices} color="blue" icon="FaFileAlt" />
<Widget
title="Satış Tutarı"
@ -372,16 +331,14 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
{/* Distribution Charts */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="bg-white rounded-lg shadow-sm border p-4">
<h3 className="text-base font-semibold text-gray-900 mb-3">
Fatura Türü Dağılımı
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">Fatura Türü Dağılımı</h3>
<div className="space-y-2">
{typeDistribution.map(({ type, count, amount }) => (
<div key={type} className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getInvoiceTypeColor(
type
type,
)}`}
>
{getInvoiceTypeText(type)}
@ -399,16 +356,14 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
</div>
<div className="bg-white rounded-lg shadow-sm border p-4">
<h3 className="text-base font-semibold text-gray-900 mb-3">
Ödeme Durumu Dağılımı
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">Ödeme Durumu Dağılımı</h3>
<div className="space-y-2">
{paymentDistribution.map(({ status, count, amount }) => (
<div key={status} className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getPaymentStatusColor(
status
status,
)}`}
>
{getPaymentStatusText(status)}
@ -431,20 +386,15 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
<div className="flex items-center gap-2">
<FaExclamationTriangle className="w-5 h-5 text-red-600" />
<h3 className="text-base font-semibold text-red-900">
Vadesi Geçmiş Faturalar
</h3>
<h3 className="text-base font-semibold text-red-900">Vadesi Geçmiş Faturalar</h3>
</div>
<p className="text-sm text-red-700 mt-1">
{overdueInvoices.length} adet fatura vadesi geçmiş durumda. Toplam
tutar:{" "}
{formatCurrency(
overdueInvoices.reduce((sum, i) => sum + i.remainingAmount, 0)
)}
{overdueInvoices.length} adet fatura vadesi geçmiş durumda. Toplam tutar:{' '}
{formatCurrency(overdueInvoices.reduce((sum, i) => sum + i.remainingAmount, 0))}
</p>
<div className="mt-2 space-y-1.5">
{overdueInvoices.slice(0, 3).map((invoice) => {
const daysOverdue = Math.abs(getDaysUntilDue(invoice.dueDate));
const daysOverdue = Math.abs(getDaysUntilDue(invoice.dueDate))
return (
<div
@ -466,7 +416,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
</span>
</div>
</div>
);
)
})}
</div>
</div>
@ -487,9 +437,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<select
value={selectedType}
onChange={(e) =>
setSelectedType(e.target.value as InvoiceTypeEnum | "all")
}
onChange={(e) => setSelectedType(e.target.value as InvoiceTypeEnum | '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"
>
<option value="all">Tüm Türler</option>
@ -502,9 +450,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<select
value={selectedStatus}
onChange={(e) =>
setSelectedStatus(e.target.value as InvoiceStatusEnum | "all")
}
onChange={(e) => setSelectedStatus(e.target.value as InvoiceStatusEnum | '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"
>
<option value="all">Tüm Durumlar</option>
@ -517,11 +463,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<select
value={selectedPaymentStatus}
onChange={(e) =>
setSelectedPaymentStatus(
e.target.value as PaymentStatusEnum | "all"
)
}
onChange={(e) => setSelectedPaymentStatus(e.target.value as PaymentStatusEnum | '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"
>
<option value="all">Tüm Ödeme Durumları</option>
@ -534,9 +476,7 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
<select
value={sortBy}
onChange={(e) =>
setSortBy(e.target.value as "date" | "amount" | "dueDate")
}
onChange={(e) => setSortBy(e.target.value as 'date' | 'amount' | 'dueDate')}
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>
@ -553,16 +493,14 @@ const InvoiceManagement: React.FC<InvoiceManagementProps> = ({
{filteredInvoices.length === 0 && (
<div className="text-center py-10">
<FaFileAlt className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<h3 className="text-base font-medium text-gray-900 mb-2">
Fatura bulunamadı
</h3>
<h3 className="text-base font-medium text-gray-900 mb-2">Fatura bulunamadı</h3>
<p className="text-sm text-gray-500">
Yeni bir fatura ekleyin veya arama kriterlerinizi değiştirin.
</p>
</div>
)}
</div>
);
};
)
}
export default InvoiceManagement;
export default InvoiceManagement

View file

@ -1,20 +1,15 @@
import React, { useState, useEffect } from "react";
import { FaFileAlt, FaSave, FaTimes } from "react-icons/fa";
import {
PromissoryNote,
NoteTypeEnum,
NoteStatusEnum,
FiCurrentAccount,
} from "../../../types/fi";
import React, { useState, useEffect } from 'react'
import { FaFileAlt, FaSave, FaTimes } from 'react-icons/fa'
import { PromissoryNote, NoteStatusEnum, FiCurrentAccount, TypeEnum } from '../../../types/fi'
import { getNoteStatusText, getTypeText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface PromissoryNoteFormProps {
note?: PromissoryNote;
currentAccounts: FiCurrentAccount[];
onSave: (
note: Omit<PromissoryNote, "id" | "creationTime" | "lastModificationTime">
) => void;
onCancel: () => void;
isOpen: boolean;
note?: PromissoryNote
currentAccounts: FiCurrentAccount[]
onSave: (note: Omit<PromissoryNote, 'id' | 'creationTime' | 'lastModificationTime'>) => void
onCancel: () => void
isOpen: boolean
}
const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
@ -25,21 +20,21 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
isOpen,
}) => {
const [formData, setFormData] = useState({
noteNumber: "",
drawerName: "",
payeeName: "",
currentAccountId: "",
issueDate: new Date().toISOString().split("T")[0],
dueDate: new Date().toISOString().split("T")[0],
noteNumber: '',
drawerName: '',
payeeName: '',
currentAccountId: '',
issueDate: new Date().toISOString().split('T')[0],
dueDate: new Date().toISOString().split('T')[0],
amount: 0,
currency: "TRY",
currency: 'TRY',
status: NoteStatusEnum.InHand,
type: NoteTypeEnum.Received,
location: "",
notes: "",
});
type: TypeEnum.Received,
location: '',
notes: '',
})
const [errors, setErrors] = useState<Record<string, string>>({});
const [errors, setErrors] = useState<Record<string, string>>({})
useEffect(() => {
if (note) {
@ -47,60 +42,60 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
noteNumber: note.noteNumber,
drawerName: note.drawerName,
payeeName: note.payeeName,
currentAccountId: note.currentAccountId || "",
issueDate: new Date(note.issueDate).toISOString().split("T")[0],
dueDate: new Date(note.dueDate).toISOString().split("T")[0],
currentAccountId: note.currentAccountId || '',
issueDate: new Date(note.issueDate).toISOString().split('T')[0],
dueDate: new Date(note.dueDate).toISOString().split('T')[0],
amount: note.amount,
currency: note.currency,
status: note.status,
type: note.type,
location: note.location || "",
notes: note.notes || "",
});
location: note.location || '',
notes: note.notes || '',
})
} else {
setFormData({
noteNumber: "",
drawerName: "",
payeeName: "",
currentAccountId: "",
issueDate: new Date().toISOString().split("T")[0],
dueDate: new Date().toISOString().split("T")[0],
noteNumber: '',
drawerName: '',
payeeName: '',
currentAccountId: '',
issueDate: new Date().toISOString().split('T')[0],
dueDate: new Date().toISOString().split('T')[0],
amount: 0,
currency: "TRY",
currency: 'TRY',
status: NoteStatusEnum.InHand,
type: NoteTypeEnum.Received,
location: "",
notes: "",
});
type: TypeEnum.Received,
location: '',
notes: '',
})
}
setErrors({});
}, [note, isOpen]);
setErrors({})
}, [note, isOpen])
const validateForm = () => {
const newErrors: Record<string, string> = {};
const newErrors: Record<string, string> = {}
if (!formData.noteNumber.trim()) {
newErrors.noteNumber = "Senet numarası gereklidir";
newErrors.noteNumber = 'Senet numarası gereklidir'
}
if (!formData.drawerName.trim()) {
newErrors.drawerName = "Keşideci adı gereklidir";
newErrors.drawerName = 'Keşideci adı gereklidir'
}
if (!formData.payeeName.trim()) {
newErrors.payeeName = "Lehtar adı gereklidir";
newErrors.payeeName = 'Lehtar adı gereklidir'
}
if (formData.amount <= 0) {
newErrors.amount = "Tutar 0'dan büyük olmalıdır";
newErrors.amount = "Tutar 0'dan büyük olmalıdır"
}
if (new Date(formData.dueDate) < new Date(formData.issueDate)) {
newErrors.dueDate = "Vade tarihi düzenleme tarihinden sonra olmalıdır";
newErrors.dueDate = 'Vade tarihi düzenleme tarihinden sonra olmalıdır'
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (validateForm()) {
const noteData = {
...formData,
@ -109,22 +104,19 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
currentAccount: formData.currentAccountId
? currentAccounts.find((acc) => acc.id === formData.currentAccountId)
: undefined,
};
onSave(noteData);
}
onSave(noteData)
}
};
}
const handleInputChange = (
field: string,
value: string | number | NoteTypeEnum | NoteStatusEnum
) => {
setFormData((prev) => ({ ...prev, [field]: value }));
const handleInputChange = (field: string, value: string | number | TypeEnum | NoteStatusEnum) => {
setFormData((prev) => ({ ...prev, [field]: value }))
if (errors[field]) {
setErrors((prev) => ({ ...prev, [field]: "" }));
setErrors((prev) => ({ ...prev, [field]: '' }))
}
};
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
@ -133,13 +125,10 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
<div className="flex items-center gap-2.5">
<FaFileAlt className="w-5 h-5 text-green-600" />
<h2 className="text-lg font-semibold text-gray-900">
{note ? "Senet Düzenle" : "Yeni Senet"}
{note ? 'Senet Düzenle' : 'Yeni Senet'}
</h2>
</div>
<button
onClick={onCancel}
className="p-2 hover:bg-gray-100 rounded-md"
>
<button onClick={onCancel} className="p-2 hover:bg-gray-100 rounded-md">
<FaTimes className="w-5 h-5 text-gray-500" />
</button>
</div>
@ -154,11 +143,9 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
<input
type="text"
value={formData.noteNumber}
onChange={(e) =>
handleInputChange("noteNumber", e.target.value)
}
onChange={(e) => handleInputChange('noteNumber', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 ${
errors.noteNumber ? "border-red-500" : "border-gray-300"
errors.noteNumber ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Senet numarasını giriniz"
/>
@ -168,100 +155,77 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Tür *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Tür *</label>
<select
value={formData.type}
onChange={(e) =>
handleInputChange("type", e.target.value as NoteTypeEnum)
}
onChange={(e) => handleInputChange('type', e.target.value as TypeEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
>
<option value={NoteTypeEnum.Received}>Alınan Senet</option>
<option value={NoteTypeEnum.Issued}>Verilen Senet</option>
{Object.values(TypeEnum).map((type) => (
<option key={type} value={type}>
{getTypeText(type)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Durum
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Durum</label>
<select
value={formData.status}
onChange={(e) =>
handleInputChange("status", e.target.value as NoteStatusEnum)
}
onChange={(e) => handleInputChange('status', e.target.value as NoteStatusEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
>
<option value={NoteStatusEnum.InHand}>Elde</option>
<option value={NoteStatusEnum.Collected}>Tahsil Edildi</option>
<option value={NoteStatusEnum.Overdue}>Vadesi Geçmiş</option>
<option value={NoteStatusEnum.Endorsed}>Ciro Edildi</option>
<option value={NoteStatusEnum.Cancelled}>İptal</option>
{Object.values(NoteStatusEnum).map((status) => (
<option key={status} value={status}>
{getNoteStatusText(status)}
</option>
))}
</select>
</div>
</div>
{/* Taraf Bilgileri */}
<div className="bg-gray-50 p-3 rounded-lg">
<h3 className="text-base font-medium text-gray-900 mb-3">
Taraf Bilgileri
</h3>
<h3 className="text-base font-medium text-gray-900 mb-3">Taraf Bilgileri</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Keşideci *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Keşideci *</label>
<input
type="text"
value={formData.drawerName}
onChange={(e) =>
handleInputChange("drawerName", e.target.value)
}
onChange={(e) => handleInputChange('drawerName', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 ${
errors.drawerName ? "border-red-500" : "border-gray-300"
errors.drawerName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Keşideci adını giriniz"
/>
{errors.drawerName && (
<p className="text-red-500 text-xs mt-1">
{errors.drawerName}
</p>
<p className="text-red-500 text-xs mt-1">{errors.drawerName}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Lehtar *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Lehtar *</label>
<input
type="text"
value={formData.payeeName}
onChange={(e) =>
handleInputChange("payeeName", e.target.value)
}
onChange={(e) => handleInputChange('payeeName', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 ${
errors.payeeName ? "border-red-500" : "border-gray-300"
errors.payeeName ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Lehtar adını giriniz"
/>
{errors.payeeName && (
<p className="text-red-500 text-xs mt-1">
{errors.payeeName}
</p>
<p className="text-red-500 text-xs mt-1">{errors.payeeName}</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Cari Hesap
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Cari Hesap</label>
<select
value={formData.currentAccountId}
onChange={(e) =>
handleInputChange("currentAccountId", e.target.value)
}
onChange={(e) => handleInputChange('currentAccountId', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
>
<option value="">Cari hesap seçiniz</option>
@ -278,39 +242,33 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
{/* Tutar ve Tarih Bilgileri */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Tutar *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Tutar *</label>
<input
type="number"
step="0.01"
min="0"
value={formData.amount}
onChange={(e) =>
handleInputChange("amount", parseFloat(e.target.value) || 0)
}
onChange={(e) => handleInputChange('amount', parseFloat(e.target.value) || 0)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 ${
errors.amount ? "border-red-500" : "border-gray-300"
errors.amount ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="0.00"
/>
{errors.amount && (
<p className="text-red-500 text-xs mt-1">{errors.amount}</p>
)}
{errors.amount && <p className="text-red-500 text-xs mt-1">{errors.amount}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Para Birimi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Para Birimi</label>
<select
value={formData.currency}
onChange={(e) => handleInputChange("currency", e.target.value)}
onChange={(e) => handleInputChange('currency', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
>
<option value="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -321,38 +279,32 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
<input
type="date"
value={formData.issueDate}
onChange={(e) => handleInputChange("issueDate", e.target.value)}
onChange={(e) => handleInputChange('issueDate', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Vade Tarihi *
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Vade Tarihi *</label>
<input
type="date"
value={formData.dueDate}
onChange={(e) => handleInputChange("dueDate", e.target.value)}
onChange={(e) => handleInputChange('dueDate', e.target.value)}
className={`w-full px-3 py-1.5 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 ${
errors.dueDate ? "border-red-500" : "border-gray-300"
errors.dueDate ? 'border-red-500' : 'border-gray-300'
}`}
/>
{errors.dueDate && (
<p className="text-red-500 text-xs mt-1">{errors.dueDate}</p>
)}
{errors.dueDate && <p className="text-red-500 text-xs mt-1">{errors.dueDate}</p>}
</div>
</div>
{/* Konum */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Konum
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Konum</label>
<input
type="text"
value={formData.location}
onChange={(e) => handleInputChange("location", e.target.value)}
onChange={(e) => handleInputChange('location', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="Senetin bulunduğu konum"
/>
@ -360,12 +312,10 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
{/* Notlar */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Notlar
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Notlar</label>
<textarea
value={formData.notes}
onChange={(e) => handleInputChange("notes", e.target.value)}
onChange={(e) => handleInputChange('notes', e.target.value)}
rows={3}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
placeholder="Ek notlar..."
@ -386,13 +336,13 @@ const PromissoryNoteForm: React.FC<PromissoryNoteFormProps> = ({
className="flex items-center gap-2 px-4 py-1.5 text-sm bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors"
>
<FaSave className="w-4 h-4" />
{note ? "Güncelle" : "Kaydet"}
{note ? 'Güncelle' : 'Kaydet'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default PromissoryNoteForm;
export default PromissoryNoteForm

View file

@ -1,178 +1,161 @@
import React, { useState, useEffect } from "react";
import { FaSave, FaTimes, FaPlus, FaTrash, FaTruck } from "react-icons/fa";
import {
FiWaybill,
FiWaybillItem,
WaybillTypeEnum,
WaybillStatusEnum,
} from "../../../types/fi";
import { mockCurrentAccounts } from "../../../mocks/mockCurrentAccounts";
import React, { useState, useEffect } from 'react'
import { FaSave, FaTimes, FaPlus, FaTrash, FaTruck } from 'react-icons/fa'
import { FiWaybill, FiWaybillItem, WaybillTypeEnum, WaybillStatusEnum } from '../../../types/fi'
import { mockCurrentAccounts } from '../../../mocks/mockCurrentAccounts'
import { getWaybillStatusText, getWaybillTypeText } from '@/utils/erp'
interface WaybillFormProps {
waybill?: FiWaybill;
onSave: (waybill: Partial<FiWaybill>) => void;
onCancel: () => void;
isVisible: boolean;
waybill?: FiWaybill
onSave: (waybill: Partial<FiWaybill>) => void
onCancel: () => void
isVisible: boolean
}
const WaybillForm: React.FC<WaybillFormProps> = ({
waybill,
onSave,
onCancel,
isVisible,
}) => {
const WaybillForm: React.FC<WaybillFormProps> = ({ waybill, onSave, onCancel, isVisible }) => {
const [formData, setFormData] = useState<Partial<FiWaybill>>({
waybillNumber: "",
waybillNumber: '',
waybillType: WaybillTypeEnum.Outgoing,
currentAccountId: "",
currentAccountId: '',
waybillDate: new Date(),
deliveryDate: new Date(),
subtotal: 0,
taxAmount: 0,
discountAmount: 0,
totalAmount: 0,
currency: "TRY",
currency: 'TRY',
status: WaybillStatusEnum.Draft,
isInvoiced: false,
items: [],
deliveryAddress: "",
receiverName: "",
receiverPhone: "",
carrierCompany: "",
trackingNumber: "",
notes: "",
});
deliveryAddress: '',
receiverName: '',
receiverPhone: '',
carrierCompany: '',
trackingNumber: '',
notes: '',
})
const [newItem, setNewItem] = useState<Partial<FiWaybillItem>>({
description: "",
description: '',
quantity: 1,
unitPrice: 0,
taxRate: 18,
discountRate: 0,
unit: "Adet",
});
unit: 'Adet',
})
useEffect(() => {
if (waybill) {
setFormData({
...waybill,
waybillDate: new Date(waybill.waybillDate),
deliveryDate: waybill.deliveryDate
? new Date(waybill.deliveryDate)
: new Date(),
});
deliveryDate: waybill.deliveryDate ? new Date(waybill.deliveryDate) : new Date(),
})
} else {
// Generate new waybill number
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, "0");
const waybillNumber = `IRS${year}${month}${String(
Math.floor(Math.random() * 10000)
).padStart(4, "0")}`;
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const waybillNumber = `IRS${year}${month}${String(Math.floor(Math.random() * 10000)).padStart(
4,
'0',
)}`
setFormData((prev) => ({
...prev,
waybillNumber,
waybillDate: now,
deliveryDate: now,
}));
}))
}
}, [waybill]);
}, [waybill])
const calculateItemTotal = (item: Partial<FiWaybillItem>) => {
const subtotal = (item.quantity || 0) * (item.unitPrice || 0);
const discountAmount = subtotal * ((item.discountRate || 0) / 100);
const taxableAmount = subtotal - discountAmount;
const taxAmount = taxableAmount * ((item.taxRate || 0) / 100);
return taxableAmount + taxAmount;
};
const subtotal = (item.quantity || 0) * (item.unitPrice || 0)
const discountAmount = subtotal * ((item.discountRate || 0) / 100)
const taxableAmount = subtotal - discountAmount
const taxAmount = taxableAmount * ((item.taxRate || 0) / 100)
return taxableAmount + taxAmount
}
const calculateWaybillTotals = (items: FiWaybillItem[]) => {
const subtotal = items.reduce(
(sum, item) => sum + item.quantity * item.unitPrice,
0
);
const discountAmount = items.reduce(
(sum, item) => sum + item.discountAmount,
0
);
const taxAmount = items.reduce((sum, item) => sum + item.taxAmount, 0);
const totalAmount = items.reduce((sum, item) => sum + item.lineTotal, 0);
const subtotal = items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0)
const discountAmount = items.reduce((sum, item) => sum + item.discountAmount, 0)
const taxAmount = items.reduce((sum, item) => sum + item.taxAmount, 0)
const totalAmount = items.reduce((sum, item) => sum + item.lineTotal, 0)
return {
subtotal,
discountAmount,
taxAmount,
totalAmount,
};
};
}
}
const handleAddItem = () => {
if (!newItem.description || !newItem.quantity || !newItem.unitPrice) {
alert("Lütfen ürün bilgilerini doldurun");
return;
alert('Lütfen ürün bilgilerini doldurun')
return
}
const subtotal = (newItem.quantity || 0) * (newItem.unitPrice || 0);
const discountAmount = subtotal * ((newItem.discountRate || 0) / 100);
const taxableAmount = subtotal - discountAmount;
const taxAmount = taxableAmount * ((newItem.taxRate || 0) / 100);
const subtotal = (newItem.quantity || 0) * (newItem.unitPrice || 0)
const discountAmount = subtotal * ((newItem.discountRate || 0) / 100)
const taxableAmount = subtotal - discountAmount
const taxAmount = taxableAmount * ((newItem.taxRate || 0) / 100)
const item: FiWaybillItem = {
id: Date.now().toString(),
waybillId: formData.id || "",
waybillId: formData.id || '',
description: newItem.description!,
quantity: newItem.quantity!,
unitPrice: newItem.unitPrice!,
unit: newItem.unit || "Adet",
unit: newItem.unit || 'Adet',
taxRate: newItem.taxRate || 18,
discountRate: newItem.discountRate || 0,
lineTotal: calculateItemTotal(newItem),
discountAmount,
taxAmount,
netAmount: taxableAmount,
};
}
const updatedItems = [...(formData.items || []), item];
const totals = calculateWaybillTotals(updatedItems);
const updatedItems = [...(formData.items || []), item]
const totals = calculateWaybillTotals(updatedItems)
setFormData((prev) => ({
...prev,
items: updatedItems,
...totals,
}));
}))
setNewItem({
description: "",
description: '',
quantity: 1,
unitPrice: 0,
taxRate: 18,
discountRate: 0,
unit: "Adet",
});
};
unit: 'Adet',
})
}
const handleRemoveItem = (itemId: string) => {
const updatedItems =
formData.items?.filter((item) => item.id !== itemId) || [];
const totals = calculateWaybillTotals(updatedItems);
const updatedItems = formData.items?.filter((item) => item.id !== itemId) || []
const totals = calculateWaybillTotals(updatedItems)
setFormData((prev) => ({
...prev,
items: updatedItems,
...totals,
}));
};
}))
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (!formData.currentAccountId) {
alert("Lütfen cari hesap seçin");
return;
alert('Lütfen cari hesap seçin')
return
}
if (!formData.items?.length) {
alert("Lütfen en az bir ürün ekleyin");
return;
alert('Lütfen en az bir ürün ekleyin')
return
}
onSave({
@ -180,18 +163,18 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
id: waybill?.id || Date.now().toString(),
creationTime: waybill?.creationTime || new Date(),
lastModificationTime: new Date(),
});
};
})
}
const formatCurrency = (amount: number) => {
return amount.toLocaleString("tr-TR", {
style: "currency",
currency: "TRY",
return amount.toLocaleString('tr-TR', {
style: 'currency',
currency: 'TRY',
minimumFractionDigits: 2,
});
};
})
}
if (!isVisible) return null;
if (!isVisible) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
@ -201,7 +184,7 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
<div className="flex items-center gap-2.5">
<FaTruck className="w-5 h-5 text-blue-600" />
<h2 className="text-lg font-semibold text-gray-900">
{waybill ? "İrsaliye Düzenle" : "Yeni İrsaliye"}
{waybill ? 'İrsaliye Düzenle' : 'Yeni İrsaliye'}
</h2>
</div>
<button
@ -217,24 +200,18 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
{/* Basic Information */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
İrsaliye No
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">İrsaliye No</label>
<input
type="text"
value={formData.waybillNumber}
onChange={(e) =>
setFormData({ ...formData, waybillNumber: e.target.value })
}
onChange={(e) => setFormData({ ...formData, waybillNumber: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
İrsaliye Türü
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">İrsaliye Türü</label>
<select
value={formData.waybillType}
onChange={(e) =>
@ -245,23 +222,16 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
}
className="w-full 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={WaybillTypeEnum.Outgoing}>
Çıkış İrsaliyesi
</option>
<option value={WaybillTypeEnum.Incoming}>
Giriş İrsaliyesi
</option>
<option value={WaybillTypeEnum.Transfer}>
Transfer İrsaliyesi
</option>
<option value={WaybillTypeEnum.Return}>İade İrsaliyesi</option>
{Object.values(WaybillTypeEnum).map((type) => (
<option key={type} value={type}>
{getWaybillTypeText(type)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Durum
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Durum</label>
<select
value={formData.status}
onChange={(e) =>
@ -272,24 +242,19 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
}
className="w-full 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={WaybillStatusEnum.Draft}>Taslak</option>
<option value={WaybillStatusEnum.Confirmed}>Onaylandı</option>
<option value={WaybillStatusEnum.Delivered}>
Teslim Edildi
</option>
<option value={WaybillStatusEnum.Cancelled}>İptal</option>
{Object.values(WaybillStatusEnum).map((status) => (
<option key={status} value={status}>
{getWaybillStatusText(status)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Cari Hesap
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Cari Hesap</label>
<select
value={formData.currentAccountId}
onChange={(e) =>
setFormData({ ...formData, currentAccountId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, currentAccountId: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
>
@ -308,7 +273,7 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</label>
<input
type="date"
value={formData.waybillDate?.toISOString().split("T")[0]}
value={formData.waybillDate?.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -321,12 +286,10 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Teslim Tarihi
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Teslim Tarihi</label>
<input
type="date"
value={formData.deliveryDate?.toISOString().split("T")[0]}
value={formData.deliveryDate?.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -340,16 +303,14 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
{/* Delivery Information */}
<div className="mb-6">
<h3 className="text-base font-semibold text-gray-900 mb-3">
Teslimat Bilgileri
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">Teslimat Bilgileri</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Teslimat Adresi
</label>
<textarea
value={formData.deliveryAddress || ""}
value={formData.deliveryAddress || ''}
onChange={(e) =>
setFormData({
...formData,
@ -362,15 +323,11 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</div>
<div className="space-y-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Alıcı Adı
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Alıcı Adı</label>
<input
type="text"
value={formData.receiverName || ""}
onChange={(e) =>
setFormData({ ...formData, receiverName: e.target.value })
}
value={formData.receiverName || ''}
onChange={(e) => setFormData({ ...formData, receiverName: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
@ -380,7 +337,7 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</label>
<input
type="text"
value={formData.receiverPhone || ""}
value={formData.receiverPhone || ''}
onChange={(e) =>
setFormData({
...formData,
@ -397,10 +354,8 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</label>
<input
type="text"
value={formData.carrierCompany || ""}
onChange={(e) =>
setFormData({ ...formData, carrierCompany: e.target.value })
}
value={formData.carrierCompany || ''}
onChange={(e) => setFormData({ ...formData, carrierCompany: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
@ -410,10 +365,8 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</label>
<input
type="text"
value={formData.trackingNumber || ""}
onChange={(e) =>
setFormData({ ...formData, trackingNumber: e.target.value })
}
value={formData.trackingNumber || ''}
onChange={(e) => setFormData({ ...formData, trackingNumber: e.target.value })}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
@ -422,9 +375,7 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
{/* Waybill Items */}
<div className="mb-6">
<h3 className="text-base font-semibold text-gray-900 mb-3">
İrsaliye Kalemleri
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">İrsaliye Kalemleri</h3>
{/* Add New Item */}
<div className="bg-gray-50 p-3 rounded-lg mb-3">
@ -435,21 +386,17 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</label>
<input
type="text"
value={newItem.description || ""}
onChange={(e) =>
setNewItem({ ...newItem, description: e.target.value })
}
value={newItem.description || ''}
onChange={(e) => setNewItem({ ...newItem, description: e.target.value })}
className="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Ürün/Hizmet açıklaması"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Miktar
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Miktar</label>
<input
type="number"
value={newItem.quantity || ""}
value={newItem.quantity || ''}
onChange={(e) =>
setNewItem({
...newItem,
@ -462,15 +409,11 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Birim
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Birim</label>
<input
type="text"
value={newItem.unit || ""}
onChange={(e) =>
setNewItem({ ...newItem, unit: e.target.value })
}
value={newItem.unit || ''}
onChange={(e) => setNewItem({ ...newItem, unit: e.target.value })}
className="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Adet"
/>
@ -481,7 +424,7 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</label>
<input
type="number"
value={newItem.unitPrice || ""}
value={newItem.unitPrice || ''}
onChange={(e) =>
setNewItem({
...newItem,
@ -535,15 +478,11 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
<tbody className="divide-y divide-gray-200">
{formData.items.map((item) => (
<tr key={item.id} className="text-sm">
<td className="px-3 py-2 text-gray-900">
{item.description}
</td>
<td className="px-3 py-2 text-gray-900">{item.description}</td>
<td className="px-3 py-2 text-gray-900 text-right">
{item.quantity.toLocaleString("tr-TR")}
</td>
<td className="px-3 py-2 text-gray-900 text-center">
{item.unit}
{item.quantity.toLocaleString('tr-TR')}
</td>
<td className="px-3 py-2 text-gray-900 text-center">{item.unit}</td>
<td className="px-3 py-2 text-gray-900 text-right">
{formatCurrency(item.unitPrice)}
</td>
@ -571,14 +510,10 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
<div className="bg-gray-50 p-4 rounded-lg mb-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Notlar
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Notlar</label>
<textarea
value={formData.notes || ""}
onChange={(e) =>
setFormData({ ...formData, notes: e.target.value })
}
value={formData.notes || ''}
onChange={(e) => setFormData({ ...formData, notes: e.target.value })}
rows={4}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="İrsaliye ile ilgili notlar..."
@ -587,9 +522,7 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
<div className="space-y-2 text-sm">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">Ara Toplam:</span>
<span className="font-medium">
{formatCurrency(formData.subtotal || 0)}
</span>
<span className="font-medium">{formatCurrency(formData.subtotal || 0)}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">İndirim:</span>
@ -599,15 +532,11 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
</div>
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">KDV:</span>
<span className="font-medium">
{formatCurrency(formData.taxAmount || 0)}
</span>
<span className="font-medium">{formatCurrency(formData.taxAmount || 0)}</span>
</div>
<div className="border-t pt-3">
<div className="flex justify-between items-center">
<span className="text-base font-semibold text-gray-900">
Genel Toplam:
</span>
<span className="text-base font-semibold text-gray-900">Genel Toplam:</span>
<span className="text-base font-bold text-blue-600">
{formatCurrency(formData.totalAmount || 0)}
</span>
@ -631,13 +560,13 @@ const WaybillForm: React.FC<WaybillFormProps> = ({
className="px-4 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-2"
>
<FaSave className="w-4 h-4" />
{waybill ? "Güncelle" : "Kaydet"}
{waybill ? 'Güncelle' : 'Kaydet'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default WaybillForm;
export default WaybillForm

View file

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState } from 'react'
import {
FaPlus,
FaSearch,
@ -9,28 +9,24 @@ import {
FaTruck,
FaCheck,
FaEye,
} from "react-icons/fa";
import {
FiWaybill,
WaybillTypeEnum,
WaybillStatusEnum,
} from "../../../types/fi";
import DataTable, { Column } from "../../../components/common/DataTable";
import Widget from "../../../components/common/Widget";
} from 'react-icons/fa'
import { FiWaybill, WaybillTypeEnum, WaybillStatusEnum } from '../../../types/fi'
import DataTable, { Column } from '../../../components/common/DataTable'
import Widget from '../../../components/common/Widget'
import {
getWaybillStatusColor,
getWaybillStatusText,
getWaybillTypeColor,
getWaybillTypeText,
} from "../../../utils/erp";
} from '../../../utils/erp'
interface WaybillManagementProps {
waybills: FiWaybill[];
onAdd: () => void;
onEdit: (waybill: FiWaybill) => void;
onViewDetails: (waybill: FiWaybill) => void;
onCreateInvoice: (waybill: FiWaybill) => void;
onMarkAsDelivered: (waybill: FiWaybill) => void;
waybills: FiWaybill[]
onAdd: () => void
onEdit: (waybill: FiWaybill) => void
onViewDetails: (waybill: FiWaybill) => void
onCreateInvoice: (waybill: FiWaybill) => void
onMarkAsDelivered: (waybill: FiWaybill) => void
}
const WaybillManagement: React.FC<WaybillManagementProps> = ({
@ -41,109 +37,87 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
onCreateInvoice,
onMarkAsDelivered,
}) => {
const [searchTerm, setSearchTerm] = useState("");
const [selectedType, setSelectedType] = useState<WaybillTypeEnum | "all">(
"all"
);
const [selectedStatus, setSelectedStatus] = useState<
WaybillStatusEnum | "all"
>("all");
const [showInvoicedOnly, setShowInvoicedOnly] = useState<
"all" | "invoiced" | "not_invoiced"
>("not_invoiced");
const [sortBy, setSortBy] = useState<"date" | "amount" | "deliveryDate">(
"date"
);
const [searchTerm, setSearchTerm] = useState('')
const [selectedType, setSelectedType] = useState<WaybillTypeEnum | 'all'>('all')
const [selectedStatus, setSelectedStatus] = useState<WaybillStatusEnum | 'all'>('all')
const [showInvoicedOnly, setShowInvoicedOnly] = useState<'all' | 'invoiced' | 'not_invoiced'>(
'not_invoiced',
)
const [sortBy, setSortBy] = useState<'date' | 'amount' | 'deliveryDate'>('date')
const filteredWaybills = waybills
.filter((waybill) => {
if (
searchTerm &&
!waybill.waybillNumber
.toLowerCase()
.includes(searchTerm.toLowerCase()) &&
!waybill.currentAccount?.accountCode
?.toLowerCase()
.includes(searchTerm.toLowerCase()) &&
!waybill.trackingNumber
?.toLowerCase()
.includes(searchTerm.toLowerCase())
!waybill.waybillNumber.toLowerCase().includes(searchTerm.toLowerCase()) &&
!waybill.currentAccount?.accountCode?.toLowerCase().includes(searchTerm.toLowerCase()) &&
!waybill.trackingNumber?.toLowerCase().includes(searchTerm.toLowerCase())
) {
return false;
return false
}
if (selectedType !== "all" && waybill.waybillType !== selectedType) {
return false;
if (selectedType !== 'all' && waybill.waybillType !== selectedType) {
return false
}
if (selectedStatus !== "all" && waybill.status !== selectedStatus) {
return false;
if (selectedStatus !== 'all' && waybill.status !== selectedStatus) {
return false
}
if (showInvoicedOnly === "invoiced" && !waybill.isInvoiced) {
return false;
if (showInvoicedOnly === 'invoiced' && !waybill.isInvoiced) {
return false
}
if (showInvoicedOnly === "not_invoiced" && waybill.isInvoiced) {
return false;
if (showInvoicedOnly === 'not_invoiced' && waybill.isInvoiced) {
return false
}
return true;
return true
})
.sort((a, b) => {
switch (sortBy) {
case "date":
return (
new Date(b.waybillDate).getTime() -
new Date(a.waybillDate).getTime()
);
case "amount":
return b.totalAmount - a.totalAmount;
case "deliveryDate":
if (!a.deliveryDate && !b.deliveryDate) return 0;
if (!a.deliveryDate) return 1;
if (!b.deliveryDate) return -1;
return (
new Date(a.deliveryDate).getTime() -
new Date(b.deliveryDate).getTime()
);
case 'date':
return new Date(b.waybillDate).getTime() - new Date(a.waybillDate).getTime()
case 'amount':
return b.totalAmount - a.totalAmount
case 'deliveryDate':
if (!a.deliveryDate && !b.deliveryDate) return 0
if (!a.deliveryDate) return 1
if (!b.deliveryDate) return -1
return new Date(a.deliveryDate).getTime() - new Date(b.deliveryDate).getTime()
default:
return 0;
return 0
}
});
})
const formatCurrency = (amount: number) => {
return amount.toLocaleString("tr-TR", {
style: "currency",
currency: "TRY",
return amount.toLocaleString('tr-TR', {
style: 'currency',
currency: 'TRY',
minimumFractionDigits: 2,
});
};
})
}
const formatDate = (date: Date) => {
return new Date(date).toLocaleDateString("tr-TR");
};
return new Date(date).toLocaleDateString('tr-TR')
}
const columns: Column<FiWaybill>[] = [
{
key: "waybillNumber",
header: "İrsaliye No",
key: 'waybillNumber',
header: 'İrsaliye No',
sortable: true,
render: (waybill: FiWaybill) => (
<div>
<div className="font-medium text-gray-900">
{waybill.waybillNumber}
</div>
<div className="font-medium text-gray-900">{waybill.waybillNumber}</div>
{waybill.trackingNumber && (
<div className="text-sm text-gray-500">
Takip: {waybill.trackingNumber}
</div>
<div className="text-sm text-gray-500">Takip: {waybill.trackingNumber}</div>
)}
</div>
),
},
{
key: "type",
header: "Tür",
key: 'type',
header: 'Tür',
render: (waybill: FiWaybill) => (
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getWaybillTypeColor(
waybill.waybillType
waybill.waybillType,
)}`}
>
{getWaybillTypeText(waybill.waybillType)}
@ -151,22 +125,20 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
),
},
{
key: "currentAccount",
header: "Cari Hesap",
key: 'currentAccount',
header: 'Cari Hesap',
render: (waybill: FiWaybill) => (
<div>
<div className="font-medium text-gray-900">
{waybill.currentAccount?.accountCode || "Bilinmeyen"}
</div>
<div className="text-sm text-gray-500">
{waybill.currentAccount?.accountCode}
{waybill.currentAccount?.accountCode || 'Bilinmeyen'}
</div>
<div className="text-sm text-gray-500">{waybill.currentAccount?.accountCode}</div>
</div>
),
},
{
key: "dates",
header: "Tarihler",
key: 'dates',
header: 'Tarihler',
render: (waybill: FiWaybill) => (
<div className="text-sm">
<div className="flex items-center gap-1">
@ -183,27 +155,23 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
),
},
{
key: "amounts",
header: "Tutarlar",
key: 'amounts',
header: 'Tutarlar',
render: (waybill: FiWaybill) => (
<div className="text-right">
<div className="font-medium text-gray-900">
{formatCurrency(waybill.totalAmount)}
</div>
<div className="text-sm text-gray-500">
{waybill.items.length} kalem
</div>
<div className="font-medium text-gray-900">{formatCurrency(waybill.totalAmount)}</div>
<div className="text-sm text-gray-500">{waybill.items.length} kalem</div>
</div>
),
},
{
key: "status",
header: "Durum",
key: 'status',
header: 'Durum',
render: (waybill: FiWaybill) => (
<div className="space-y-1">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getWaybillStatusColor(
waybill.status
waybill.status,
)}`}
>
{getWaybillStatusText(waybill.status)}
@ -211,25 +179,21 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<br />
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${
waybill.isInvoiced
? "bg-green-100 text-green-800"
: "bg-yellow-100 text-yellow-800"
waybill.isInvoiced ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'
}`}
>
{waybill.isInvoiced ? "Faturalandı" : "Faturalanmadı"}
{waybill.isInvoiced ? 'Faturalandı' : 'Faturalanmadı'}
</span>
</div>
),
},
{
key: "carrier",
header: "Kargo",
key: 'carrier',
header: 'Kargo',
render: (waybill: FiWaybill) => (
<div className="text-sm">
{waybill.carrierCompany && (
<div className="font-medium text-gray-900">
{waybill.carrierCompany}
</div>
<div className="font-medium text-gray-900">{waybill.carrierCompany}</div>
)}
{waybill.receiverName && (
<div className="text-gray-500">Alıcı: {waybill.receiverName}</div>
@ -238,8 +202,8 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
),
},
{
key: "actions",
header: "İşlemler",
key: 'actions',
header: 'İşlemler',
render: (waybill: FiWaybill) => (
<div className="flex gap-1">
<button
@ -256,16 +220,15 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
>
<FaEdit className="w-4 h-4" />
</button>
{!waybill.isInvoiced &&
waybill.status === WaybillStatusEnum.Delivered && (
<button
onClick={() => onCreateInvoice(waybill)}
className="p-1 text-purple-600 hover:bg-purple-50 rounded"
title="Fatura Oluştur"
>
<FaFileAlt className="w-4 h-4" />
</button>
)}
{!waybill.isInvoiced && waybill.status === WaybillStatusEnum.Delivered && (
<button
onClick={() => onCreateInvoice(waybill)}
className="p-1 text-purple-600 hover:bg-purple-50 rounded"
title="Fatura Oluştur"
>
<FaFileAlt className="w-4 h-4" />
</button>
)}
{waybill.status === WaybillStatusEnum.Confirmed && (
<button
onClick={() => onMarkAsDelivered(waybill)}
@ -278,18 +241,13 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
</div>
),
},
];
]
// Calculate statistics
const totalWaybills = waybills.length;
const notInvoicedWaybills = waybills.filter((w) => !w.isInvoiced);
const deliveredWaybills = waybills.filter(
(w) => w.status === WaybillStatusEnum.Delivered
);
const totalNotInvoicedAmount = notInvoicedWaybills.reduce(
(sum, w) => sum + w.totalAmount,
0
);
const totalWaybills = waybills.length
const notInvoicedWaybills = waybills.filter((w) => !w.isInvoiced)
const deliveredWaybills = waybills.filter((w) => w.status === WaybillStatusEnum.Delivered)
const totalNotInvoicedAmount = notInvoicedWaybills.reduce((sum, w) => sum + w.totalAmount, 0)
// Waybill type distribution
const typeDistribution = Object.values(WaybillTypeEnum).map((type) => ({
@ -298,16 +256,14 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
amount: waybills
.filter((w) => w.waybillType === type)
.reduce((sum, w) => sum + w.totalAmount, 0),
}));
}))
// Status distribution
const statusDistribution = Object.values(WaybillStatusEnum).map((status) => ({
status,
count: waybills.filter((w) => w.status === status).length,
amount: waybills
.filter((w) => w.status === status)
.reduce((sum, w) => sum + w.totalAmount, 0),
}));
amount: waybills.filter((w) => w.status === status).reduce((sum, w) => sum + w.totalAmount, 0),
}))
return (
<div className="space-y-2">
@ -315,9 +271,7 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold text-gray-900">İrsaliye Yönetimi</h2>
<p className="text-gray-600">
Giriş ve çıkış irsaliyeleri yönetimi
</p>
<p className="text-gray-600">Giriş ve çıkış irsaliyeleri yönetimi</p>
</div>
<div className="flex gap-2 text-sm">
<button
@ -332,12 +286,7 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
{/* Stats Cards */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Widget
title="Toplam İrsaliye"
value={totalWaybills}
color="blue"
icon="FaFileAlt"
/>
<Widget title="Toplam İrsaliye" value={totalWaybills} color="blue" icon="FaFileAlt" />
<Widget
title="Faturalanmamış"
@ -364,25 +313,21 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
{/* Distribution Charts */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="bg-white rounded-lg shadow-sm border p-4">
<h3 className="text-base font-semibold text-gray-900 mb-3">
İrsaliye Türü Dağılımı
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">İrsaliye Türü Dağılımı</h3>
<div className="space-y-2">
{typeDistribution.map(({ type, count, amount }) => (
<div key={type} className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getWaybillTypeColor(
type
type,
)}`}
>
{getWaybillTypeText(type)}
</span>
</div>
<div className="flex items-center gap-4">
<span className="text-sm text-gray-600">
{count} irsaliye
</span>
<span className="text-sm text-gray-600">{count} irsaliye</span>
<span className="text-sm font-medium text-gray-900">
{formatCurrency(amount)}
</span>
@ -393,25 +338,21 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
</div>
<div className="bg-white rounded-lg shadow-sm border p-4">
<h3 className="text-base font-semibold text-gray-900 mb-3">
Durum Dağılımı
</h3>
<h3 className="text-base font-semibold text-gray-900 mb-3">Durum Dağılımı</h3>
<div className="space-y-2">
{statusDistribution.map(({ status, count, amount }) => (
<div key={status} className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getWaybillStatusColor(
status
status,
)}`}
>
{getWaybillStatusText(status)}
</span>
</div>
<div className="flex items-center gap-4">
<span className="text-sm text-gray-600">
{count} irsaliye
</span>
<span className="text-sm text-gray-600">{count} irsaliye</span>
<span className="text-sm font-medium text-gray-900">
{formatCurrency(amount)}
</span>
@ -427,13 +368,11 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<div className="bg-orange-50 border border-orange-200 rounded-lg p-3">
<div className="flex items-center gap-2">
<FaExclamationTriangle className="w-5 h-5 text-orange-600" />
<h3 className="text-base font-semibold text-orange-900">
Faturalanmamış İrsaliyeler
</h3>
<h3 className="text-base font-semibold text-orange-900">Faturalanmamış İrsaliyeler</h3>
</div>
<p className="text-sm text-orange-700 mt-1">
{notInvoicedWaybills.length} adet irsaliye henüz faturalanmamış.
Toplam tutar: {formatCurrency(totalNotInvoicedAmount)}
{notInvoicedWaybills.length} adet irsaliye henüz faturalanmamış. Toplam tutar:{' '}
{formatCurrency(totalNotInvoicedAmount)}
</p>
</div>
)}
@ -453,9 +392,7 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<select
value={selectedType}
onChange={(e) =>
setSelectedType(e.target.value as WaybillTypeEnum | "all")
}
onChange={(e) => setSelectedType(e.target.value as WaybillTypeEnum | '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"
>
<option value="all">Tüm Türler</option>
@ -468,9 +405,7 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<select
value={selectedStatus}
onChange={(e) =>
setSelectedStatus(e.target.value as WaybillStatusEnum | "all")
}
onChange={(e) => setSelectedStatus(e.target.value as WaybillStatusEnum | '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"
>
<option value="all">Tüm Durumlar</option>
@ -484,9 +419,7 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<select
value={showInvoicedOnly}
onChange={(e) =>
setShowInvoicedOnly(
e.target.value as "all" | "invoiced" | "not_invoiced"
)
setShowInvoicedOnly(e.target.value as 'all' | 'invoiced' | 'not_invoiced')
}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
@ -497,9 +430,7 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
<select
value={sortBy}
onChange={(e) =>
setSortBy(e.target.value as "date" | "amount" | "deliveryDate")
}
onChange={(e) => setSortBy(e.target.value as 'date' | 'amount' | 'deliveryDate')}
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>
@ -516,16 +447,14 @@ const WaybillManagement: React.FC<WaybillManagementProps> = ({
{filteredWaybills.length === 0 && (
<div className="text-center py-10">
<FaFileAlt className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<h3 className="text-base font-medium text-gray-900 mb-2">
İrsaliye bulunamadı
</h3>
<h3 className="text-base font-medium text-gray-900 mb-2">İrsaliye bulunamadı</h3>
<p className="text-sm text-gray-500">
Yeni bir irsaliye ekleyin veya arama kriterlerinizi değiştirin.
</p>
</div>
)}
</div>
);
};
)
}
export default WaybillManagement;
export default WaybillManagement

View file

@ -28,8 +28,8 @@ import Widget from '../../../components/common/Widget'
import { BusinessPartyStatusEnum, PartyType } from '../../../types/common'
import {
getBusinessPartyStatusColor,
getBusinessPartyStatusName,
getCustomerSegmentName,
getBusinessPartyStatusText,
getCustomerSegmentText,
} from '../../../utils/erp'
import { ROUTES_ENUM } from '@/routes/route.constant'
@ -177,10 +177,11 @@ const CustomerCards: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={BusinessPartyStatusEnum.Prospect}>Potansiyel</option>
<option value={BusinessPartyStatusEnum.Active}>Aktif</option>
<option value={BusinessPartyStatusEnum.Inactive}>Pasif</option>
<option value={BusinessPartyStatusEnum.Blocked}>Blokeli</option>
{Object.values(BusinessPartyStatusEnum).map((status) => (
<option key={status} value={status}>
{getBusinessPartyStatusText(status)}
</option>
))}
</select>
</div>
@ -192,10 +193,11 @@ const CustomerCards: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={CustomerSegmentEnum.Enterprise}>Kurumsal</option>
<option value={CustomerSegmentEnum.SMB}>KOBİ</option>
<option value={CustomerSegmentEnum.Startup}>Girişim</option>
<option value={CustomerSegmentEnum.Government}>Kamu</option>
{Object.values(CustomerSegmentEnum).map((segment) => (
<option key={segment} value={segment}>
{getCustomerSegmentText(segment)}
</option>
))}
</select>
</div>
@ -289,7 +291,7 @@ const CustomerCards: React.FC = () => {
{customer.code}
</h3>
<p className="text-sm text-gray-600">
{getCustomerSegmentName(customer.customerSegment!)}
{getCustomerSegmentText(customer.customerSegment!)}
</p>
</div>
</div>
@ -299,7 +301,7 @@ const CustomerCards: React.FC = () => {
getBusinessPartyStatusColor(customer.status!),
)}
>
{getBusinessPartyStatusName(customer.status!)}
{getBusinessPartyStatusText(customer.status!)}
</span>
</div>

View file

@ -18,6 +18,13 @@ import { mockBusinessParties, mockBusinessPartyNew } from '../../../mocks/mockBu
import { BusinessParty, BusinessPartyStatusEnum, PaymentTerms } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import {
getBusinessPartyStatusText,
getCustomerSegmentText,
getCustomerTypeText,
getPaymentTermsText,
} from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
const CustomerEdit: React.FC = () => {
const { id } = useParams<{ id: string }>()
@ -316,10 +323,11 @@ const CustomerEdit: React.FC = () => {
onChange={(e) => handleInputChange('customerType', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={CustomerTypeEnum.Company}>Şirket</option>
<option value={CustomerTypeEnum.Individual}>Bireysel</option>
<option value={CustomerTypeEnum.Government}>Kamu</option>
<option value={CustomerTypeEnum.NonProfit}>Kar Amacı Gütmeyen</option>
{Object.values(CustomerTypeEnum).map((type) => (
<option key={type} value={type}>
{getCustomerTypeText(type)}
</option>
))}
</select>
</div>
@ -354,10 +362,11 @@ const CustomerEdit: React.FC = () => {
onChange={(e) => handleInputChange('status', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={BusinessPartyStatusEnum.Prospect}>Potansiyel</option>
<option value={BusinessPartyStatusEnum.Active}>Aktif</option>
<option value={BusinessPartyStatusEnum.Inactive}>Pasif</option>
<option value={BusinessPartyStatusEnum.Blocked}>Blokeli</option>
{Object.values(BusinessPartyStatusEnum).map((status) => (
<option key={status} value={status}>
{getBusinessPartyStatusText(status)}
</option>
))}
</select>
</div>
@ -370,10 +379,11 @@ const CustomerEdit: React.FC = () => {
onChange={(e) => handleInputChange('customerSegment', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={CustomerSegmentEnum.Enterprise}>Kurumsal</option>
<option value={CustomerSegmentEnum.SMB}>KOBİ</option>
<option value={CustomerSegmentEnum.Startup}>Girişim</option>
<option value={CustomerSegmentEnum.Government}>Kamu</option>
{Object.values(CustomerSegmentEnum).map((segment) => (
<option key={segment} value={segment}>
{getCustomerSegmentText(segment)}
</option>
))}
</select>
</div>
</div>
@ -644,10 +654,11 @@ const CustomerEdit: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="TRY">Türk Lirası (TRY)</option>
<option value="USD">Amerikan Doları (USD)</option>
<option value="EUR">Euro (EUR)</option>
<option value="GBP">İngiliz Sterlini (GBP)</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -660,11 +671,11 @@ const CustomerEdit: React.FC = () => {
onChange={(e) => handleInputChange('paymentTerms', e.target.value)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={PaymentTerms.Prepaid}>Peşin</option>
<option value={PaymentTerms.COD}>Kapıda Ödeme</option>
<option value={PaymentTerms.Net30}>30 Gün Vade</option>
<option value={PaymentTerms.Net60}>60 Gün Vade</option>
<option value={PaymentTerms.Net90}>90 Gün Vade</option>
{Object.values(PaymentTerms).map((term) => (
<option key={term} value={term}>
{getPaymentTermsText(term)}
</option>
))}
</select>
</div>
</div>

View file

@ -11,9 +11,23 @@ import {
} from 'react-icons/fa'
import LoadingSpinner from '../../../components/common/LoadingSpinner'
import { mockBusinessParties, mockBusinessPartyNew } from '../../../mocks/mockBusinessParties'
import { BusinessParty } from '../../../types/common'
import {
BusinessParty,
BusinessPartyIndustryEnum,
BusinessPartyStatusEnum,
PaymentTerms,
} from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { mockCurrencies } from '@/mocks/mockCurrencies'
import {
getBusinessPartyIndustryText,
getBusinessPartyStatusText,
getCustomerSegmentText,
getCustomerTypeText,
getPaymentTermsText,
} from '@/utils/erp'
import { CustomerSegmentEnum, CustomerTypeEnum } from '@/types/crm'
interface ValidationErrors {
[key: string]: string
@ -181,8 +195,11 @@ const CustomerForm: React.FC = () => {
}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="COMPANY">Şirket</option>
<option value="INDIVIDUAL">Bireysel</option>
{Object.values(CustomerTypeEnum).map((type) => (
<option key={type} value={type}>
{getCustomerTypeText(type)}
</option>
))}
</select>
</div>
</div>
@ -216,14 +233,11 @@ const CustomerForm: React.FC = () => {
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Sektör seçin</option>
<option value="TECHNOLOGY">Teknoloji</option>
<option value="MANUFACTURING">İmalat</option>
<option value="CONSTRUCTION">İnşaat</option>
<option value="AUTOMOTIVE">Otomotiv</option>
<option value="RETAIL">Perakende</option>
<option value="FINANCE">Finans</option>
<option value="HEALTHCARE">Sağlık</option>
<option value="OTHER">Diğer</option>
{Object.values(BusinessPartyIndustryEnum).map((industry) => (
<option key={industry} value={industry}>
{getBusinessPartyIndustryText(industry)}
</option>
))}
</select>
</div>
</div>
@ -369,11 +383,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('paymentTerms', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="CASH">Peşin</option>
<option value="NET_15">15 Gün Vadeli</option>
<option value="NET_30">30 Gün Vadeli</option>
<option value="NET_60">60 Gün Vadeli</option>
<option value="NET_90">90 Gün Vadeli</option>
{Object.values(PaymentTerms).map((term) => (
<option key={term} value={term}>
{getPaymentTermsText(term)}
</option>
))}
</select>
</div>
@ -386,9 +400,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="TRY">Türk Lirası (TRY)</option>
<option value="USD">Amerikan Doları (USD)</option>
<option value="EUR">Euro (EUR)</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
@ -415,10 +431,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('status', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="ACTIVE">Aktif</option>
<option value="INACTIVE">Pasif</option>
<option value="PROSPECT">Potansiyel</option>
<option value="BLOCKED">Blokeli</option>
{Object.values(BusinessPartyStatusEnum).map((status) => (
<option key={status} value={status}>
{getBusinessPartyStatusText(status)}
</option>
))}
</select>
</div>
@ -431,10 +448,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('customerSegment', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="STANDARD">Standart</option>
<option value="PREMIUM">Premium</option>
<option value="ENTERPRISE">Kurumsal</option>
<option value="VIP">VIP</option>
{Object.values(CustomerSegmentEnum).map((segment) => (
<option key={segment} value={segment}>
{getCustomerSegmentText(segment)}
</option>
))}
</select>
</div>
@ -442,16 +460,13 @@ const CustomerForm: React.FC = () => {
<label className="block text-xs font-medium text-gray-700 mb-1">
Sorumlu Satış Temsilcisi
</label>
<select
<input
type="text"
value={formData.assignedSalesRep}
onChange={(e) => handleInputChange('assignedSalesRep', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Temsilci seçin</option>
<option value="sales_rep_1">Mehmet Özkan</option>
<option value="sales_rep_2">Ayşe Demir</option>
<option value="sales_rep_3">Ali Yılmaz</option>
</select>
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Satış temsilcisi adı"
/>
</div>
</div>

View file

@ -10,10 +10,24 @@ import {
FaEnvelope,
} from 'react-icons/fa'
import LoadingSpinner from '../../../components/common/LoadingSpinner'
import { BusinessParty } from '../../../types/common'
import {
BusinessParty,
BusinessPartyIndustryEnum,
BusinessPartyStatusEnum,
PaymentTerms,
} from '../../../types/common'
import { mockBusinessPartyNew } from '../../../mocks/mockBusinessParties'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { mockCurrencies } from '@/mocks/mockCurrencies'
import { CustomerSegmentEnum, CustomerTypeEnum } from '@/types/crm'
import {
getBusinessPartyIndustryText,
getBusinessPartyStatusText,
getCustomerSegmentText,
getCustomerTypeText,
getPaymentTermsText,
} from '@/utils/erp'
interface ValidationErrors {
[key: string]: string
@ -174,13 +188,14 @@ const CustomerForm: React.FC = () => {
</label>
<select
value={formData.customerType}
onChange={(e) =>
handleInputChange('customerType', e.target.value as 'INDIVIDUAL' | 'COMPANY')
}
onChange={(e) => handleInputChange('customerType', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="COMPANY">Şirket</option>
<option value="INDIVIDUAL">Bireysel</option>
{Object.values(CustomerTypeEnum).map((type) => (
<option key={type} value={type}>
{getCustomerTypeText(type)}
</option>
))}
</select>
</div>
</div>
@ -214,14 +229,11 @@ const CustomerForm: React.FC = () => {
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Sektör seçin</option>
<option value="TECHNOLOGY">Teknoloji</option>
<option value="MANUFACTURING">İmalat</option>
<option value="CONSTRUCTION">İnşaat</option>
<option value="AUTOMOTIVE">Otomotiv</option>
<option value="RETAIL">Perakende</option>
<option value="FINANCE">Finans</option>
<option value="HEALTHCARE">Sağlık</option>
<option value="OTHER">Diğer</option>
{Object.values(BusinessPartyIndustryEnum).map((industry) => (
<option key={industry} value={industry}>
{getBusinessPartyIndustryText(industry)}
</option>
))}
</select>
</div>
</div>
@ -367,11 +379,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('paymentTerms', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="CASH">Peşin</option>
<option value="NET_15">15 Gün Vadeli</option>
<option value="NET_30">30 Gün Vadeli</option>
<option value="NET_60">60 Gün Vadeli</option>
<option value="NET_90">90 Gün Vadeli</option>
{Object.values(PaymentTerms).map((term) => (
<option key={term} value={term}>
{getPaymentTermsText(term)}
</option>
))}
</select>
</div>
@ -384,9 +396,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="TRY">Türk Lirası (TRY)</option>
<option value="USD">Amerikan Doları (USD)</option>
<option value="EUR">Euro (EUR)</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
@ -413,10 +427,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('status', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="ACTIVE">Aktif</option>
<option value="INACTIVE">Pasif</option>
<option value="PROSPECT">Potansiyel</option>
<option value="BLOCKED">Blokeli</option>
{Object.values(BusinessPartyStatusEnum).map((status) => (
<option key={status} value={status}>
{getBusinessPartyStatusText(status)}
</option>
))}
</select>
</div>
@ -429,10 +444,11 @@ const CustomerForm: React.FC = () => {
onChange={(e) => handleInputChange('customerSegment', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="STANDARD">Standart</option>
<option value="PREMIUM">Premium</option>
<option value="ENTERPRISE">Kurumsal</option>
<option value="VIP">VIP</option>
{Object.values(CustomerSegmentEnum).map((segment) => (
<option key={segment} value={segment}>
{getCustomerSegmentText(segment)}
</option>
))}
</select>
</div>
@ -440,16 +456,13 @@ const CustomerForm: React.FC = () => {
<label className="block text-xs font-medium text-gray-700 mb-1">
Sorumlu Satış Temsilcisi
</label>
<select
<input
type="text"
value={formData.assignedSalesRep}
onChange={(e) => handleInputChange('assignedSalesRep', e.target.value)}
className="block w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Temsilci seçin</option>
<option value="sales_rep_1">Mehmet Özkan</option>
<option value="sales_rep_2">Ayşe Demir</option>
<option value="sales_rep_3">Ali Yılmaz</option>
</select>
placeholder="Satış temsilcisi adı"
/>
</div>
</div>

View file

@ -25,9 +25,9 @@ import { BusinessPartyStatusEnum, PartyType } from '../../../types/common'
import Widget from '../../../components/common/Widget'
import {
getBusinessPartyStatusColor,
getBusinessPartyStatusName,
getBusinessPartyStatusText,
getCustomerSegmentColor,
getCustomerSegmentName,
getCustomerSegmentText,
} from '../../../utils/erp'
import { ROUTES_ENUM } from '@/routes/route.constant'
@ -146,10 +146,11 @@ const CustomerList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={BusinessPartyStatusEnum.Prospect}>Potansiyel</option>
<option value={BusinessPartyStatusEnum.Active}>Aktif</option>
<option value={BusinessPartyStatusEnum.Inactive}>Pasif</option>
<option value={BusinessPartyStatusEnum.Blocked}>Blokeli</option>
{Object.values(BusinessPartyStatusEnum).map((status) => (
<option key={status} value={status}>
{getBusinessPartyStatusText(status)}
</option>
))}
</select>
</div>
@ -161,10 +162,11 @@ const CustomerList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={CustomerSegmentEnum.Enterprise}>Kurumsal</option>
<option value={CustomerSegmentEnum.SMB}>KOBİ</option>
<option value={CustomerSegmentEnum.Startup}>Girişim</option>
<option value={CustomerSegmentEnum.Government}>Kamu</option>
{Object.values(CustomerSegmentEnum).map((segment) => (
<option key={segment} value={segment}>
{getCustomerSegmentText(segment)}
</option>
))}
</select>
</div>
@ -310,7 +312,7 @@ const CustomerList: React.FC = () => {
),
)}
>
{getCustomerSegmentName(
{getCustomerSegmentText(
customer.customerSegment || CustomerSegmentEnum.SMB,
)}
</div>
@ -322,7 +324,7 @@ const CustomerList: React.FC = () => {
),
)}
>
{getBusinessPartyStatusName(
{getBusinessPartyStatusText(
customer.status ?? BusinessPartyStatusEnum.Prospect,
)}
</span>

View file

@ -30,8 +30,8 @@ import dayjs from 'dayjs'
import { mockBusinessParties } from '../../../mocks/mockBusinessParties'
import {
getBusinessPartyStatusColor,
getBusinessPartyStatusName,
getCustomerSegmentName,
getBusinessPartyStatusText,
getCustomerSegmentText,
} from '../../../utils/erp'
import { BusinessPartyStatusEnum } from '../../../types/common'
import { Container } from '@/components/shared'
@ -167,7 +167,7 @@ const CustomerView: React.FC = () => {
),
)}
>
{getBusinessPartyStatusName(
{getBusinessPartyStatusText(
customer.status || BusinessPartyStatusEnum.Active,
)}
</span>
@ -176,7 +176,7 @@ const CustomerView: React.FC = () => {
<span className="text-sm text-gray-600">{customer.code}</span>
<span className="text-sm text-gray-400"></span>
<span className="text-sm text-gray-600">
{getCustomerSegmentName(
{getCustomerSegmentText(
customer.customerSegment || CustomerSegmentEnum.Startup,
)}
</span>
@ -311,7 +311,7 @@ const CustomerView: React.FC = () => {
<div className="flex justify-between">
<span className="text-gray-600">Segment:</span>
<span className="font-medium">
{getCustomerSegmentName(
{getCustomerSegmentText(
customer.customerSegment || CustomerSegmentEnum.Startup,
)}
</span>
@ -729,7 +729,7 @@ const CustomerView: React.FC = () => {
),
)}
>
{getBusinessPartyStatusName(
{getBusinessPartyStatusText(
customer.status || BusinessPartyStatusEnum.Active,
)}
</span>
@ -739,7 +739,7 @@ const CustomerView: React.FC = () => {
Müşteri Segmenti
</label>
<p className="text-gray-900">
{getCustomerSegmentName(
{getCustomerSegmentText(
customer.customerSegment || CustomerSegmentEnum.Startup,
)}
</p>

View file

@ -10,6 +10,7 @@ import { mockBusinessParties } from '../../../mocks/mockBusinessParties'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { BusinessParty } from '../../../types/common'
import { getOpportunityLeadSourceText, getOpportunityStageText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface OpportunityFormProps {
isOpen: boolean
@ -353,9 +354,11 @@ const OpportunityForm: React.FC<OpportunityFormProps> = ({
onChange={handleInputChange}
className="w-full 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="TRY">TRY - Türk Lirası</option>
<option value="USD">USD - Amerikan Doları</option>
<option value="EUR">EUR - Euro</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>

View file

@ -24,6 +24,8 @@ import { mockSalesOrders } from '../../../mocks/mockSalesOrders'
import { BusinessParty, PaymentTerms } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { getPaymentTermsText, getSaleOrderStatusText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
const SalesOrderForm: React.FC = () => {
const navigate = useNavigate()
@ -328,13 +330,11 @@ const SalesOrderForm: React.FC = () => {
}
className="w-full 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={SaleOrderStatusEnum.Draft}>Taslak</option>
<option value={SaleOrderStatusEnum.Confirmed}>Onaylandı</option>
<option value={SaleOrderStatusEnum.InProduction}>Üretimde</option>
<option value={SaleOrderStatusEnum.Ready}>Hazır</option>
<option value={SaleOrderStatusEnum.Shipped}>Kargoda</option>
<option value={SaleOrderStatusEnum.Delivered}>Teslim Edildi</option>
<option value={SaleOrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(SaleOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getSaleOrderStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -684,9 +684,11 @@ const SalesOrderForm: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="w-full 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="TRY">TRY - Türk Lirası</option>
<option value="USD">USD - ABD Doları</option>
<option value="EUR">EUR - Euro</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -746,11 +748,11 @@ const SalesOrderForm: React.FC = () => {
className="w-full 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="">Seçin...</option>
<option value="NET30">30 Gün Vadeli</option>
<option value="NET60">60 Gün Vadeli</option>
<option value="NET90">90 Gün Vadeli</option>
<option value="COD">Kapıda Ödeme</option>
<option value="PREPAID">Peşin</option>
{Object.values(PaymentTerms).map((term) => (
<option key={term} value={term}>
{getPaymentTermsText(term)}
</option>
))}
</select>
</div>
</div>

View file

@ -14,6 +14,7 @@ import { mockEmployees } from '../../../mocks/mockEmployees'
import { Team, TeamMember, TeamRoleEnum } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { getTeamRoleText } from '@/utils/erp'
const SalesTeamCreate: React.FC = () => {
const navigate = useNavigate()
@ -308,9 +309,11 @@ const SalesTeamCreate: React.FC = () => {
onChange={(e) => updateMember(index, 'role', e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={TeamRoleEnum.Member}>Üye</option>
<option value={TeamRoleEnum.Lead}>Takım Lideri</option>
<option value={TeamRoleEnum.Manager}>Yönetici</option>
{Object.values(TeamRoleEnum).map((role) => (
<option key={role} value={role}>
{getTeamRoleText(role)}
</option>
))}
</select>
</div>
</div>

View file

@ -15,6 +15,7 @@ import { mockEmployees } from '../../../mocks/mockEmployees'
import { Team, TeamMember, TeamRoleEnum } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { getTeamRoleText } from '@/utils/erp'
const SalesTeamEdit: React.FC = () => {
const navigate = useNavigate()
@ -358,9 +359,11 @@ const SalesTeamEdit: React.FC = () => {
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value={TeamRoleEnum.Member}>Üye</option>
<option value={TeamRoleEnum.Lead}>Takım Lideri</option>
<option value={TeamRoleEnum.Manager}>Yönetici</option>
{Object.values(TeamRoleEnum).map((role) => (
<option key={role} value={role}>
{getTeamRoleText(role)}
</option>
))}
</select>
</div>
</div>

View file

@ -323,7 +323,7 @@ export function ForumView({
: 'hover:text-blue-600 cursor-pointer'
}`}
>
Forum
<h2 className="text-2xl font-bold text-gray-900">Forum</h2>
</button>
{selectedCategory && (
<>

View file

@ -1,16 +1,17 @@
import React, { useState, useEffect } from "react";
import { FaSave, FaTimes } from "react-icons/fa";
import { HrCostCenter, CostCenterType } from "../../../types/hr";
import { mockEmployees } from "../../../mocks/mockEmployees";
import { mockCostCenters } from "../../../mocks/mockCostCenters";
import { getCostCenterTypeText } from "../../../utils/erp";
import React, { useState, useEffect } from 'react'
import { FaSave, FaTimes } from 'react-icons/fa'
import { HrCostCenter, CostCenterType } from '../../../types/hr'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { mockCostCenters } from '../../../mocks/mockCostCenters'
import { getCostCenterTypeText } from '../../../utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface CostCenterFormModalProps {
isOpen: boolean;
onClose: () => void;
onSave: (costCenter: Partial<HrCostCenter>) => void;
costCenter?: HrCostCenter;
title: string;
isOpen: boolean
onClose: () => void
onSave: (costCenter: Partial<HrCostCenter>) => void
costCenter?: HrCostCenter
title: string
}
const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
@ -21,55 +22,55 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
title,
}) => {
const [formData, setFormData] = useState({
costCenterCode: "",
name: "",
description: "",
costCenterCode: '',
name: '',
description: '',
costCenterType: CostCenterType.Standard,
responsibleEmployeeId: "",
parentCostCenterId: "",
responsibleEmployeeId: '',
parentCostCenterId: '',
budgetedAmount: 0,
actualAmount: 0,
currency: "TRY",
fiscalYear: "2025",
currency: 'TRY',
fiscalYear: '2025',
isActive: true,
});
})
useEffect(() => {
if (costCenter) {
setFormData({
costCenterCode: costCenter.code,
name: costCenter.name,
description: costCenter.description || "",
description: costCenter.description || '',
costCenterType: costCenter.costCenterType,
responsibleEmployeeId: costCenter.responsibleEmployeeId || "",
parentCostCenterId: costCenter.parentCostCenterId || "",
responsibleEmployeeId: costCenter.responsibleEmployeeId || '',
parentCostCenterId: costCenter.parentCostCenterId || '',
budgetedAmount: costCenter.budgetedAmount,
actualAmount: costCenter.actualAmount,
currency: costCenter.currency,
fiscalYear: costCenter.fiscalYear,
isActive: costCenter.isActive,
});
})
} else {
setFormData({
costCenterCode: "",
name: "",
description: "",
costCenterCode: '',
name: '',
description: '',
costCenterType: CostCenterType.Standard,
responsibleEmployeeId: "",
parentCostCenterId: "",
responsibleEmployeeId: '',
parentCostCenterId: '',
budgetedAmount: 0,
actualAmount: 0,
currency: "TRY",
fiscalYear: "2025",
currency: 'TRY',
fiscalYear: '2025',
isActive: true,
});
})
}
}, [costCenter]);
}, [costCenter])
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSave(formData);
};
e.preventDefault()
onSave(formData)
}
return (
isOpen && (
@ -77,10 +78,7 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
<div className="bg-white rounded-lg p-3 w-full max-w-lg max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between mb-3">
<h2 className="text-base font-bold text-gray-900">{title}</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600"
>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
<FaTimes className="w-5 h-5" />
</button>
</div>
@ -94,9 +92,7 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
<input
type="text"
value={formData.costCenterCode}
onChange={(e) =>
setFormData({ ...formData, costCenterCode: e.target.value })
}
onChange={(e) => setFormData({ ...formData, costCenterCode: e.target.value })}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
@ -109,9 +105,7 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
<input
type="text"
value={formData.name}
onChange={(e) =>
setFormData({ ...formData, name: e.target.value })
}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
@ -119,14 +113,10 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
ıklama
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">ıklama</label>
<textarea
value={formData.description}
onChange={(e) =>
setFormData({ ...formData, description: e.target.value })
}
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
rows={2}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
@ -206,15 +196,11 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Mali Yıl
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Mali Yıl</label>
<input
type="text"
value={formData.fiscalYear}
onChange={(e) =>
setFormData({ ...formData, fiscalYear: e.target.value })
}
onChange={(e) => setFormData({ ...formData, fiscalYear: e.target.value })}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
@ -222,9 +208,7 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Bütçe Tutarı
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Bütçe Tutarı</label>
<input
type="number"
value={formData.budgetedAmount}
@ -256,19 +240,17 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Para Birimi
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Para Birimi</label>
<select
value={formData.currency}
onChange={(e) =>
setFormData({ ...formData, currency: e.target.value })
}
onChange={(e) => setFormData({ ...formData, currency: e.target.value })}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
@ -277,9 +259,7 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
<input
type="checkbox"
checked={formData.isActive}
onChange={(e) =>
setFormData({ ...formData, isActive: e.target.checked })
}
onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label className="ml-2 block text-sm text-gray-900">Aktif</label>
@ -305,7 +285,7 @@ const CostCenterFormModal: React.FC<CostCenterFormModalProps> = ({
</div>
</div>
)
);
};
)
}
export default CostCenterFormModal;
export default CostCenterFormModal

View file

@ -808,9 +808,11 @@ const Degree360Evaluation: React.FC = () => {
className="border border-gray-300 rounded-md px-2.5 py-1 text-sm"
>
<option value="all">Tüm Durumlar</option>
<option value={CampaignStatusEnum.Draft}>Taslak</option>
<option value={CampaignStatusEnum.Active}>Aktif</option>
<option value={CampaignStatusEnum.Completed}>Tamamlandı</option>
{Object.values(CampaignStatusEnum).map((status) => (
<option key={status} value={status}>
{getCampaignStatusText(status)}
</option>
))}
</select>
<select
@ -834,7 +836,7 @@ const Degree360Evaluation: React.FC = () => {
<option value="all">Tüm Personel</option>
{mockEmployees.map((employee) => (
<option key={employee.id} value={employee.id}>
{employee.firstName} {employee.lastName}
{employee.fullName}
</option>
))}
</select>
@ -887,11 +889,11 @@ const Degree360Evaluation: React.FC = () => {
className="border border-gray-300 rounded-md px-2.5 py-1 text-sm"
>
<option value="all">Tüm Durumlar</option>
<option value={ParticipantStatusEnum.Invited}>Davet Edildi</option>
<option value={ParticipantStatusEnum.Started}>Başladı</option>
<option value={ParticipantStatusEnum.Completed}>Tamamlandı</option>
<option value={ParticipantStatusEnum.Expired}>Süresi Dolmuş</option>
<option value={ParticipantStatusEnum.Declined}>Reddedildi</option>
{Object.values(ParticipantStatusEnum).map((status) => (
<option key={status} value={status}>
{getParticipantStatusText(status)}
</option>
))}
</select>
<select

View file

@ -7,6 +7,7 @@ import {
QuestionTypeEnum,
HrQuestionOption,
AssessorTypeEnum,
getQuestionTypeText,
} from '../../../types/hr'
import DataTable, { Column } from '../../../components/common/DataTable'
import { mockEvaluation360Templates } from '../../../mocks/mockEvaluation360Templates'
@ -692,10 +693,11 @@ const Degree360Templates: React.FC = () => {
}
className="w-full border border-gray-300 rounded-md px-3 py-1.5 text-sm focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
>
<option value={QuestionTypeEnum.Rating}>Puanlama</option>
<option value={QuestionTypeEnum.MultipleChoice}>Çoktan Seçmeli</option>
<option value={QuestionTypeEnum.Text}>Metin</option>
<option value={QuestionTypeEnum.YesNo}>Evet/Hayır</option>
{Object.values(QuestionTypeEnum).map((type) => (
<option key={type} value={type}>
{getQuestionTypeText(type)}
</option>
))}
</select>
</div>

View file

@ -82,11 +82,11 @@ const EmployeeCards: React.FC = () => {
className="px-2 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 Durumlar</option>
<option value={EmployeeStatusEnum.Active}>Aktif</option>
<option value={EmployeeStatusEnum.Inactive}>Pasif</option>
<option value={EmployeeStatusEnum.OnLeave}>İzinli</option>
<option value={EmployeeStatusEnum.Suspended}>Askıda</option>
<option value={EmployeeStatusEnum.Terminated}>İşten Çıkarılmış</option>
{Object.values(EmployeeStatusEnum).map((status) => (
<option key={status} value={status}>
{getEmployeeStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -26,6 +26,15 @@ import {
import { mockEmployees } from '../../../mocks/mockEmployees'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { mockCurrencies } from '@/mocks/mockCurrencies'
import {
getEmployeeStatusText,
getEmploymentTypeText,
getFrequencyUnitText,
getGenderText,
getMaritalStatusText,
} from '@/utils/erp'
import { FrequencyUnitEnum } from '@/types/pm'
interface ValidationErrors {
[key: string]: string
@ -370,8 +379,11 @@ const EmployeeForm: React.FC = () => {
className="block w-full px-2 py-1 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Cinsiyet seçin</option>
<option value="MALE">Erkek</option>
<option value="FEMALE">Kadın</option>
{Object.values(GenderEnum).map((gender) => (
<option key={gender} value={gender}>
{getGenderText(gender)}
</option>
))}
</select>
</div>
@ -385,10 +397,11 @@ const EmployeeForm: React.FC = () => {
className="block w-full px-2 py-1 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Medeni durum seçin</option>
<option value="SINGLE">Bekar</option>
<option value="MARRIED">Evli</option>
<option value="DIVORCED">Boşanmış</option>
<option value="WIDOWED">Dul</option>
{Object.values(MaritalStatusEnum).map((status) => (
<option key={status} value={status}>
{getMaritalStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -508,11 +521,11 @@ const EmployeeForm: React.FC = () => {
}`}
>
<option value="">Tip seçin</option>
<option value="FULL_TIME">Tam Zamanlı</option>
<option value="PART_TIME">Yarı Zamanlı</option>
<option value="CONTRACT">Sözleşmeli</option>
<option value="INTERN">Stajyer</option>
<option value="TEMPORARY">Geçici</option>
{Object.values(EmploymentTypeEnum).map((type) => (
<option key={type} value={type}>
{getEmploymentTypeText(type)}
</option>
))}
</select>
{errors.employmentType && (
<p className="mt-1 text-sm text-red-600">{errors.employmentType}</p>
@ -660,9 +673,11 @@ const EmployeeForm: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="block w-full px-2 py-1 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="TRY">Türk Lirası (TRY)</option>
<option value="USD">Amerikan Doları (USD)</option>
<option value="EUR">Euro (EUR)</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -676,9 +691,15 @@ const EmployeeForm: React.FC = () => {
className="block w-full px-2 py-1 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="">Grup seçin</option>
<option value="MONTHLY">Aylık</option>
<option value="WEEKLY">Haftalık</option>
<option value="HOURLY">Saatlik</option>
<option value={FrequencyUnitEnum.Weeks}>
{getFrequencyUnitText(FrequencyUnitEnum.Weeks)}
</option>
<option value={FrequencyUnitEnum.Months}>
{getFrequencyUnitText(FrequencyUnitEnum.Months)}
</option>
<option value={FrequencyUnitEnum.Hours}>
{getFrequencyUnitText(FrequencyUnitEnum.Hours)}
</option>
</select>
</div>
</div>
@ -748,10 +769,11 @@ const EmployeeForm: React.FC = () => {
onChange={(e) => handleInputChange('employeeStatus', e.target.value)}
className="block w-full px-2 py-1 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="ACTIVE">Aktif</option>
<option value="INACTIVE">Pasif</option>
<option value="ON_LEAVE">İzinli</option>
<option value="TERMINATED">İşten Ayrılmış</option>
{Object.values(EmployeeStatusEnum).map((status) => (
<option key={status} value={status}>
{getEmployeeStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -34,11 +34,12 @@ import {
} from '../../../utils/erp'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { mockDepartments } from '@/mocks/mockDepartments'
const EmployeeList: React.FC = () => {
const [searchTerm, setSearchTerm] = useState('')
const [filterStatus, setFilterStatus] = useState('all')
const [filterDepartment, setFilterDepartment] = useState('all')
const [filterDepartment, setFilterDepartment] = useState('')
const [showFilters, setShowFilters] = useState(false)
const [viewMode, setViewMode] = useState<'list' | 'cards'>('list')
@ -204,11 +205,11 @@ const EmployeeList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-2 py-1 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={EmployeeStatusEnum.Active}>Aktif</option>
<option value={EmployeeStatusEnum.Inactive}>Pasif</option>
<option value={EmployeeStatusEnum.OnLeave}>İzinli</option>
<option value={EmployeeStatusEnum.Suspended}>Askıda</option>
<option value={EmployeeStatusEnum.Terminated}>İşten Çıkarıldı</option>
{Object.values(EmployeeStatusEnum).map((status) => (
<option key={status} value={status}>
{getEmployeeStatusText(status)}
</option>
))}
</select>
</div>
@ -220,10 +221,11 @@ const EmployeeList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-2 py-1 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value="IT">Bilgi İşlem</option>
<option value="PROC">Satınalma</option>
<option value="PROD">Üretim</option>
<option value="HR">İnsan Kaynakları</option>
{mockDepartments.map((dept) => (
<option key={dept.id} value={dept.id}>
{dept.name}
</option>
))}
</select>
</div>

View file

@ -1,14 +1,16 @@
import React, { useState, useEffect } from "react";
import { FaSave, FaTimes, FaPlus, FaTrash } from "react-icons/fa";
import { HrJobPosition, JobLevelEnum } from "../../../types/hr";
import { mockDepartments } from "../../../mocks/mockDepartments";
import React, { useState, useEffect } from 'react'
import { FaSave, FaTimes, FaPlus, FaTrash } from 'react-icons/fa'
import { HrJobPosition, JobLevelEnum } from '../../../types/hr'
import { mockDepartments } from '../../../mocks/mockDepartments'
import { getJobLevelText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
interface JobPositionFormModalProps {
isOpen: boolean;
onClose: () => void;
onSave: (position: Partial<HrJobPosition>) => void;
position?: HrJobPosition;
title: string;
isOpen: boolean
onClose: () => void
onSave: (position: Partial<HrJobPosition>) => void
position?: HrJobPosition
title: string
}
const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
@ -19,31 +21,31 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
title,
}) => {
const [formData, setFormData] = useState({
positionCode: "",
title: "",
description: "",
departmentId: "",
positionCode: '',
title: '',
description: '',
departmentId: '',
level: JobLevelEnum.Entry,
minSalary: 0,
maxSalary: 0,
currency: "TRY",
currency: 'TRY',
requiredSkills: [] as string[],
responsibilities: [] as string[],
qualifications: [] as string[],
isActive: true,
});
})
const [errors, setErrors] = useState<Record<string, string>>({});
const [skillInput, setSkillInput] = useState("");
const [responsibilityInput, setResponsibilityInput] = useState("");
const [qualificationInput, setQualificationInput] = useState("");
const [errors, setErrors] = useState<Record<string, string>>({})
const [skillInput, setSkillInput] = useState('')
const [responsibilityInput, setResponsibilityInput] = useState('')
const [qualificationInput, setQualificationInput] = useState('')
useEffect(() => {
if (position) {
setFormData({
positionCode: position.code,
title: position.name,
description: position.description || "",
description: position.description || '',
departmentId: position.departmentId,
level: position.level,
minSalary: position.minSalary,
@ -53,97 +55,91 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
responsibilities: [...(position.responsibilities || [])],
qualifications: [...(position.qualifications || [])],
isActive: position.isActive,
});
})
} else {
setFormData({
positionCode: "",
title: "",
description: "",
departmentId: "",
positionCode: '',
title: '',
description: '',
departmentId: '',
level: JobLevelEnum.Entry,
minSalary: 0,
maxSalary: 0,
currency: "TRY",
currency: 'TRY',
requiredSkills: [],
responsibilities: [],
qualifications: [],
isActive: true,
});
})
}
setErrors({});
setSkillInput("");
setResponsibilityInput("");
setQualificationInput("");
}, [position, isOpen]);
setErrors({})
setSkillInput('')
setResponsibilityInput('')
setQualificationInput('')
}, [position, isOpen])
const validateForm = (): boolean => {
const newErrors: Record<string, string> = {};
const newErrors: Record<string, string> = {}
if (!formData.positionCode.trim()) {
newErrors.positionCode = "Pozisyon kodu zorunludur";
newErrors.positionCode = 'Pozisyon kodu zorunludur'
}
if (!formData.title.trim()) {
newErrors.title = "Pozisyon adı zorunludur";
newErrors.title = 'Pozisyon adı zorunludur'
}
if (!formData.departmentId) {
newErrors.departmentId = "Departman seçimi zorunludur";
newErrors.departmentId = 'Departman seçimi zorunludur'
}
if (formData.minSalary < 0) {
newErrors.minSalary = "Minimum maaş negatif olamaz";
newErrors.minSalary = 'Minimum maaş negatif olamaz'
}
if (formData.maxSalary < 0) {
newErrors.maxSalary = "Maksimum maaş negatif olamaz";
newErrors.maxSalary = 'Maksimum maaş negatif olamaz'
}
if (formData.maxSalary < formData.minSalary) {
newErrors.maxSalary = "Maksimum maaş minimum maaştan düşük olamaz";
newErrors.maxSalary = 'Maksimum maaş minimum maaştan düşük olamaz'
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
if (validateForm()) {
onSave(formData);
onClose();
onSave(formData)
onClose()
}
};
}
const handleInputChange = (
field: string,
value: string | number | boolean | JobLevelEnum
) => {
const handleInputChange = (field: string, value: string | number | boolean | JobLevelEnum) => {
setFormData((prev) => ({
...prev,
[field]: value,
}));
};
}))
}
const addSkill = () => {
if (
skillInput.trim() &&
!formData.requiredSkills.includes(skillInput.trim())
) {
if (skillInput.trim() && !formData.requiredSkills.includes(skillInput.trim())) {
setFormData((prev) => ({
...prev,
requiredSkills: [...prev.requiredSkills, skillInput.trim()],
}));
setSkillInput("");
}))
setSkillInput('')
}
};
}
const removeSkill = (index: number) => {
setFormData((prev) => ({
...prev,
requiredSkills: prev.requiredSkills.filter((_, i) => i !== index),
}));
};
}))
}
const addResponsibility = () => {
if (
@ -152,53 +148,44 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
) {
setFormData((prev) => ({
...prev,
responsibilities: [
...prev.responsibilities,
responsibilityInput.trim(),
],
}));
setResponsibilityInput("");
responsibilities: [...prev.responsibilities, responsibilityInput.trim()],
}))
setResponsibilityInput('')
}
};
}
const removeResponsibility = (index: number) => {
setFormData((prev) => ({
...prev,
responsibilities: prev.responsibilities.filter((_, i) => i !== index),
}));
};
}))
}
const addQualification = () => {
if (
qualificationInput.trim() &&
!formData.qualifications.includes(qualificationInput.trim())
) {
if (qualificationInput.trim() && !formData.qualifications.includes(qualificationInput.trim())) {
setFormData((prev) => ({
...prev,
qualifications: [...prev.qualifications, qualificationInput.trim()],
}));
setQualificationInput("");
}))
setQualificationInput('')
}
};
}
const removeQualification = (index: number) => {
setFormData((prev) => ({
...prev,
qualifications: prev.qualifications.filter((_, i) => i !== index),
}));
};
}))
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between p-3 border-b">
<h2 className="text-xl font-bold text-gray-900">{title}</h2>
<button
onClick={onClose}
className="p-1 hover:bg-gray-100 rounded-full"
>
<button onClick={onClose} className="p-1 hover:bg-gray-100 rounded-full">
<FaTimes className="w-5 h-5" />
</button>
</div>
@ -214,47 +201,37 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
autoFocus
type="text"
value={formData.positionCode}
onChange={(e) =>
handleInputChange("positionCode", e.target.value)
}
onChange={(e) => handleInputChange('positionCode', e.target.value)}
className={`w-full px-2 py-1 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.positionCode ? "border-red-500" : "border-gray-300"
errors.positionCode ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Örn: DEV-001"
/>
{errors.positionCode && (
<p className="text-red-500 text-sm mt-1">
{errors.positionCode}
</p>
<p className="text-red-500 text-sm mt-1">{errors.positionCode}</p>
)}
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Pozisyon Adı *
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Pozisyon Adı *</label>
<input
type="text"
value={formData.title}
onChange={(e) => handleInputChange("title", e.target.value)}
onChange={(e) => handleInputChange('title', e.target.value)}
className={`w-full px-2 py-1 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.title ? "border-red-500" : "border-gray-300"
errors.title ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Örn: Software Developer"
/>
{errors.title && (
<p className="text-red-500 text-sm mt-1">{errors.title}</p>
)}
{errors.title && <p className="text-red-500 text-sm mt-1">{errors.title}</p>}
</div>
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
ıklama
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">ıklama</label>
<textarea
value={formData.description}
onChange={(e) => handleInputChange("description", e.target.value)}
onChange={(e) => handleInputChange('description', e.target.value)}
rows={2}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Pozisyon açıklaması..."
@ -263,16 +240,12 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Departman *
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Departman *</label>
<select
value={formData.departmentId}
onChange={(e) =>
handleInputChange("departmentId", e.target.value)
}
onChange={(e) => handleInputChange('departmentId', e.target.value)}
className={`w-full px-2 py-1 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.departmentId ? "border-red-500" : "border-gray-300"
errors.departmentId ? 'border-red-500' : 'border-gray-300'
}`}
>
<option value="">Departman seçin</option>
@ -283,33 +256,22 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
))}
</select>
{errors.departmentId && (
<p className="text-red-500 text-sm mt-1">
{errors.departmentId}
</p>
<p className="text-red-500 text-sm mt-1">{errors.departmentId}</p>
)}
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Seviye
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Seviye</label>
<select
value={formData.level}
onChange={(e) =>
handleInputChange("level", e.target.value as JobLevelEnum)
}
onChange={(e) => handleInputChange('level', e.target.value as JobLevelEnum)}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value={JobLevelEnum.Entry}>Giriş Seviyesi</option>
<option value={JobLevelEnum.Junior}>Junior</option>
<option value={JobLevelEnum.Mid}>Orta Seviye</option>
<option value={JobLevelEnum.Senior}>Senior</option>
<option value={JobLevelEnum.Lead}>Lider</option>
<option value={JobLevelEnum.Manager}>Yönetici</option>
<option value={JobLevelEnum.Director}>Direktör</option>
<option value={JobLevelEnum.Executive}>
Üst Düzey Yönetici
</option>
{Object.values(JobLevelEnum).map((level) => (
<option key={level} value={level}>
{getJobLevelText(level)}
</option>
))}
</select>
</div>
</div>
@ -317,23 +279,17 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
{/* Salary Information */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Minimum Maaş *
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Minimum Maaş *</label>
<input
type="number"
value={formData.minSalary}
onChange={(e) =>
handleInputChange("minSalary", Number(e.target.value))
}
onChange={(e) => handleInputChange('minSalary', Number(e.target.value))}
className={`w-full px-2 py-1 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.minSalary ? "border-red-500" : "border-gray-300"
errors.minSalary ? 'border-red-500' : 'border-gray-300'
}`}
min="0"
/>
{errors.minSalary && (
<p className="text-red-500 text-sm mt-1">{errors.minSalary}</p>
)}
{errors.minSalary && <p className="text-red-500 text-sm mt-1">{errors.minSalary}</p>}
</div>
<div>
@ -343,31 +299,27 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
<input
type="number"
value={formData.maxSalary}
onChange={(e) =>
handleInputChange("maxSalary", Number(e.target.value))
}
onChange={(e) => handleInputChange('maxSalary', Number(e.target.value))}
className={`w-full px-2 py-1 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.maxSalary ? "border-red-500" : "border-gray-300"
errors.maxSalary ? 'border-red-500' : 'border-gray-300'
}`}
min="0"
/>
{errors.maxSalary && (
<p className="text-red-500 text-sm mt-1">{errors.maxSalary}</p>
)}
{errors.maxSalary && <p className="text-red-500 text-sm mt-1">{errors.maxSalary}</p>}
</div>
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Para Birimi
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Para Birimi</label>
<select
value={formData.currency}
onChange={(e) => handleInputChange("currency", e.target.value)}
onChange={(e) => handleInputChange('currency', e.target.value)}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
@ -382,9 +334,7 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
type="text"
value={skillInput}
onChange={(e) => setSkillInput(e.target.value)}
onKeyPress={(e) =>
e.key === "Enter" && (e.preventDefault(), addSkill())
}
onKeyPress={(e) => e.key === 'Enter' && (e.preventDefault(), addSkill())}
className="flex-1 px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Yetenek ekleyin..."
/>
@ -417,17 +367,13 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
{/* Responsibilities */}
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Sorumluluklar
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Sorumluluklar</label>
<div className="flex gap-2 mb-2">
<input
type="text"
value={responsibilityInput}
onChange={(e) => setResponsibilityInput(e.target.value)}
onKeyPress={(e) =>
e.key === "Enter" && (e.preventDefault(), addResponsibility())
}
onKeyPress={(e) => e.key === 'Enter' && (e.preventDefault(), addResponsibility())}
className="flex-1 px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Sorumluluk ekleyin..."
/>
@ -445,9 +391,7 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
key={index}
className="flex items-center justify-between p-2 bg-green-50 rounded-md text-sm"
>
<span className="text-green-800 text-sm">
{responsibility}
</span>
<span className="text-green-800 text-sm">{responsibility}</span>
<button
type="button"
onClick={() => removeResponsibility(index)}
@ -462,17 +406,13 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
{/* Qualifications */}
<div>
<label className="block text-xs font-medium text-gray-700 mb-1">
Nitelikler
</label>
<label className="block text-xs font-medium text-gray-700 mb-1">Nitelikler</label>
<div className="flex gap-2 mb-2">
<input
type="text"
value={qualificationInput}
onChange={(e) => setQualificationInput(e.target.value)}
onKeyPress={(e) =>
e.key === "Enter" && (e.preventDefault(), addQualification())
}
onKeyPress={(e) => e.key === 'Enter' && (e.preventDefault(), addQualification())}
className="flex-1 px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Nitelik ekleyin..."
/>
@ -490,9 +430,7 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
key={index}
className="flex items-center justify-between p-2 bg-purple-50 rounded-md text-sm"
>
<span className="text-purple-800 text-sm">
{qualification}
</span>
<span className="text-purple-800 text-sm">{qualification}</span>
<button
type="button"
onClick={() => removeQualification(index)}
@ -511,13 +449,10 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
type="checkbox"
id="isActive"
checked={formData.isActive}
onChange={(e) => handleInputChange("isActive", e.target.checked)}
onChange={(e) => handleInputChange('isActive', e.target.checked)}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label
htmlFor="isActive"
className="ml-2 block text-sm text-gray-900"
>
<label htmlFor="isActive" className="ml-2 block text-sm text-gray-900">
Aktif pozisyon
</label>
</div>
@ -543,7 +478,7 @@ const JobPositionFormModal: React.FC<JobPositionFormModalProps> = ({
</form>
</div>
</div>
);
};
)
}
export default JobPositionFormModal;
export default JobPositionFormModal

View file

@ -336,9 +336,7 @@ const JobPositions: React.FC = () => {
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
<div>
<h2 className="text-2xl font-bold text-gray-900">İş Pozisyonları</h2>
<p className="text-gray-600">
Şirket pozisyonları ve tanımları yönetimi
</p>
<p className="text-gray-600">Şirket pozisyonları ve tanımları yönetimi</p>
</div>
<div className="flex items-center gap-3">
{/* View Toggle */}
@ -442,14 +440,11 @@ const JobPositions: React.FC = () => {
className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 min-w-0 sm:min-w-[160px]"
>
<option value="all">Tüm Seviyeler</option>
<option value={JobLevelEnum.Entry}>Giriş Seviyesi</option>
<option value={JobLevelEnum.Junior}>Junior</option>
<option value={JobLevelEnum.Mid}>Orta Seviye</option>
<option value={JobLevelEnum.Senior}>Senior</option>
<option value={JobLevelEnum.Lead}>Lider</option>
<option value={JobLevelEnum.Manager}>Yönetici</option>
<option value={JobLevelEnum.Director}>Direktör</option>
<option value={JobLevelEnum.Executive}>Üst Düzey Yönetici</option>
{Object.values(JobLevelEnum).map((level) => (
<option key={level} value={level}>
{getJobLevelText(level)}
</option>
))}
</select>
<select

View file

@ -506,10 +506,11 @@ const LeaveManagement: React.FC = () => {
className="px-3 py-1.5 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="all">Tüm Durumlar</option>
<option value={LeaveStatusEnum.Pending}>Beklemede</option>
<option value={LeaveStatusEnum.Approved}>Onaylandı</option>
<option value={LeaveStatusEnum.Rejected}>Reddedildi</option>
<option value={LeaveStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(LeaveStatusEnum).map((status) => (
<option key={status} value={status}>
{getLeaveStatusText(status)}
</option>
))}
</select>
<select
@ -518,14 +519,11 @@ const LeaveManagement: React.FC = () => {
className="px-3 py-1.5 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="all">Tüm İzin Türleri</option>
<option value={LeaveTypeEnum.Annual}>Yıllık İzin</option>
<option value={LeaveTypeEnum.Sick}>Hastalık İzni</option>
<option value={LeaveTypeEnum.Maternity}>Doğum İzni</option>
<option value={LeaveTypeEnum.Paternity}>Babalık İzni</option>
<option value={LeaveTypeEnum.Personal}>Kişisel İzin</option>
<option value={LeaveTypeEnum.Emergency}>Acil Durum İzni</option>
<option value={LeaveTypeEnum.Study}>Eğitim İzni</option>
<option value={LeaveTypeEnum.Unpaid}>Ücretsiz İzin</option>
{Object.values(LeaveTypeEnum).map((type) => (
<option key={type} value={type}>
{getLeaveTypeText(type)}
</option>
))}
</select>
<select
@ -591,14 +589,11 @@ const LeaveManagement: React.FC = () => {
}
className="w-full 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={LeaveTypeEnum.Annual}>Yıllık İzin</option>
<option value={LeaveTypeEnum.Sick}>Hastalık İzni</option>
<option value={LeaveTypeEnum.Maternity}>Doğum İzni</option>
<option value={LeaveTypeEnum.Paternity}>Babalık İzni</option>
<option value={LeaveTypeEnum.Personal}>Kişisel İzin</option>
<option value={LeaveTypeEnum.Emergency}>Acil Durum İzni</option>
<option value={LeaveTypeEnum.Study}>Eğitim İzni</option>
<option value={LeaveTypeEnum.Unpaid}>Ücretsiz İzin</option>
{Object.values(LeaveTypeEnum).map((type) => (
<option key={type} value={type}>
{getLeaveTypeText(type)}
</option>
))}
</select>
</div>
@ -933,14 +928,11 @@ const LeaveManagement: React.FC = () => {
}
className="w-full 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={LeaveTypeEnum.Annual}>Yıllık İzin</option>
<option value={LeaveTypeEnum.Sick}>Hastalık İzni</option>
<option value={LeaveTypeEnum.Maternity}>Doğum İzni</option>
<option value={LeaveTypeEnum.Paternity}>Babalık İzni</option>
<option value={LeaveTypeEnum.Personal}>Kişisel İzin</option>
<option value={LeaveTypeEnum.Emergency}>Acil Durum İzni</option>
<option value={LeaveTypeEnum.Study}>Eğitim İzni</option>
<option value={LeaveTypeEnum.Unpaid}>Ücretsiz İzin</option>
{Object.values(LeaveStatusEnum).map((status) => (
<option key={status} value={status}>
{getLeaveStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -544,9 +544,11 @@ const OvertimeManagement: React.FC = () => {
className="border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tüm Durumlar</option>
<option value={LeaveStatusEnum.Pending}>Beklemede</option>
<option value={LeaveStatusEnum.Approved}>Onaylı</option>
<option value={LeaveStatusEnum.Rejected}>Reddedildi</option>
{Object.values(LeaveStatusEnum).map((status) => (
<option key={status} value={status}>
{getLeaveStatusText(status)}
</option>
))}
</select>
<select

View file

@ -515,11 +515,11 @@ const PayrollManagement: React.FC = () => {
className="px-3 py-1.5 border border-gray-300 text-sm rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="all">Tüm Durumlar</option>
<option value={PayrollStatusEnum.Draft}>Taslak</option>
<option value={PayrollStatusEnum.Calculated}>Hesaplandı</option>
<option value={PayrollStatusEnum.Approved}>Onaylandı</option>
<option value={PayrollStatusEnum.Paid}>Ödendi</option>
<option value={PayrollStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(PayrollStatusEnum).map((status) => (
<option key={status} value={status}>
{getPayrollStatusText(status)}
</option>
))}
</select>
<select

View file

@ -137,12 +137,21 @@ const ChangeNotificationStatusModal: React.FC<ChangeNotificationStatusModalProps
errors.status ? 'border-red-500' : 'border-gray-300'
}`}
>
<option value={NotificationStatusEnum.Open}>ık</option>
<option value={NotificationStatusEnum.Assigned}>Atandı</option>
<option value={NotificationStatusEnum.InProgress}>Devam Ediyor</option>
<option value={NotificationStatusEnum.Resolved}>Çözüldü</option>
<option value={NotificationStatusEnum.Closed}>Kapatıldı</option>
<option value={NotificationStatusEnum.Rejected}>Reddedildi</option>
{Object.keys(NotificationStatusEnum).map((key) => (
<option
key={key}
value={NotificationStatusEnum[key as keyof typeof NotificationStatusEnum]}
>
{getNotificationStatusText(
NotificationStatusEnum[key as keyof typeof NotificationStatusEnum],
)}
</option>
))}
{Object.values(NotificationStatusEnum).map((status) => (
<option key={status} value={status}>
{getNotificationStatusText(status)}
</option>
))}
</select>
{errors.status && <p className="text-red-500 text-sm mt-1">{errors.status}</p>}
</div>

View file

@ -5,6 +5,7 @@ import { mockMaintenanceTeams } from '../../../mocks/mockMaintenanceTeams'
import { PmFaultNotification, WorkOrderTypeEnum } from '../../../types/pm'
import { MrpWorkOrder } from '../../../types/mrp'
import { PriorityEnum } from '../../../types/common'
import { getPriorityText, getWorkOrderTypeText } from '@/utils/erp'
interface CreateWorkOrderFromNotificationModalProps {
isOpen: boolean
@ -163,11 +164,11 @@ const CreateWorkOrderFromNotificationModal: React.FC<CreateWorkOrderFromNotifica
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkOrderTypeEnum.Preventive}>Önleyici Bakım</option>
<option value={WorkOrderTypeEnum.Corrective}>Düzeltici Bakım</option>
<option value={WorkOrderTypeEnum.Emergency}>Acil Müdahale</option>
<option value={WorkOrderTypeEnum.Inspection}>İnceleme</option>
<option value={WorkOrderTypeEnum.Calibration}>Kalibrasyon</option>
{Object.values(WorkOrderTypeEnum).map((type) => (
<option key={type} value={type}>
{getWorkOrderTypeText(type)}
</option>
))}
</select>
</div>
</div>
@ -180,10 +181,11 @@ const CreateWorkOrderFromNotificationModal: React.FC<CreateWorkOrderFromNotifica
onChange={(e) => handleInputChange('priority', e.target.value as PriorityEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>

View file

@ -8,7 +8,7 @@ import {
} from '../../../types/pm'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { PriorityEnum } from '../../../types/common'
import { getPriorityColor } from '../../../utils/erp'
import { getPriorityColor, getPriorityText } from '../../../utils/erp'
interface CreateWorkOrderModalProps {
isOpen: boolean
@ -243,10 +243,11 @@ const CreateWorkOrderModal: React.FC<CreateWorkOrderModalProps> = ({
onChange={(e) => handleCommonChange('priority', e.target.value as PriorityEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
<div>
@ -329,10 +330,11 @@ const CreateWorkOrderModal: React.FC<CreateWorkOrderModalProps> = ({
className="w-full px-2 py-1 text-sm border border-gray-300 rounded focus:ring-1 focus:ring-blue-500 focus:border-blue-500"
>
<option value="">Ortak ayarı kullan</option>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
<div>

View file

@ -9,6 +9,12 @@ import {
import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { PriorityEnum } from '../../../types/common'
import {
getCriticalityLevelText,
getFaultTypeText,
getNotificationStatusText,
getPriorityText,
} from '@/utils/erp'
interface EditFaultNotificationModalProps {
isOpen: boolean
@ -260,12 +266,11 @@ const EditFaultNotificationModal: React.FC<EditFaultNotificationModalProps> = ({
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={NotificationStatusEnum.Open}>ık</option>
<option value={NotificationStatusEnum.Assigned}>Atandı</option>
<option value={NotificationStatusEnum.InProgress}>Devam Ediyor</option>
<option value={NotificationStatusEnum.Resolved}>Çözüldü</option>
<option value={NotificationStatusEnum.Closed}>Kapatıldı</option>
<option value={NotificationStatusEnum.Rejected}>Reddedildi</option>
{Object.values(NotificationStatusEnum).map((status) => (
<option key={status} value={status}>
{getNotificationStatusText(status)}
</option>
))}
</select>
</div>
@ -294,14 +299,11 @@ const EditFaultNotificationModal: React.FC<EditFaultNotificationModalProps> = ({
onChange={(e) => handleInputChange('faultType', e.target.value as FaultTypeEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={FaultTypeEnum.Mechanical}>Mekanik</option>
<option value={FaultTypeEnum.Electrical}>Elektrik</option>
<option value={FaultTypeEnum.Hydraulic}>Hidrolik</option>
<option value={FaultTypeEnum.Pneumatic}>Pnömatik</option>
<option value={FaultTypeEnum.Software}>Yazılım</option>
<option value={FaultTypeEnum.Safety}>Güvenlik</option>
<option value={FaultTypeEnum.Performance}>Performans</option>
<option value={FaultTypeEnum.Other}>Diğer</option>
{Object.values(FaultTypeEnum).map((faultType) => (
<option key={faultType} value={faultType}>
{getFaultTypeText(faultType)}
</option>
))}
</select>
</div>
@ -312,10 +314,11 @@ const EditFaultNotificationModal: React.FC<EditFaultNotificationModalProps> = ({
onChange={(e) => handleInputChange('priority', e.target.value as PriorityEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
@ -328,10 +331,11 @@ const EditFaultNotificationModal: React.FC<EditFaultNotificationModalProps> = ({
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
</div>

View file

@ -10,6 +10,7 @@ import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { mockUnits } from '../../../mocks/mockUnits'
import { PriorityEnum } from '../../../types/common'
import { getFrequencyUnitText, getMaintenancePlanTypeText, getPriorityText } from '@/utils/erp'
interface EditMaintenancePlanModalProps {
isOpen: boolean
@ -154,10 +155,11 @@ const EditMaintenancePlanModal: React.FC<EditMaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={MaintenancePlanTypeEnum.Preventive}>Önleyici Bakım</option>
<option value={MaintenancePlanTypeEnum.Predictive}>Kestirimci Bakım</option>
<option value={MaintenancePlanTypeEnum.Corrective}>Düzeltici Bakım</option>
<option value={MaintenancePlanTypeEnum.Condition}>Durum Bazlı Bakım</option>
{Object.values(MaintenancePlanTypeEnum).map((type) => (
<option key={type} value={type}>
{getMaintenancePlanTypeText(type)}
</option>
))}
</select>
</div>
<div>
@ -168,10 +170,11 @@ const EditMaintenancePlanModal: React.FC<EditMaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
<div className="md:col-span-2">
@ -214,12 +217,11 @@ const EditMaintenancePlanModal: React.FC<EditMaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={FrequencyUnitEnum.Days}>Gün</option>
<option value={FrequencyUnitEnum.Weeks}>Hafta</option>
<option value={FrequencyUnitEnum.Months}>Ay</option>
<option value={FrequencyUnitEnum.Years}>Yıl</option>
<option value={FrequencyUnitEnum.Hours}>Saat</option>
<option value={FrequencyUnitEnum.Cycles}>Çevrim</option>
{Object.values(FrequencyUnitEnum).map((unit) => (
<option key={unit} value={unit}>
{getFrequencyUnitText(unit)}
</option>
))}
</select>
</div>
<div>

View file

@ -3,6 +3,7 @@ import { FaTimes, FaSave, FaPlus, FaMinus } from 'react-icons/fa'
import MultiSelectEmployee from '../../../components/common/MultiSelectEmployee'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { Team, TeamMember, TeamRoleEnum } from '../../../types/common'
import { getTeamRoleText } from '@/utils/erp'
interface EditTeamModalProps {
isOpen: boolean
@ -252,9 +253,13 @@ const EditTeamModal: React.FC<EditTeamModalProps> = ({ isOpen, onClose, onSave,
}
className="text-xs px-2 py-1 border border-gray-300 rounded"
>
<option value={TeamRoleEnum.Member}>Üye</option>
<option value={TeamRoleEnum.Lead}>Lider</option>
<option value={TeamRoleEnum.Specialist}>Uzman</option>
{Object.values(TeamRoleEnum)
.filter((a) => a !== TeamRoleEnum.Manager)
.map((role) => (
<option key={role} value={role}>
{getTeamRoleText(role)}
</option>
))}
</select>
</div>
</div>

View file

@ -7,6 +7,8 @@ import {
PmWorkCenterSpecification,
} from '../../../types/pm'
import { mockDepartments } from '../../../mocks/mockDepartments'
import { getCriticalityLevelText, getWorkCenterStatusText } from '@/utils/erp'
import { mockWorkCenterMachineTypes } from '@/mocks/mockWorkCenterMachineTypes'
interface EditWorkCenterModalProps {
isOpen: boolean
@ -138,14 +140,15 @@ const EditWorkCenterModal: React.FC<EditWorkCenterModalProps> = ({
<label className="block text-sm font-medium text-gray-700 mb-2">Makine Türü</label>
<select
name="machineType"
value={formData.machineType || 'Manual'}
value={formData.machineType?.id}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="Manual">Manuel</option>
<option value="CNC">CNC</option>
<option value="Automated">Otomatik</option>
<option value="Semi-Automated">Yarı Otomatik</option>
{mockWorkCenterMachineTypes.map((type) => (
<option key={type.id} value={type.id}>
{type.name}
</option>
))}
</select>
</div>
<div>
@ -290,10 +293,11 @@ const EditWorkCenterModal: React.FC<EditWorkCenterModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkCenterStatusEnum.Operational}>Operasyonel</option>
<option value={WorkCenterStatusEnum.UnderMaintenance}>Bakımda</option>
<option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option>
<option value={WorkCenterStatusEnum.Retired}>Emekli</option>
{Object.values(WorkCenterStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkCenterStatusText(status)}
</option>
))}
</select>
</div>
<div>
@ -306,10 +310,11 @@ const EditWorkCenterModal: React.FC<EditWorkCenterModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
<div>

View file

@ -12,6 +12,7 @@ import { mockMaintenanceTeams } from '../../../mocks/mockMaintenanceTeams'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { PriorityEnum } from '../../../types/common'
import { getPriorityText, getWorkOrderStatusText, getWorkOrderTypeText } from '@/utils/erp'
interface EditWorkOrderModalProps {
isOpen: boolean
@ -269,13 +270,11 @@ const EditWorkOrderModal: React.FC<EditWorkOrderModalProps> = ({
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={WorkOrderStatusEnum.Planned}>Planlandı</option>
<option value={WorkOrderStatusEnum.Released}>Serbest Bırakıldı</option>
<option value={WorkOrderStatusEnum.InProgress}>Devam Ediyor</option>
<option value={WorkOrderStatusEnum.OnHold}>Beklemede</option>
<option value={WorkOrderStatusEnum.Completed}>Tamamlandı</option>
<option value={WorkOrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(WorkOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkOrderStatusText(status)}
</option>
))}
</select>
</div>
@ -312,11 +311,11 @@ const EditWorkOrderModal: React.FC<EditWorkOrderModalProps> = ({
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkOrderTypeEnum.Preventive}>Önleyici</option>
<option value={WorkOrderTypeEnum.Corrective}>Düzeltici</option>
<option value={WorkOrderTypeEnum.Emergency}>Acil</option>
<option value={WorkOrderTypeEnum.Inspection}>İnceleme</option>
<option value={WorkOrderTypeEnum.Calibration}>Kalibrasyon</option>
{Object.values(WorkOrderTypeEnum).map((type) => (
<option key={type} value={type}>
{getWorkOrderTypeText(type)}
</option>
))}
</select>
</div>
@ -332,10 +331,11 @@ const EditWorkOrderModal: React.FC<EditWorkOrderModalProps> = ({
}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
</div>

View file

@ -254,12 +254,11 @@ const FaultNotifications: React.FC = () => {
onChange={(e) => setStatusFilter(e.target.value as NotificationStatusEnum | 'all')}
className="pl-10 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Durumlar</option>
<option value={NotificationStatusEnum.Open}>ık</option>
<option value={NotificationStatusEnum.Assigned}>Atandı</option>
<option value={NotificationStatusEnum.InProgress}>Devam Ediyor</option>
<option value={NotificationStatusEnum.Resolved}>Çözüldü</option>
<option value={NotificationStatusEnum.Closed}>Kapatıldı</option>
{Object.values(NotificationStatusEnum).map((status) => (
<option key={status} value={status}>
{getNotificationStatusText(status)}
</option>
))}
</select>
</div>
<div className="relative">
@ -269,10 +268,11 @@ const FaultNotifications: React.FC = () => {
className="pl-4 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Öncelikler</option>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
</div>

View file

@ -16,6 +16,7 @@ import {
getPriorityColor,
getWorkOrderStatusColor,
getWorkOrderStatusIcon,
getWorkOrderStatusText,
} from '../../../utils/erp'
import { Container } from '@/components/shared'
@ -312,10 +313,11 @@ const MaintenanceCalendar: React.FC = () => {
className="pl-9 pr-4 py-1.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
>
<option value="all">Tüm Durumlar</option>
<option value="scheduled">Planlanmış</option>
<option value={WorkOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={WorkOrderStatusEnum.InProgress}>Devam Ediyor</option>
<option value={WorkOrderStatusEnum.Completed}>Tamamlandı</option>
{Object.values(WorkOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkOrderStatusText(status)}
</option>
))}
</select>
</div>
<button

View file

@ -7,6 +7,7 @@ import {
PmMaintenancePlan,
} from '../../../types/pm'
import { PriorityEnum } from '../../../types/common'
import { getMaintenancePlanTypeText, getPriorityText } from '@/utils/erp'
interface MaintenancePlanModalProps {
isOpen: boolean
@ -123,10 +124,11 @@ const MaintenancePlanModal: React.FC<MaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={MaintenancePlanTypeEnum.Preventive}>Önleyici Bakım</option>
<option value={MaintenancePlanTypeEnum.Predictive}>Kestirimci Bakım</option>
<option value={MaintenancePlanTypeEnum.Corrective}>Düzeltici Bakım</option>
<option value={MaintenancePlanTypeEnum.Condition}>Durum Bazlı Bakım</option>
{Object.values(MaintenancePlanTypeEnum).map((type) => (
<option key={type} value={type}>
{getMaintenancePlanTypeText(type)}
</option>
))}
</select>
</div>
<div>
@ -137,10 +139,11 @@ const MaintenancePlanModal: React.FC<MaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
</div>

View file

@ -25,7 +25,7 @@ import PlanStatusChangeModal from './PlanStatusChangeModal'
import Widget from '../../../components/common/Widget'
import { PriorityEnum } from '../../../types/common'
import {
getFrequencyUnitText,
getFrequencyUnitTextByFrequency,
getMaintenancePlanTypeColor,
getMaintenancePlanTypeText,
getPriorityColor,
@ -194,11 +194,11 @@ const MaintenancePlans: React.FC = () => {
onChange={(e) => setTypeFilter(e.target.value as MaintenancePlanTypeEnum | 'all')}
className="pl-10 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Tipler</option>
<option value={MaintenancePlanTypeEnum.Preventive}>Önleyici</option>
<option value={MaintenancePlanTypeEnum.Corrective}>Düzeltici</option>
<option value={MaintenancePlanTypeEnum.Predictive}>Tahminsel</option>
<option value={MaintenancePlanTypeEnum.Condition}>Duruma Bağlı</option>
{Object.values(MaintenancePlanTypeEnum).map((type) => (
<option key={type} value={type}>
{getMaintenancePlanTypeText(type)}
</option>
))}
</select>
</div>
<div className="relative">
@ -313,7 +313,7 @@ const MaintenancePlans: React.FC = () => {
</td>
<td className="px-4 py-3 whitespace-nowrap">
<div className="text-sm text-gray-900">
{getFrequencyUnitText(plan.frequency, plan.frequencyUnit)}
{getFrequencyUnitTextByFrequency(plan.frequency, plan.frequencyUnit)}
</div>
<div className="text-xs text-gray-500">{plan.estimatedDuration} dakika</div>
</td>

View file

@ -187,9 +187,11 @@ const MaintenanceTeams: React.FC = () => {
className="pl-10 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Roller</option>
<option value={TeamRoleEnum.Lead}>Lider</option>
<option value={TeamRoleEnum.Specialist}>Uzman</option>
<option value={TeamRoleEnum.Member}>Üye</option>
{Object.values(TeamRoleEnum).map((role) => (
<option key={role} value={role}>
{getTeamRoleText(role)}
</option>
))}
</select>
</div>
<div className="relative">

View file

@ -274,10 +274,11 @@ const MaintenanceWorkOrders: React.FC = () => {
className="pl-10 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Durumlar</option>
<option value={WorkOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={WorkOrderStatusEnum.Planned}>Planlandı</option>
<option value={WorkOrderStatusEnum.InProgress}>Devam Ediyor</option>
<option value={WorkOrderStatusEnum.Completed}>Tamamlandı</option>
{Object.values(WorkOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkOrderStatusText(status)}
</option>
))}
</select>
</div>
<div className="relative">
@ -287,11 +288,11 @@ const MaintenanceWorkOrders: React.FC = () => {
className="pl-4 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Tipler</option>
<option value={WorkOrderTypeEnum.Preventive}>Önleyici</option>
<option value={WorkOrderTypeEnum.Corrective}>Düzeltici</option>
<option value={WorkOrderTypeEnum.Emergency}>Acil</option>
<option value={WorkOrderTypeEnum.Inspection}>İnceleme</option>
<option value={WorkOrderTypeEnum.Calibration}>Kalibrasyon</option>
{Object.values(WorkOrderTypeEnum).map((type) => (
<option key={type} value={type}>
{getWorkOrderTypeText(type)}
</option>
))}
</select>
</div>
</div>

View file

@ -4,6 +4,7 @@ import { PmCalendarEvent, WorkOrderStatusEnum } from '../../../types/pm'
import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { PriorityEnum } from '../../../types/common'
import { getPriorityText, getWorkOrderStatusText } from '@/utils/erp'
interface NewCalendarEventModalProps {
isOpen: boolean
@ -220,10 +221,11 @@ const NewCalendarEventModal: React.FC<NewCalendarEventModalProps> = ({
onChange={(e) => handleInputChange('priority', e.target.value as PriorityEnum)}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
@ -331,14 +333,11 @@ const NewCalendarEventModal: React.FC<NewCalendarEventModalProps> = ({
}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="scheduled">Planlanmış</option>
<option value={WorkOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={WorkOrderStatusEnum.Planned}>Planlandı</option>
<option value={WorkOrderStatusEnum.Released}>Serbest Bırakıldı</option>
<option value={WorkOrderStatusEnum.InProgress}>Devam Ediyor</option>
<option value={WorkOrderStatusEnum.OnHold}>Beklemede</option>
<option value={WorkOrderStatusEnum.Completed}>Tamamlandı</option>
<option value={WorkOrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(WorkOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkOrderStatusText(status)}
</option>
))}
</select>
</div>
)}

View file

@ -9,6 +9,7 @@ import {
import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { PriorityEnum } from '../../../types/common'
import { getCriticalityLevelText, getFaultTypeText, getPriorityText } from '@/utils/erp'
interface NewFaultNotificationModalProps {
isOpen: boolean
@ -274,14 +275,11 @@ const NewFaultNotificationModal: React.FC<NewFaultNotificationModalProps> = ({
onChange={(e) => handleInputChange('faultType', e.target.value as FaultTypeEnum)}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={FaultTypeEnum.Mechanical}>Mekanik</option>
<option value={FaultTypeEnum.Electrical}>Elektrik</option>
<option value={FaultTypeEnum.Hydraulic}>Hidrolik</option>
<option value={FaultTypeEnum.Pneumatic}>Pnömatik</option>
<option value={FaultTypeEnum.Software}>Yazılım</option>
<option value={FaultTypeEnum.Safety}>Güvenlik</option>
<option value={FaultTypeEnum.Performance}>Performans</option>
<option value={FaultTypeEnum.Other}>Diğer</option>
{Object.values(FaultTypeEnum).map((faultType) => (
<option key={faultType} value={faultType}>
{getFaultTypeText(faultType)}
</option>
))}
</select>
</div>
@ -292,10 +290,11 @@ const NewFaultNotificationModal: React.FC<NewFaultNotificationModalProps> = ({
onChange={(e) => handleInputChange('priority', e.target.value as PriorityEnum)}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
@ -308,10 +307,11 @@ const NewFaultNotificationModal: React.FC<NewFaultNotificationModalProps> = ({
}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
</div>

View file

@ -10,6 +10,7 @@ import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { mockUnits } from '../../../mocks/mockUnits'
import { PriorityEnum } from '../../../types/common'
import { getFrequencyUnitText, getMaintenancePlanTypeText, getPriorityText } from '@/utils/erp'
interface NewMaintenancePlanModalProps {
isOpen: boolean
@ -158,10 +159,11 @@ const NewMaintenancePlanModal: React.FC<NewMaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={MaintenancePlanTypeEnum.Preventive}>Önleyici Bakım</option>
<option value={MaintenancePlanTypeEnum.Predictive}>Kestirimci Bakım</option>
<option value={MaintenancePlanTypeEnum.Corrective}>Düzeltici Bakım</option>
<option value={MaintenancePlanTypeEnum.Condition}>Durum Bazlı Bakım</option>
{Object.values(MaintenancePlanTypeEnum).map((type) => (
<option key={type} value={type}>
{getMaintenancePlanTypeText(type)}
</option>
))}
</select>
</div>
<div>
@ -172,10 +174,11 @@ const NewMaintenancePlanModal: React.FC<NewMaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
<div className="md:col-span-2">
@ -219,12 +222,11 @@ const NewMaintenancePlanModal: React.FC<NewMaintenancePlanModalProps> = ({
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={FrequencyUnitEnum.Days}>Gün</option>
<option value={FrequencyUnitEnum.Weeks}>Hafta</option>
<option value={FrequencyUnitEnum.Months}>Ay</option>
<option value={FrequencyUnitEnum.Years}>Yıl</option>
<option value={FrequencyUnitEnum.Hours}>Saat</option>
<option value={FrequencyUnitEnum.Cycles}>Çevrim</option>
{Object.values(FrequencyUnitEnum).map((unit) => (
<option key={unit} value={unit}>
{getFrequencyUnitText(unit)}
</option>
))}
</select>
</div>
<div>

View file

@ -4,6 +4,7 @@ import { TeamRoleEnum } from '../../../types/common'
import MultiSelectEmployee from '../../../components/common/MultiSelectEmployee'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { Team, TeamMember } from '../../../types/common'
import { getTeamRoleText } from '@/utils/erp'
interface NewTeamModalProps {
isOpen: boolean
@ -259,10 +260,11 @@ const NewTeamModal: React.FC<NewTeamModalProps> = ({ isOpen, onClose, onSave })
}
className="text-xs px-1.5 py-1 border border-gray-300 rounded"
>
<option value={TeamRoleEnum.Member}>Üye</option>
<option value={TeamRoleEnum.Lead}>Lider</option>
<option value={TeamRoleEnum.Specialist}>Uzman</option>
<option value={TeamRoleEnum.Manager}>Yönetici</option>
{Object.values(TeamRoleEnum).map((role) => (
<option key={role} value={role}>
{getTeamRoleText(role)}
</option>
))}
</select>
</div>
</div>

View file

@ -6,6 +6,7 @@ import {
CriticalityLevelEnum,
PmWorkCenterSpecification,
} from '../../../types/pm'
import { getCriticalityLevelText, getWorkCenterStatusText } from '@/utils/erp'
interface NewWorkCenterModalProps {
isOpen: boolean
@ -249,10 +250,11 @@ const NewWorkCenterModal: React.FC<NewWorkCenterModalProps> = ({ isOpen, onClose
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkCenterStatusEnum.Operational}>Operasyonel</option>
<option value={WorkCenterStatusEnum.UnderMaintenance}>Bakımda</option>
<option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option>
<option value={WorkCenterStatusEnum.Retired}>Emekli</option>
{Object.values(WorkCenterStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkCenterStatusText(status)}
</option>
))}
</select>
</div>
<div>
@ -265,10 +267,11 @@ const NewWorkCenterModal: React.FC<NewWorkCenterModalProps> = ({ isOpen, onClose
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
</div>

View file

@ -12,6 +12,7 @@ import { mockMaintenanceTeams } from '../../../mocks/mockMaintenanceTeams'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { PriorityEnum } from '../../../types/common'
import { getPriorityText, getWorkOrderTypeText } from '@/utils/erp'
interface NewWorkOrderModalProps {
isOpen: boolean
@ -242,11 +243,11 @@ const NewWorkOrderModal: React.FC<NewWorkOrderModalProps> = ({ isOpen, onClose,
}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkOrderTypeEnum.Preventive}>Önleyici</option>
<option value={WorkOrderTypeEnum.Corrective}>Düzeltici</option>
<option value={WorkOrderTypeEnum.Emergency}>Acil</option>
<option value={WorkOrderTypeEnum.Inspection}>İnceleme</option>
<option value={WorkOrderTypeEnum.Calibration}>Kalibrasyon</option>
{Object.values(WorkOrderTypeEnum).map((type) => (
<option key={type} value={type}>
{getWorkOrderTypeText(type)}
</option>
))}
</select>
</div>
@ -262,10 +263,11 @@ const NewWorkOrderModal: React.FC<NewWorkOrderModalProps> = ({ isOpen, onClose,
}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
</div>

View file

@ -102,10 +102,11 @@ const StatusUpdateModal: React.FC<StatusUpdateModalProps> = ({
onChange={(e) => setNewStatus(e.target.value as WorkCenterStatusEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={WorkCenterStatusEnum.Operational}>Operasyonel</option>
<option value={WorkCenterStatusEnum.UnderMaintenance}>Bakımda</option>
<option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option>
<option value={WorkCenterStatusEnum.Retired}>Emekli</option>
{Object.values(WorkCenterStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkCenterStatusText(status)}
</option>
))}
</select>
{isStatusCritical && (
@ -145,10 +146,11 @@ const StatusUpdateModal: React.FC<StatusUpdateModalProps> = ({
onChange={(e) => setNewCriticality(e.target.value as CriticalityLevelEnum)}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
)}

View file

@ -238,10 +238,11 @@ const WorkCenterCards: React.FC = () => {
className="pl-10 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Durumlar</option>
<option value={WorkCenterStatusEnum.Operational}>Operasyonel</option>
<option value={WorkCenterStatusEnum.UnderMaintenance}>Bakımda</option>
<option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option>
<option value={WorkCenterStatusEnum.Retired}>Emekli</option>
{Object.values(WorkCenterStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkCenterStatusText(status)}
</option>
))}
</select>
</div>
<div className="relative">
@ -250,11 +251,11 @@ const WorkCenterCards: React.FC = () => {
onChange={(e) => setCriticalityFilter(e.target.value as CriticalityLevelEnum | 'all')}
className="pl-4 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Kritiklik</option>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
</div>

View file

@ -21,6 +21,7 @@ import { mockDepartments } from '../../../mocks/mockDepartments'
import { HrDepartment } from '../../../types/hr'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { getCriticalityLevelText, getWorkCenterStatusText } from '@/utils/erp'
interface ValidationErrors {
[key: string]: string
@ -65,7 +66,7 @@ const WorkCenterForm: React.FC = () => {
capacity: 0,
costPerHour: 0,
setupTime: 0,
machineType: '',
machineTypeId: '',
isActive: true,
creationTime: new Date('2022-03-15'),
lastModificationTime: new Date('2024-01-15'),
@ -288,12 +289,11 @@ const WorkCenterForm: React.FC = () => {
}`}
>
<option value="">Tip seçin</option>
<option value="MACHINE">Makine</option>
<option value="VEHICLE">Araç</option>
<option value="TOOL">Alet</option>
<option value="FACILITY">Tesis</option>
<option value="SYSTEM">Sistem</option>
<option value="OTHER">Diğer</option>
{mockWorkCenters.map((wc) => (
<option key={wc.workCenterType?.id} value={wc.workCenterType?.id}>
{wc.workCenterType?.code} - {wc.workCenterType?.name}
</option>
))}
</select>
{errors.workCenterType && (
<p className="mt-1 text-sm text-red-600">{errors.workCenterType}</p>
@ -428,10 +428,11 @@ const WorkCenterForm: React.FC = () => {
onChange={(e) => handleInputChange('status', e.target.value)}
className="block w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="OPERATIONAL">Çalışır Durumda</option>
<option value="DOWN">Arızalı</option>
<option value="MAINTENANCE">Bakımda</option>
<option value="RETIRED">Kullanım Dışı</option>
{Object.values(WorkCenterStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkCenterStatusText(status)}
</option>
))}
</select>
</div>
@ -444,10 +445,11 @@ const WorkCenterForm: React.FC = () => {
onChange={(e) => handleInputChange('criticality', e.target.value)}
className="block w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-1 focus:border-blue-500 focus:ring-blue-500"
>
<option value="LOW">Düşük</option>
<option value="MEDIUM">Orta</option>
<option value="HIGH">Yüksek</option>
<option value="CRITICAL">Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>
</div>

View file

@ -141,10 +141,11 @@ const WorkCenterList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={WorkCenterStatusEnum.Operational}>Operasyonel</option>
<option value={WorkCenterStatusEnum.UnderMaintenance}>Bakımda</option>
<option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option>
<option value={WorkCenterStatusEnum.Retired}>Emekli</option>
{Object.values(WorkCenterStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkCenterStatusText(status)}
</option>
))}
</select>
</div>
@ -156,10 +157,11 @@ const WorkCenterList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={CriticalityLevelEnum.Low}>Düşük</option>
<option value={CriticalityLevelEnum.Medium}>Orta</option>
<option value={CriticalityLevelEnum.High}>Yüksek</option>
<option value={CriticalityLevelEnum.Critical}>Kritik</option>
{Object.values(CriticalityLevelEnum).map((level) => (
<option key={level} value={level}>
{getCriticalityLevelText(level)}
</option>
))}
</select>
</div>

View file

@ -13,7 +13,7 @@ import {
} from 'react-icons/fa'
import { MrpBOM, MrpBOMComponent, MrpBOMOperation } from '../../../types/mrp'
import BOMFormModal from './BOMFormModal'
import { getBOMTypeColor, getBOMTypeName } from '../../../utils/erp'
import { getBOMTypeColor, getBOMTypeText } from '../../../utils/erp'
import { mockBOMs } from '../../../mocks/mockBOMs'
import { Container } from '@/components/shared'
@ -82,9 +82,7 @@ const BOMManagement: React.FC = () => {
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold text-gray-900">Ürün Ağaçları (BOM)</h2>
<p className="text-gray-600">
Ürün bileşenlerini ve üretim operasyonlarını yönetin
</p>
<p className="text-gray-600">Ürün bileşenlerini ve üretim operasyonlarını yönetin</p>
</div>
<button
onClick={handleAddNew}
@ -126,7 +124,7 @@ const BOMManagement: React.FC = () => {
bom.bomType,
)}`}
>
{getBOMTypeName(bom.bomType)}
{getBOMTypeText(bom.bomType)}
</span>
</div>
<p className="text-sm text-gray-600 mb-0.5">
@ -235,7 +233,7 @@ const BOMManagement: React.FC = () => {
Malzeme: {selectedBOM.material?.code} - {selectedBOM.material?.name}
</div>
<div>Versiyon: {selectedBOM.version}</div>
<div>Tip: {getBOMTypeName(selectedBOM.bomType)}</div>
<div>Tip: {getBOMTypeText(selectedBOM.bomType)}</div>
<div>Temel Miktar: {selectedBOM.baseQuantity}</div>
</div>
</div>

View file

@ -1,15 +1,14 @@
import React, { useState, useEffect } from "react";
import { FaTimes, FaSave } from "react-icons/fa";
import { MrpDemandForecast, ForecastMethodEnum } from "../../../types/mrp";
import { mockMaterials } from "../../../mocks/mockMaterials";
import React, { useState, useEffect } from 'react'
import { FaTimes, FaSave } from 'react-icons/fa'
import { MrpDemandForecast, ForecastMethodEnum } from '../../../types/mrp'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { getForecastMethodText } from '@/utils/erp'
interface DemandForecastFormModalProps {
isOpen: boolean;
onClose: () => void;
onSave: (
forecastData: Omit<MrpDemandForecast, "id" | "material"> & { id?: string }
) => void;
initialData: MrpDemandForecast | null;
isOpen: boolean
onClose: () => void
onSave: (forecastData: Omit<MrpDemandForecast, 'id' | 'material'> & { id?: string }) => void
initialData: MrpDemandForecast | null
}
const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
@ -19,9 +18,9 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
initialData,
}) => {
const newFormData: MrpDemandForecast = {
id: "",
materialId: "",
forecastPeriod: "",
id: '',
materialId: '',
forecastPeriod: '',
startDate: new Date(),
endDate: new Date(),
forecastMethod: ForecastMethodEnum.MovingAverage,
@ -32,10 +31,10 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
trendFactor: 0,
creationTime: new Date(),
lastModificationTime: new Date(),
notes: "",
};
notes: '',
}
const [formData, setFormData] = useState(newFormData);
const [formData, setFormData] = useState(newFormData)
useEffect(() => {
if (initialData) {
@ -43,36 +42,33 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
...initialData,
startDate: new Date(initialData.startDate),
endDate: new Date(initialData.endDate),
});
})
} else {
setFormData(newFormData);
setFormData(newFormData)
}
}, [initialData, isOpen]);
}, [initialData, isOpen])
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
const saveData = {
...formData,
id: initialData?.id,
startDate: new Date(formData.startDate),
endDate: new Date(formData.endDate),
};
onSave(saveData);
};
}
onSave(saveData)
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between p-4 border-b">
<h2 className="text-lg font-semibold text-gray-900">
{initialData ? "Talep Tahmini Düzenle" : "Yeni Talep Tahmini"}
{initialData ? 'Talep Tahmini Düzenle' : 'Yeni Talep Tahmini'}
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600"
>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
<FaTimes className="w-4 h-4" />
</button>
</div>
@ -80,15 +76,11 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
<form onSubmit={handleSubmit} className="p-4 space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Malzeme
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Malzeme</label>
<select
required
value={formData.materialId}
onChange={(e) =>
setFormData({ ...formData, materialId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, materialId: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Seçiniz</option>
@ -108,9 +100,7 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
type="text"
required
value={formData.forecastPeriod}
onChange={(e) =>
setFormData({ ...formData, forecastPeriod: e.target.value })
}
onChange={(e) => setFormData({ ...formData, forecastPeriod: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="Örn: 2024-Q3"
/>
@ -123,7 +113,7 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
<input
type="date"
required
value={formData.startDate.toISOString().split("T")[0]}
value={formData.startDate.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -135,13 +125,11 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Bitiş Tarihi
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Bitiş Tarihi</label>
<input
type="date"
required
value={formData.endDate.toISOString().split("T")[0]}
value={formData.endDate.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -153,9 +141,7 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Tahmin Yöntemi
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Tahmin Yöntemi</label>
<select
required
value={formData.forecastMethod}
@ -167,23 +153,16 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value={ForecastMethodEnum.MovingAverage}>
Hareketli Ortalama
</option>
<option value={ForecastMethodEnum.ExponentialSmoothing}>
Üstel Yumuşatma
</option>
<option value={ForecastMethodEnum.LinearRegression}>
Doğrusal Regresyon
</option>
<option value={ForecastMethodEnum.Seasonal}>Mevsimsel</option>
{Object.values(ForecastMethodEnum).map((method) => (
<option key={method} value={method}>
{getForecastMethodText(method)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">
Tahmin Miktarı
</label>
<label className="block text-sm font-medium text-gray-700 mb-2">Tahmin Miktarı</label>
<input
type="number"
required
@ -219,7 +198,7 @@ const DemandForecastFormModal: React.FC<DemandForecastFormModalProps> = ({
</form>
</div>
</div>
);
};
)
}
export default DemandForecastFormModal;
export default DemandForecastFormModal

View file

@ -1,17 +1,18 @@
import React, { useState, useEffect } from "react";
import { FaTimes, FaSave } from "react-icons/fa";
import { MrpWorkOrder } from "../../../types/mrp";
import { mockProductionOrders } from "../../../mocks/mockProductionOrders";
import { mockOperations } from "../../../mocks/mockOperations";
import { mockMaterials } from "../../../mocks/mockMaterials";
import { mockWorkCenters } from "../../../mocks/mockWorkCenters";
import { WorkOrderStatusEnum } from "../../../types/pm";
import React, { useState, useEffect } from 'react'
import { FaTimes, FaSave } from 'react-icons/fa'
import { MrpWorkOrder } from '../../../types/mrp'
import { mockProductionOrders } from '../../../mocks/mockProductionOrders'
import { mockOperations } from '../../../mocks/mockOperations'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { WorkOrderStatusEnum } from '../../../types/pm'
import { getWorkOrderStatusText } from '@/utils/erp'
interface EditWorkOrderFormProps {
isOpen: boolean;
onClose: () => void;
onSave: (workOrder: MrpWorkOrder) => void;
workOrder: MrpWorkOrder | null;
isOpen: boolean
onClose: () => void
onSave: (workOrder: MrpWorkOrder) => void
workOrder: MrpWorkOrder | null
}
const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
@ -21,20 +22,20 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
workOrder,
}) => {
const [formData, setFormData] = useState({
workOrderNumber: "",
productionOrderId: "",
operationId: "",
materialId: "",
workOrderNumber: '',
productionOrderId: '',
operationId: '',
materialId: '',
sequence: 1,
plannedStartDate: "",
plannedEndDate: "",
plannedStartDate: '',
plannedEndDate: '',
plannedQuantity: 0,
workCenterId: "",
workCenterId: '',
assignedOperators: [] as string[],
setupTime: 0,
processTime: 0,
status: WorkOrderStatusEnum.Created,
});
})
useEffect(() => {
if (workOrder) {
@ -44,23 +45,21 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
operationId: workOrder.operationId,
materialId: workOrder.materialId,
sequence: workOrder.sequence,
plannedStartDate: workOrder.plannedStartDate
.toISOString()
.split("T")[0],
plannedEndDate: workOrder.plannedEndDate.toISOString().split("T")[0],
plannedStartDate: workOrder.plannedStartDate.toISOString().split('T')[0],
plannedEndDate: workOrder.plannedEndDate.toISOString().split('T')[0],
plannedQuantity: workOrder.plannedQuantity,
workCenterId: workOrder.workCenterId,
assignedOperators: workOrder.assignedOperators,
setupTime: workOrder.setupTime,
processTime: workOrder.processTime,
status: workOrder.status,
});
})
}
}, [workOrder]);
}, [workOrder])
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!workOrder) return;
e.preventDefault()
if (!workOrder) return
const updatedWorkOrder: MrpWorkOrder = {
...workOrder,
@ -68,24 +67,19 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
plannedStartDate: new Date(formData.plannedStartDate),
plannedEndDate: new Date(formData.plannedEndDate),
lastModificationTime: new Date(),
};
onSave(updatedWorkOrder);
onClose();
};
}
onSave(updatedWorkOrder)
onClose()
}
if (!isOpen || !workOrder) return null;
if (!isOpen || !workOrder) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between p-4 border-b">
<h2 className="text-lg font-semibold text-gray-900">
İş Emri Düzenle
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600"
>
<h2 className="text-lg font-semibold text-gray-900">İş Emri Düzenle</h2>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
<FaTimes className="w-4 h-4" />
</button>
</div>
@ -100,18 +94,14 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
type="text"
required
value={formData.workOrderNumber}
onChange={(e) =>
setFormData({ ...formData, workOrderNumber: e.target.value })
}
onChange={(e) => setFormData({ ...formData, workOrderNumber: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="WO-2024-XXX"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Üretim Emri
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Üretim Emri</label>
<select
required
value={formData.productionOrderId}
@ -133,15 +123,11 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Operasyon
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Operasyon</label>
<select
required
value={formData.operationId}
onChange={(e) =>
setFormData({ ...formData, operationId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, operationId: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Seçiniz</option>
@ -154,15 +140,11 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Malzeme
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Malzeme</label>
<select
required
value={formData.materialId}
onChange={(e) =>
setFormData({ ...formData, materialId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, materialId: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Seçiniz</option>
@ -175,15 +157,11 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
İş Merkezi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">İş Merkezi</label>
<select
required
value={formData.workCenterId}
onChange={(e) =>
setFormData({ ...formData, workCenterId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, workCenterId: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Seçiniz</option>
@ -196,9 +174,7 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Sıra
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Sıra</label>
<input
type="number"
required
@ -222,9 +198,7 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
type="date"
required
value={formData.plannedStartDate}
onChange={(e) =>
setFormData({ ...formData, plannedStartDate: e.target.value })
}
onChange={(e) => setFormData({ ...formData, plannedStartDate: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
@ -237,9 +211,7 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
type="date"
required
value={formData.plannedEndDate}
onChange={(e) =>
setFormData({ ...formData, plannedEndDate: e.target.value })
}
onChange={(e) => setFormData({ ...formData, plannedEndDate: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
@ -302,9 +274,7 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Durum
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Durum</label>
<select
value={formData.status}
onChange={(e) =>
@ -315,15 +285,11 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value={WorkOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={WorkOrderStatusEnum.Released}>Yayınlandı</option>
<option value={WorkOrderStatusEnum.InProgress}>İşlemde</option>
<option value={WorkOrderStatusEnum.Completed}>
Tamamlandı
</option>
<option value={WorkOrderStatusEnum.Cancelled}>
İptal Edildi
</option>
{Object.values(WorkOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getWorkOrderStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -347,7 +313,7 @@ const EditWorkOrderForm: React.FC<EditWorkOrderFormProps> = ({
</form>
</div>
</div>
);
};
)
}
export default EditWorkOrderForm;
export default EditWorkOrderForm

View file

@ -1,25 +1,24 @@
import React, { useState, useEffect } from "react";
import { FaTimes, FaSave } from "react-icons/fa";
import {
MrpMaterialRequirement,
RequirementSourceTypeEnum,
} from "../../../types/mrp";
import { mockMaterials } from "../../../mocks/mockMaterials";
import React, { useState, useEffect } from 'react'
import { FaTimes, FaSave } from 'react-icons/fa'
import { MrpMaterialRequirement, RequirementSourceTypeEnum } from '../../../types/mrp'
import { mockMaterials } from '../../../mocks/mockMaterials'
import { getRequirementSourceTypeText } from '@/utils/erp'
interface MaterialRequirementFormModalProps {
isOpen: boolean;
onClose: () => void;
onSave: (
reqData: Omit<MrpMaterialRequirement, "id" | "material"> & { id?: string }
) => void;
initialData: MrpMaterialRequirement | null;
isOpen: boolean
onClose: () => void
onSave: (reqData: Omit<MrpMaterialRequirement, 'id' | 'material'> & { id?: string }) => void
initialData: MrpMaterialRequirement | null
}
const MaterialRequirementFormModal: React.FC<
MaterialRequirementFormModalProps
> = ({ isOpen, onClose, onSave, initialData }) => {
const MaterialRequirementFormModal: React.FC<MaterialRequirementFormModalProps> = ({
isOpen,
onClose,
onSave,
initialData,
}) => {
const newFormData: MrpMaterialRequirement = {
materialId: "",
materialId: '',
sourceType: RequirementSourceTypeEnum.Forecast,
grossRequirement: 0,
netRequirement: 0,
@ -29,14 +28,14 @@ const MaterialRequirementFormModal: React.FC<
plannedOrderRelease: 0,
requirementDate: new Date(),
plannedReceiptDate: new Date(),
id: "",
mrpRunId: "",
id: '',
mrpRunId: '',
plannedReleaseDate: new Date(),
creationTime: new Date(),
lastModificationTime: new Date(),
};
}
const [formData, setFormData] = useState(newFormData);
const [formData, setFormData] = useState(newFormData)
useEffect(() => {
if (initialData) {
@ -44,37 +43,34 @@ const MaterialRequirementFormModal: React.FC<
...initialData,
requirementDate: new Date(initialData.requirementDate),
plannedReceiptDate: new Date(initialData.plannedReceiptDate),
});
})
} else {
// Reset form for new entry
setFormData(newFormData);
setFormData(newFormData)
}
}, [initialData, isOpen]);
}, [initialData, isOpen])
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
const saveData = {
...formData,
id: initialData?.id,
requirementDate: new Date(formData.requirementDate),
plannedReceiptDate: new Date(formData.plannedReceiptDate),
};
onSave(saveData);
};
}
onSave(saveData)
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg shadow-xl max-w-xl w-full mx-4 max-h-[90vh] overflow-y-auto">
<div className="flex items-center justify-between p-4 border-b">
<h2 className="text-lg font-semibold text-gray-900">
{initialData ? "Malzeme İhtiyacı Düzenle" : "Yeni Malzeme İhtiyacı"}
{initialData ? 'Malzeme İhtiyacı Düzenle' : 'Yeni Malzeme İhtiyacı'}
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600"
>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
<FaTimes className="w-4 h-4" />
</button>
</div>
@ -82,15 +78,11 @@ const MaterialRequirementFormModal: React.FC<
<form onSubmit={handleSubmit} className="p-4 space-y-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Malzeme
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Malzeme</label>
<select
required
value={formData.materialId}
onChange={(e) =>
setFormData({ ...formData, materialId: e.target.value })
}
onChange={(e) => setFormData({ ...formData, materialId: e.target.value })}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Seçiniz</option>
@ -103,9 +95,7 @@ const MaterialRequirementFormModal: React.FC<
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Kaynak Tipi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Kaynak Tipi</label>
<select
required
value={formData.sourceType}
@ -117,25 +107,16 @@ const MaterialRequirementFormModal: React.FC<
}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value={RequirementSourceTypeEnum.Forecast}>
Tahmin
</option>
<option value={RequirementSourceTypeEnum.SalesOrder}>
Satış Siparişi
</option>
<option value={RequirementSourceTypeEnum.SafetyStock}>
Güvenlik Stoku
</option>
<option value={RequirementSourceTypeEnum.ProductionOrder}>
Üretim Emri
</option>
{Object.values(RequirementSourceTypeEnum).map((type) => (
<option key={type} value={type}>
{getRequirementSourceTypeText(type)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Brüt İhtiyaç
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Brüt İhtiyaç</label>
<input
type="number"
required
@ -152,9 +133,7 @@ const MaterialRequirementFormModal: React.FC<
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Net İhtiyaç
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Net İhtiyaç</label>
<input
type="number"
required
@ -170,13 +149,11 @@ const MaterialRequirementFormModal: React.FC<
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
İhtiyaç Tarihi
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">İhtiyaç Tarihi</label>
<input
type="date"
required
value={formData.requirementDate.toISOString().split("T")[0]}
value={formData.requirementDate.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -194,7 +171,7 @@ const MaterialRequirementFormModal: React.FC<
<input
type="date"
required
value={formData.plannedReceiptDate.toISOString().split("T")[0]}
value={formData.plannedReceiptDate.toISOString().split('T')[0]}
onChange={(e) =>
setFormData({
...formData,
@ -225,7 +202,7 @@ const MaterialRequirementFormModal: React.FC<
</form>
</div>
</div>
);
};
)
}
export default MaterialRequirementFormModal;
export default MaterialRequirementFormModal

View file

@ -1,15 +1,13 @@
import React, { useState, useEffect } from "react";
import { FaSave, FaTimes } from "react-icons/fa";
import {
OperationCategoryEnum,
MrpOperationTypeDefinition,
} from "../../../types/mrp";
import React, { useState, useEffect } from 'react'
import { FaSave, FaTimes } from 'react-icons/fa'
import { OperationCategoryEnum, MrpOperationTypeDefinition } from '../../../types/mrp'
import { getOperationTypeText } from '@/utils/erp'
interface OperationTypeFormProps {
open: boolean;
initial?: MrpOperationTypeDefinition | null;
onClose: () => void;
onSave: (data: MrpOperationTypeDefinition) => void;
open: boolean
initial?: MrpOperationTypeDefinition | null
onClose: () => void
onSave: (data: MrpOperationTypeDefinition) => void
}
const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
@ -18,13 +16,13 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
onClose,
onSave,
}) => {
const [saving, setSaving] = useState(false);
const [saving, setSaving] = useState(false)
const [form, setForm] = useState<MrpOperationTypeDefinition>(
initial || {
id: "",
code: "",
name: "",
description: "",
id: '',
code: '',
name: '',
description: '',
category: OperationCategoryEnum.Setup,
defaultDuration: 0,
requiresSetup: false,
@ -34,85 +32,79 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
isActive: true,
creationTime: new Date(),
lastModificationTime: new Date(),
}
);
},
)
useEffect(() => {
if (initial) setForm(initial);
if (initial) setForm(initial)
else
setForm((prev) => ({
...prev,
id: "",
code: "",
name: "",
description: "",
}));
}, [initial, open]);
id: '',
code: '',
name: '',
description: '',
}))
}, [initial, open])
if (!open) return null;
if (!open) return null
const handleChange = (
field: keyof MrpOperationTypeDefinition,
value: string | number | boolean
value: string | number | boolean,
) => {
setForm((s) => ({
...s,
[field]: value,
lastModificationTime: new Date(),
}));
};
}))
}
const handleSave = async () => {
setSaving(true);
setSaving(true)
try {
// simulate API
await new Promise((r) => setTimeout(r, 600));
onSave({ ...form, id: form.id || String(Date.now()) });
await new Promise((r) => setTimeout(r, 600))
onSave({ ...form, id: form.id || String(Date.now()) })
} finally {
setSaving(false);
setSaving(false)
}
};
}
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-4 w-full max-w-xl mx-4">
<h3 className="text-lg font-semibold mb-3">
{form.id ? "Operasyon Türünü Düzenle" : "Yeni Operasyon Türü"}
{form.id ? 'Operasyon Türünü Düzenle' : 'Yeni Operasyon Türü'}
</h3>
<div className="space-y-2">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Kod
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Kod</label>
<input
autoFocus
value={form.code}
onChange={(e) => handleChange("code", e.target.value)}
onChange={(e) => handleChange('code', e.target.value)}
className="w-full border rounded-lg px-2 py-1.5 text-sm"
placeholder="Örn: CUT001"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Ad
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Ad</label>
<input
value={form.name}
onChange={(e) => handleChange("name", e.target.value)}
onChange={(e) => handleChange('name', e.target.value)}
className="w-full border rounded-lg px-2 py-1.5 text-sm"
placeholder="Kesme İşlemi"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
ıklama
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">ıklama</label>
<textarea
value={form.description}
onChange={(e) => handleChange("description", e.target.value)}
onChange={(e) => handleChange('description', e.target.value)}
rows={3}
className="w-full border rounded-lg px-2 py-1.5 text-sm"
/>
@ -120,27 +112,18 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Kategori
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Kategori</label>
<select
value={form.category}
onChange={(e) => handleChange("category", e.target.value)}
onChange={(e) => handleChange('category', e.target.value)}
className="w-full border rounded-lg px-2 py-1.5 text-sm"
>
<option value="">Kategori seçin</option>
<option value={OperationCategoryEnum.Production}>Üretim</option>
<option value={OperationCategoryEnum.Assembly}>Montaj</option>
<option value={OperationCategoryEnum.Inspection}>
Kontrol
</option>
<option value={OperationCategoryEnum.Packaging}>
Paketleme
</option>
<option value={OperationCategoryEnum.Setup}>Hazırlık</option>
<option value={OperationCategoryEnum.Maintenance}>Bakım</option>
<option value={OperationCategoryEnum.Transport}>Taşıma</option>
<option value={OperationCategoryEnum.Quality}>Kalite</option>
{Object.values(OperationCategoryEnum).map((cat) => (
<option key={cat} value={cat}>
{getOperationTypeText(cat)}
</option>
))}
</select>
</div>
<div>
@ -150,9 +133,7 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
<input
type="number"
value={form.defaultDuration}
onChange={(e) =>
handleChange("defaultDuration", Number(e.target.value))
}
onChange={(e) => handleChange('defaultDuration', Number(e.target.value))}
className="w-full border rounded-lg px-2 py-1.5 text-sm"
/>
</div>
@ -163,9 +144,7 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
<input
type="checkbox"
checked={form.requiresSetup}
onChange={(e) =>
handleChange("requiresSetup", e.target.checked)
}
onChange={(e) => handleChange('requiresSetup', e.target.checked)}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<span className="text-sm text-gray-700">Hazırlık Gerekli</span>
@ -175,9 +154,7 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
<input
type="checkbox"
checked={form.allowsParallelOperation}
onChange={(e) =>
handleChange("allowsParallelOperation", e.target.checked)
}
onChange={(e) => handleChange('allowsParallelOperation', e.target.checked)}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<span className="text-sm text-gray-700">Paralel İşlem</span>
@ -197,13 +174,12 @@ const OperationTypeFormModal: React.FC<OperationTypeFormProps> = ({
disabled={saving}
className="px-3 py-1.5 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-blue-400"
>
<FaSave className="inline mr-2" />{" "}
{saving ? "Kaydediliyor..." : "Kaydet"}
<FaSave className="inline mr-2" /> {saving ? 'Kaydediliyor...' : 'Kaydet'}
</button>
</div>
</div>
</div>
);
};
)
}
export default OperationTypeFormModal;
export default OperationTypeFormModal

View file

@ -13,12 +13,7 @@ import {
import { MrpOperationTypeDefinition } from '../../../types/mrp'
import OperationTypeFormModal from './OperationTypeFormModal'
import { mockOperationTypes } from '../../../mocks/mockOperationTypes'
import {
getOperationCategoryColor,
getOperationTypeColor,
getOperationTypeText,
getSkillLevelText,
} from '../../../utils/erp'
import { getOperationTypeColor, getOperationTypeText, getSkillLevelText } from '../../../utils/erp'
import { Container } from '@/components/shared'
const OperationTypes: React.FC = () => {
@ -261,7 +256,7 @@ const OperationTypes: React.FC = () => {
</td>
<td className="px-3 py-2 whitespace-nowrap">
<span
className={`px-2 py-1 rounded-full text-xs font-medium ${getOperationCategoryColor(
className={`px-2 py-1 rounded-full text-xs font-medium ${getOperationTypeText(
type.category,
)}`}
>

View file

@ -11,9 +11,9 @@ import { mockEmployees } from '../../../mocks/mockEmployees'
import { mockProductionOrders } from '../../../mocks/mockProductionOrders'
import { mockWorkOrders } from '../../../mocks/mockWorkOrders'
import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { PriorityEnum } from '../../../types/common'
import { getPriorityColor, getProductionOrderStatus, getWorkOrderStatus } from '../../../utils/erp'
import { getFrequencyUnitText, getPriorityColor } from '../../../utils/erp'
import { Container } from '@/components/shared'
import { FrequencyUnitEnum } from '@/types/pm'
interface PlanningGanttProps {
workCenterId?: string
@ -107,7 +107,7 @@ const PlanningGantt: React.FC<PlanningGanttProps> = ({ workCenterId }) => {
assignee: wo.assignedOperators[0]
? mockEmployees.find((e) => e.id === wo.assignedOperators[0])
: undefined,
status: getWorkOrderStatus(wo.status),
status: wo.status,
priority: order.priority,
level: 1,
children: [],
@ -125,7 +125,7 @@ const PlanningGantt: React.FC<PlanningGanttProps> = ({ workCenterId }) => {
order.confirmedQuantity && order.plannedQuantity
? Math.round((order.confirmedQuantity / order.plannedQuantity) * 100)
: 0,
status: getProductionOrderStatus(order.status),
status: order.status,
priority: order.priority,
level: 0,
children: workOrders,
@ -480,10 +480,18 @@ const PlanningGantt: React.FC<PlanningGanttProps> = ({ workCenterId }) => {
onChange={(e) => setViewMode(e.target.value as 'day' | 'week' | 'month' | 'year')}
className="px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-full sm:w-auto"
>
<option value="day">Günlük</option>
<option value="week">Haftalık</option>
<option value="month">Aylık</option>
<option value="year">Yıllık</option>
<option value={FrequencyUnitEnum.Days}>
{getFrequencyUnitText(FrequencyUnitEnum.Days)}
</option>
<option value={FrequencyUnitEnum.Weeks}>
{getFrequencyUnitText(FrequencyUnitEnum.Days)}
</option>
<option value={FrequencyUnitEnum.Months}>
{getFrequencyUnitText(FrequencyUnitEnum.Days)}
</option>
<option value={FrequencyUnitEnum.Years}>
{getFrequencyUnitText(FrequencyUnitEnum.Days)}
</option>
</select>
</div>
</div>

View file

@ -26,6 +26,12 @@ import { mockMaterials } from '../../../mocks/mockMaterials'
import { PriorityEnum } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import {
getPriorityText,
getProductionOrderStatusText,
getProductionOrderTypeText,
} from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
const ProductionOrderForm: React.FC = () => {
const { id } = useParams()
@ -260,10 +266,11 @@ const ProductionOrderForm: React.FC = () => {
onChange={handleChange}
className="w-full px-2 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-200 bg-gray-50 focus:bg-white"
>
<option value={ProductionOrderTypeEnum.Standard}>Standart</option>
<option value={ProductionOrderTypeEnum.Rework}>Yeniden İşleme</option>
<option value={ProductionOrderTypeEnum.Maintenance}>Bakım</option>
<option value={ProductionOrderTypeEnum.Sample}>Numune</option>
{Object.values(ProductionOrderTypeEnum).map((type) => (
<option key={type} value={type}>
{getProductionOrderTypeText(type)}
</option>
))}
</select>
</div>
@ -275,12 +282,11 @@ const ProductionOrderForm: React.FC = () => {
onChange={handleChange}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-200 bg-gray-50 focus:bg-white"
>
<option value={ProductionOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={ProductionOrderStatusEnum.Released}>Yayınlandı</option>
<option value={ProductionOrderStatusEnum.InProgress}>İşlemde</option>
<option value={ProductionOrderStatusEnum.Completed}>Tamamlandı</option>
<option value={ProductionOrderStatusEnum.Cancelled}>İptal Edildi</option>
<option value={ProductionOrderStatusEnum.OnHold}>Beklemede</option>
{Object.values(ProductionOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getProductionOrderStatusText(status)}
</option>
))}
</select>
</div>
@ -292,10 +298,11 @@ const ProductionOrderForm: React.FC = () => {
onChange={handleChange}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-200 bg-gray-50 focus:bg-white"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
</div>
@ -469,10 +476,11 @@ const ProductionOrderForm: React.FC = () => {
onChange={handleChange}
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:border-yellow-500 transition-all duration-200 bg-gray-50 focus:bg-white"
>
<option value="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>

View file

@ -665,12 +665,11 @@ const ProductionOrderList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-2 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={ProductionOrderStatusEnum.Created}>Oluşturuldu</option>
<option value={ProductionOrderStatusEnum.Released}>Serbest Bırakıldı</option>
<option value={ProductionOrderStatusEnum.InProgress}>Devam Ediyor</option>
<option value={ProductionOrderStatusEnum.Completed}>Tamamlandı</option>
<option value={ProductionOrderStatusEnum.OnHold}>Beklemede</option>
<option value={ProductionOrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(ProductionOrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getProductionOrderStatusText(status)}
</option>
))}
</select>
</div>
<div>
@ -681,10 +680,11 @@ const ProductionOrderList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-2 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
<div>

View file

@ -8,7 +8,7 @@ import {
FaChartBar,
FaDownload,
} from 'react-icons/fa'
import { PsProjectCostTracking } from '../../../types/ps'
import { ProjectCostTrackingStatus, PsProjectCostTracking } from '../../../types/ps'
import { mockProjectCostTracking } from '../../../mocks/mockProjectCostTracking'
import Widget from '../../../components/common/Widget'
import {
@ -326,10 +326,11 @@ const CostTimeTracking: React.FC = () => {
className="px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="">Tüm Durumlar</option>
<option value="ON_TRACK">Planında</option>
<option value="AT_RISK">Risk Altında</option>
<option value="DELAYED">Gecikmiş</option>
<option value="COMPLETED">Tamamlandı</option>
{Object.values(ProjectCostTrackingStatus).map((status) => (
<option key={status} value={status}>
{getCostTimeTrackingStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -1,26 +1,22 @@
import React, { useState, useEffect } from "react";
import {
FaPlus,
FaEdit,
FaSave,
FaTimesCircle,
FaProjectDiagram,
} from "react-icons/fa";
import React, { useState, useEffect } from 'react'
import { FaPlus, FaEdit, FaSave, FaTimesCircle, FaProjectDiagram } from 'react-icons/fa'
import {
PhaseStatusEnum,
PsProjectPhase,
ProjectStatusEnum,
} from "../../../types/ps";
import { mockProjects } from "../../../mocks/mockProjects";
import { mockProjectPhases } from "../../../mocks/mockProjectPhases";
import MultiSelectTeam from "../../../components/common/MultiSelectTeam";
PhaseCategoryEnum,
} from '../../../types/ps'
import { mockProjects } from '../../../mocks/mockProjects'
import { mockProjectPhases } from '../../../mocks/mockProjectPhases'
import MultiSelectTeam from '../../../components/common/MultiSelectTeam'
import { getPhaseCategoryText, getPhaseStatusText } from '@/utils/erp'
interface PhaseEditModalProps {
isOpen: boolean;
onClose: () => void;
phase?: PsProjectPhase | null;
defaultProjectId?: string;
onSubmit: (data: PsProjectPhase) => void;
isOpen: boolean
onClose: () => void
phase?: PsProjectPhase | null
defaultProjectId?: string
onSubmit: (data: PsProjectPhase) => void
}
const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
@ -30,14 +26,14 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
defaultProjectId,
onSubmit,
}) => {
const isEdit = Boolean(phase);
const isEdit = Boolean(phase)
const ProjectPhaseNew: PsProjectPhase = {
id: "",
projectId: defaultProjectId || "",
code: "",
name: "",
description: "",
id: '',
projectId: defaultProjectId || '',
code: '',
name: '',
description: '',
sequence: 0,
startDate: new Date(),
endDate: new Date(),
@ -52,10 +48,10 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
assignedTeams: [],
deliverables: [],
risks: [],
category: "",
};
category: PhaseCategoryEnum.Planning,
}
const [formData, setFormData] = useState<PsProjectPhase>(ProjectPhaseNew);
const [formData, setFormData] = useState<PsProjectPhase>(ProjectPhaseNew)
useEffect(() => {
if (isOpen) {
@ -66,50 +62,48 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
name: phase.name,
projectId: phase.projectId,
code: phase.code,
description: phase.description || "",
description: phase.description || '',
status: phase.status,
startDate: phase.startDate,
endDate: phase.endDate,
budget: phase.budget,
category: phase.category,
assignedTeams: phase.assignedTeams || [],
});
})
} else {
setFormData(ProjectPhaseNew);
setFormData(ProjectPhaseNew)
}
}
}, [isOpen, phase, defaultProjectId]);
}, [isOpen, phase, defaultProjectId])
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>,
) => {
const { name, value } = e.target;
const { name, value } = e.target
setFormData((prev) => ({
...prev,
[name]: value,
}));
};
}))
}
const handleTeamChange = (teams: string[]) => {
setFormData((prev) => ({
...prev,
assignedTeams: teams,
}));
};
}))
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(formData);
};
e.preventDefault()
onSubmit(formData)
}
const generatePhaseCode = () => {
const phaseCount = mockProjectPhases.length + 1;
return `PH-${phaseCount.toString().padStart(3, "0")}`;
};
const phaseCount = mockProjectPhases.length + 1
return `PH-${phaseCount.toString().padStart(3, '0')}`
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
@ -126,12 +120,12 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
</div>
<div>
<h3 className="text-base font-semibold text-gray-900">
{isEdit ? "Aşama Düzenle" : "Yeni Aşama Oluştur"}
{isEdit ? 'Aşama Düzenle' : 'Yeni Aşama Oluştur'}
</h3>
<p className="text-xs text-gray-600">
{isEdit
? "Mevcut aşama bilgilerini güncelleyin"
: "Yeni bir proje aşaması tanımlayın"}
? 'Mevcut aşama bilgilerini güncelleyin'
: 'Yeni bir proje aşaması tanımlayın'}
</p>
</div>
</div>
@ -179,9 +173,9 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
{formData.projectId &&
(() => {
const selectedProject = mockProjects.find(
(p) => p.id === formData.projectId
);
if (!selectedProject) return null;
(p) => p.id === formData.projectId,
)
if (!selectedProject) return null
return (
<div className="mt-1.5 p-1.5 bg-blue-50 border border-blue-200 rounded-lg">
@ -195,79 +189,56 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
</p>
<div className="grid grid-cols-2 gap-1.5 text-xs">
<div>
<span className="font-medium text-blue-800">
Durum:
</span>
<span className="font-medium text-blue-800">Durum:</span>
<span
className={`ml-1 px-1.5 py-0.5 rounded-full text-xs font-medium ${
selectedProject.status ===
ProjectStatusEnum.Active
? "bg-green-100 text-green-800"
: selectedProject.status ===
ProjectStatusEnum.Planning
? "bg-yellow-100 text-yellow-800"
: "bg-gray-100 text-gray-800"
selectedProject.status === ProjectStatusEnum.Active
? 'bg-green-100 text-green-800'
: selectedProject.status === ProjectStatusEnum.Planning
? 'bg-yellow-100 text-yellow-800'
: 'bg-gray-100 text-gray-800'
}`}
>
{selectedProject.status ===
ProjectStatusEnum.Active
? "Aktif"
: selectedProject.status ===
ProjectStatusEnum.Planning
? "Planlama"
: selectedProject.status ===
ProjectStatusEnum.Completed
? "Tamamlandı"
: selectedProject.status ===
ProjectStatusEnum.OnHold
? "Beklemede"
: "İptal"}
{selectedProject.status === ProjectStatusEnum.Active
? 'Aktif'
: selectedProject.status === ProjectStatusEnum.Planning
? 'Planlama'
: selectedProject.status === ProjectStatusEnum.Completed
? 'Tamamlandı'
: selectedProject.status === ProjectStatusEnum.OnHold
? 'Beklemede'
: 'İptal'}
</span>
</div>
<div>
<span className="font-medium text-blue-800">
İlerleme:
</span>
<span className="font-medium text-blue-800">İlerleme:</span>
<span className="ml-1 text-blue-700">
%{selectedProject.progress}
</span>
</div>
<div>
<span className="font-medium text-blue-800">
Başlangıç:
</span>
<span className="font-medium text-blue-800">Başlangıç:</span>
<span className="ml-1 text-blue-700">
{selectedProject.startDate.toLocaleDateString(
"tr-TR"
)}
{selectedProject.startDate.toLocaleDateString('tr-TR')}
</span>
</div>
<div>
<span className="font-medium text-blue-800">
Bitiş:
</span>
<span className="font-medium text-blue-800">Bitiş:</span>
<span className="ml-1 text-blue-700">
{selectedProject.endDate.toLocaleDateString(
"tr-TR"
)}
{selectedProject.endDate.toLocaleDateString('tr-TR')}
</span>
</div>
</div>
</div>
<div className="ml-1.5 text-right">
<div className="text-base font-bold text-blue-900">
{selectedProject.budget.toLocaleString(
"tr-TR"
)}
</div>
<div className="text-xs text-blue-700">
Bütçe
{selectedProject.budget.toLocaleString('tr-TR')}
</div>
<div className="text-xs text-blue-700">Bütçe</div>
</div>
</div>
</div>
);
)
})()}
</div>
@ -287,9 +258,7 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
ıklama
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">ıklama</label>
<textarea
name="description"
value={formData.description}
@ -302,30 +271,18 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Durum
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Durum</label>
<select
name="status"
value={formData.status}
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value={PhaseStatusEnum.NotStarted}>
Başlanmadı
</option>
<option value={PhaseStatusEnum.InProgress}>
Devam Ediyor
</option>
<option value={PhaseStatusEnum.Completed}>
Tamamlandı
</option>
<option value={PhaseStatusEnum.OnHold}>
Beklemede
</option>
<option value={PhaseStatusEnum.Cancelled}>
İptal Edildi
</option>
{Object.values(PhaseStatusEnum).map((status) => (
<option key={status} value={status}>
{getPhaseStatusText(status)}
</option>
))}
</select>
</div>
@ -340,11 +297,11 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value="">Kategori seçin...</option>
<option value="Planning">Planlama</option>
<option value="Development">Geliştirme</option>
<option value="Testing">Test</option>
<option value="Deployment">Dağıtım</option>
<option value="Design">Tasarım</option>
{Object.values(PhaseCategoryEnum).map((cat) => (
<option key={cat} value={cat}>
{getPhaseCategoryText(cat)}
</option>
))}
</select>
</div>
</div>
@ -369,7 +326,7 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
<input
type="date"
name="startDate"
value={formData.startDate.toISOString().split("T")[0]}
value={formData.startDate.toISOString().split('T')[0]}
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
@ -382,7 +339,7 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
<input
type="date"
name="endDate"
value={formData.endDate.toISOString().split("T")[0]}
value={formData.endDate.toISOString().split('T')[0]}
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
/>
@ -426,9 +383,7 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
<div className="flex items-center gap-2 text-blue-800">
<FaProjectDiagram className="w-4 h-4" />
<span className="text-sm font-medium">Aşama Kodu:</span>
<span className="font-bold">
{isEdit ? phase?.code : generatePhaseCode()}
</span>
<span className="font-bold">{isEdit ? phase?.code : generatePhaseCode()}</span>
</div>
</div>
</div>
@ -449,13 +404,13 @@ const PhaseEditModal: React.FC<PhaseEditModalProps> = ({
className="px-4 py-1.5 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-2 shadow-md hover:shadow-lg"
>
<FaSave className="w-4 h-4" />
{isEdit ? "Güncelle" : "Oluştur"}
{isEdit ? 'Güncelle' : 'Oluştur'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default PhaseEditModal;
export default PhaseEditModal

View file

@ -66,6 +66,7 @@ import {
} from '../../../utils/erp'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { mockCurrencies } from '@/mocks/mockCurrencies'
// Custom styles for the slider
const sliderStyles = `
@ -810,10 +811,11 @@ const ProjectForm: React.FC = () => {
}`}
>
<option value="">Tip seçin</option>
<option value="INTERNAL">İç Proje</option>
<option value="CUSTOMER">Müşteri Projesi</option>
<option value="RESEARCH">Ar-Ge Projesi</option>
<option value="MAINTENANCE">Bakım Projesi</option>
{Object.values(ProjectTypeEnum).map((type) => (
<option key={type} value={type}>
{getProjectTypeText(type)}
</option>
))}
</select>
{errors.projectType && (
<p className="mt-1 text-sm text-red-600">{errors.projectType}</p>
@ -851,11 +853,11 @@ const ProjectForm: React.FC = () => {
onChange={(e) => handleInputChange('status', e.target.value)}
className="block w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="PLANNING">Planlama</option>
<option value="ACTIVE">Aktif</option>
<option value="ON_HOLD">Beklemede</option>
<option value="COMPLETED">Tamamlandı</option>
<option value="CANCELLED">İptal Edildi</option>
{Object.values(ProjectStatusEnum).map((status) => (
<option key={status} value={status}>
{getProjectStatusText(status)}
</option>
))}
</select>
</div>
@ -868,10 +870,11 @@ const ProjectForm: React.FC = () => {
onChange={(e) => handleInputChange('priority', e.target.value)}
className="block w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="LOW">Düşük</option>
<option value="NORMAL">Normal</option>
<option value="HIGH">Yüksek</option>
<option value="URGENT">Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{priority}
</option>
))}
</select>
</div>
@ -884,9 +887,11 @@ const ProjectForm: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="block w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="TRY">Türk Lirası (TRY)</option>
<option value="USD">Amerikan Doları (USD)</option>
<option value="EUR">Euro (EUR)</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
@ -1238,9 +1243,11 @@ const ProjectForm: React.FC = () => {
onChange={(e) => handleInputChange('currency', e.target.value)}
className="block w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="TRY">Türk Lirası (TRY)</option>
<option value="USD">Amerikan Doları (USD)</option>
<option value="EUR">Euro (EUR)</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>

View file

@ -12,8 +12,9 @@ import { mockProjects } from '../../../mocks/mockProjects'
import { mockProjectPhases } from '../../../mocks/mockProjectPhases'
import { mockProjectTasks } from '../../../mocks/mockProjectTasks'
import { PriorityEnum } from '../../../types/common'
import { getPriorityColor, getProjectStatusColor } from '../../../utils/erp'
import { getFrequencyUnitText, getGanttStatusColor, getPriorityColor } from '../../../utils/erp'
import { Container } from '@/components/shared'
import { FrequencyUnitEnum } from '@/types/pm'
interface ProjectGanttProps {
employeeId?: string
@ -479,7 +480,7 @@ const ProjectGantt: React.FC<ProjectGanttProps> = ({ employeeId }) => {
if (task.type === 'task' && position.isVisible) {
return (
<div
className={`absolute h-4 sm:h-5 mt-0.5 rounded-sm ${getProjectStatusColor(
className={`absolute h-4 sm:h-5 mt-0.5 rounded-sm ${getGanttStatusColor(
task.status,
)} shadow-md group cursor-pointer border border-white border-opacity-20`}
style={{ left: position.left, width: position.width }}
@ -546,9 +547,7 @@ const ProjectGantt: React.FC<ProjectGanttProps> = ({ employeeId }) => {
<div className="flex items-center gap-3">
<div>
<h2 className="text-2xl font-bold text-gray-900">İş Yükü ve Proje Takibi</h2>
<p className="text-gray-600">
Tüm görevlerinizi merkezi bir noktadan yönetin.
</p>
<p className="text-gray-600">Tüm görevlerinizi merkezi bir noktadan yönetin.</p>
</div>
</div>
@ -592,7 +591,7 @@ const ProjectGantt: React.FC<ProjectGanttProps> = ({ employeeId }) => {
<option value="">Tüm Çalışanlar</option>
{mockEmployees.map((emp) => (
<option key={emp.id} value={emp.id}>
{emp.firstName} {emp.lastName}
{emp.fullName}
</option>
))}
</select>
@ -602,10 +601,18 @@ const ProjectGantt: React.FC<ProjectGanttProps> = ({ employeeId }) => {
onChange={(e) => setViewMode(e.target.value as 'day' | 'week' | 'month' | 'year')}
className="px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-full sm:w-auto"
>
<option value="day">Günlük</option>
<option value="week">Haftalık</option>
<option value="month">Aylık</option>
<option value="year">Yıllık</option>
<option value={FrequencyUnitEnum.Days}>
{getFrequencyUnitText(FrequencyUnitEnum.Days)}
</option>
<option value={FrequencyUnitEnum.Weeks}>
{getFrequencyUnitText(FrequencyUnitEnum.Weeks)}
</option>
<option value={FrequencyUnitEnum.Months}>
{getFrequencyUnitText(FrequencyUnitEnum.Months)}
</option>
<option value={FrequencyUnitEnum.Years}>
{getFrequencyUnitText(FrequencyUnitEnum.Years)}
</option>
</select>
</div>
</div>

View file

@ -201,11 +201,11 @@ const ProjectList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={ProjectStatusEnum.Planning}>Planlama</option>
<option value={ProjectStatusEnum.Active}>Aktif</option>
<option value={ProjectStatusEnum.OnHold}>Beklemede</option>
<option value={ProjectStatusEnum.Completed}>Tamamlandı</option>
<option value={ProjectStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(ProjectStatusEnum).map((status) => (
<option key={status} value={status}>
{getProjectStatusText(status)}
</option>
))}
</select>
</div>
@ -217,10 +217,11 @@ const ProjectList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>

View file

@ -12,7 +12,12 @@ import {
FaSave,
FaProjectDiagram,
} from 'react-icons/fa'
import { PhaseStatusEnum, PsProjectPhase, ProjectStatusEnum } from '../../../types/ps'
import {
PhaseStatusEnum,
PsProjectPhase,
ProjectStatusEnum,
PhaseCategoryEnum,
} from '../../../types/ps'
import { mockProjectPhases } from '../../../mocks/mockProjectPhases'
import { mockProjects } from '../../../mocks/mockProjects'
import MultiSelectTeam from '../../../components/common/MultiSelectTeam'
@ -23,6 +28,8 @@ import {
getPhaseStatusIcon,
getPhaseStatusText,
getPhaseStatusColor,
getProjectStatusText,
getPhaseCategoryText,
} from '../../../utils/erp'
import { Container } from '@/components/shared'
@ -45,7 +52,7 @@ const ProjectPhases: React.FC = () => {
startDate: '',
endDate: '',
budget: 0,
category: '',
category: PhaseCategoryEnum.Planning,
assignedTeams: [] as string[],
})
@ -93,7 +100,7 @@ const ProjectPhases: React.FC = () => {
startDate: '',
endDate: '',
budget: 0,
category: '',
category: PhaseCategoryEnum.Planning,
assignedTeams: [],
})
setIsCreateModalOpen(true)
@ -247,11 +254,11 @@ const ProjectPhases: React.FC = () => {
className="px-2 py-1 text-sm border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500"
>
<option value="All">Tüm Durumlar</option>
<option value={ProjectStatusEnum.Planning}>Başlanmadı</option>
<option value={ProjectStatusEnum.Active}>Devam Ediyor</option>
<option value={ProjectStatusEnum.OnHold}>Beklemede</option>
<option value={ProjectStatusEnum.Completed}>Tamamlandı</option>
<option value={ProjectStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(ProjectStatusEnum).map((status) => (
<option key={status} value={status}>
{getProjectStatusText(status)}
</option>
))}
</select>
</div>
@ -862,11 +869,11 @@ const ProjectPhases: React.FC = () => {
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value="">Kategori seçin...</option>
<option value="Planning">Planlama</option>
<option value="Development">Geliştirme</option>
<option value="Testing">Test</option>
<option value="Deployment">Dağıtım</option>
<option value="Design">Tasarım</option>
{Object.values(PhaseCategoryEnum).map((cat) => (
<option key={cat} value={cat}>
{getPhaseCategoryText(cat)}
</option>
))}
</select>
</div>
@ -880,11 +887,11 @@ const ProjectPhases: React.FC = () => {
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value={PhaseStatusEnum.NotStarted}>Başlanmadı</option>
<option value={PhaseStatusEnum.InProgress}>Devam Ediyor</option>
<option value={PhaseStatusEnum.Completed}>Tamamlandı</option>
<option value={PhaseStatusEnum.OnHold}>Beklemede</option>
<option value={PhaseStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(PhaseStatusEnum).map((status) => (
<option key={status} value={status}>
{getPhaseStatusText(status)}
</option>
))}
</select>
</div>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState } from "react";
import { PsProjectTask, TaskTypeEnum, TaskStatusEnum } from "../../../types/ps";
import React, { useState } from 'react'
import { PsProjectTask, TaskTypeEnum, TaskStatusEnum } from '../../../types/ps'
import {
FaSearch,
FaPlus,
@ -13,158 +13,157 @@ import {
FaFlag,
FaProjectDiagram,
FaUserCog,
} from "react-icons/fa";
import { mockProjectTasks } from "../../../mocks/mockProjectTasks";
import { mockEmployees } from "../../../mocks/mockEmployees";
import { mockProjects } from "../../../mocks/mockProjects";
import { mockProjectPhases } from "../../../mocks/mockProjectPhases";
import Widget from "../../../components/common/Widget";
import { PriorityEnum } from "../../../types/common";
} from 'react-icons/fa'
import { mockProjectTasks } from '../../../mocks/mockProjectTasks'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { mockProjects } from '../../../mocks/mockProjects'
import { mockProjectPhases } from '../../../mocks/mockProjectPhases'
import Widget from '../../../components/common/Widget'
import { PriorityEnum } from '../../../types/common'
import {
getTaskStatusColor,
getTaskStatusIcon,
getPriorityColor,
getTaskTypeColor,
} from "../../../utils/erp";
import { Container } from "@/components/shared";
getPriorityText,
getTaskStatusText,
getTaskTypeText,
} from '../../../utils/erp'
import { Container } from '@/components/shared'
const ProjectTasks: React.FC = () => {
const [searchTerm, setSearchTerm] = useState("");
const [statusFilter, setStatusFilter] = useState<TaskStatusEnum | "">("");
const [selectedProjectFilter, setSelectedProjectFilter] = useState("All");
const [selectedTask, setSelectedTask] = useState<PsProjectTask | null>(null);
const [isModalOpen, setIsModalOpen] = useState(false);
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [editingTask, setEditingTask] = useState<PsProjectTask | null>(null);
const [searchTerm, setSearchTerm] = useState('')
const [statusFilter, setStatusFilter] = useState<TaskStatusEnum | ''>('')
const [selectedProjectFilter, setSelectedProjectFilter] = useState('All')
const [selectedTask, setSelectedTask] = useState<PsProjectTask | null>(null)
const [isModalOpen, setIsModalOpen] = useState(false)
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false)
const [isEditModalOpen, setIsEditModalOpen] = useState(false)
const [editingTask, setEditingTask] = useState<PsProjectTask | null>(null)
// Form state for creating/editing tasks
const [formData, setFormData] = useState({
name: "",
description: "",
projectId: "",
phaseId: "",
name: '',
description: '',
projectId: '',
phaseId: '',
taskType: TaskTypeEnum.Development,
status: TaskStatusEnum.NotStarted,
priority: PriorityEnum.Normal,
assignedTo: "",
assigneeEmail: "",
startDate: "",
endDate: "",
assignedTo: '',
assigneeEmail: '',
startDate: '',
endDate: '',
estimatedHours: 0,
progress: 0,
});
})
const filteredTasks = mockProjectTasks.filter((task) => {
const matchesSearch =
task.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
task.taskCode.toLowerCase().includes(searchTerm.toLowerCase()) ||
(task.description &&
task.description.toLowerCase().includes(searchTerm.toLowerCase()));
const matchesStatus = statusFilter === "" || task.status === statusFilter;
(task.description && task.description.toLowerCase().includes(searchTerm.toLowerCase()))
const matchesStatus = statusFilter === '' || task.status === statusFilter
const matchesProject =
selectedProjectFilter === "All" ||
task.projectId === selectedProjectFilter;
return matchesSearch && matchesStatus && matchesProject;
});
selectedProjectFilter === 'All' || task.projectId === selectedProjectFilter
return matchesSearch && matchesStatus && matchesProject
})
const openModal = (task: PsProjectTask) => {
setSelectedTask(task);
setIsModalOpen(true);
};
setSelectedTask(task)
setIsModalOpen(true)
}
const closeModal = () => {
setSelectedTask(null);
setIsModalOpen(false);
};
setSelectedTask(null)
setIsModalOpen(false)
}
const openCreateModal = () => {
setFormData({
name: "",
description: "",
projectId: "",
phaseId: "",
name: '',
description: '',
projectId: '',
phaseId: '',
taskType: TaskTypeEnum.Development,
status: TaskStatusEnum.NotStarted,
priority: PriorityEnum.Normal,
assignedTo: "",
assigneeEmail: "",
startDate: "",
endDate: "",
assignedTo: '',
assigneeEmail: '',
startDate: '',
endDate: '',
estimatedHours: 0,
progress: 0,
});
setIsCreateModalOpen(true);
};
})
setIsCreateModalOpen(true)
}
const closeCreateModal = () => {
setIsCreateModalOpen(false);
};
setIsCreateModalOpen(false)
}
const openEditModal = (task: PsProjectTask) => {
setEditingTask(task);
setEditingTask(task)
setFormData({
name: task.name,
description: task.description || "",
projectId: task.projectId || "",
phaseId: task.phaseId || "",
description: task.description || '',
projectId: task.projectId || '',
phaseId: task.phaseId || '',
taskType: task.taskType,
status: task.status,
priority: task.priority,
assignedTo: task.assignedTo || "",
assigneeEmail: task.assignee?.email || "",
startDate: task.startDate.toISOString().split("T")[0],
endDate: task.endDate.toISOString().split("T")[0],
assignedTo: task.assignedTo || '',
assigneeEmail: task.assignee?.email || '',
startDate: task.startDate.toISOString().split('T')[0],
endDate: task.endDate.toISOString().split('T')[0],
estimatedHours: task.estimatedHours,
progress: task.progress,
});
setIsEditModalOpen(true);
};
})
setIsEditModalOpen(true)
}
const closeEditModal = () => {
setIsEditModalOpen(false);
setEditingTask(null);
};
setIsEditModalOpen(false)
setEditingTask(null)
}
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>,
) => {
const { name, value } = e.target;
const { name, value } = e.target
// Eğer atanan kişi seçimi yapılıyorsa, e-posta adresini otomatik doldur
if (name === "assignedTo") {
const selectedEmployee = mockEmployees.find((emp) => emp.id === value);
if (name === 'assignedTo') {
const selectedEmployee = mockEmployees.find((emp) => emp.id === value)
setFormData((prev) => ({
...prev,
[name]: value,
assigneeEmail: selectedEmployee?.email || "",
}));
assigneeEmail: selectedEmployee?.email || '',
}))
} else {
setFormData((prev) => ({
...prev,
[name]: value,
}));
}))
}
};
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault()
// Here you would normally save to backend
console.log("Saving task:", formData);
alert(isEditModalOpen ? "Görev güncellendi!" : "Yeni görev oluşturuldu!");
console.log('Saving task:', formData)
alert(isEditModalOpen ? 'Görev güncellendi!' : 'Yeni görev oluşturuldu!')
if (isEditModalOpen) {
closeEditModal();
closeEditModal()
} else {
closeCreateModal();
closeCreateModal()
}
};
}
const generateTaskCode = () => {
const taskCount = mockProjectTasks.length + 1;
return `TSK-${taskCount.toString().padStart(3, "0")}`;
};
const taskCount = mockProjectTasks.length + 1
return `TSK-${taskCount.toString().padStart(3, '0')}`
}
return (
<Container>
@ -172,9 +171,7 @@ const ProjectTasks: React.FC = () => {
<div className="flex items-center justify-between mb-4">
<div>
<h2 className="text-2xl font-bold text-gray-900">Görev Yönetimi</h2>
<p className="text-gray-600">
Proje görevlerinizi oluşturun, düzenleyin ve takip edin
</p>
<p className="text-gray-600">Proje görevlerinizi oluşturun, düzenleyin ve takip edin</p>
</div>
<button
onClick={openCreateModal}
@ -196,22 +193,14 @@ const ProjectTasks: React.FC = () => {
<Widget
title="Devam Eden"
value={
mockProjectTasks.filter(
(t) => t.status === TaskStatusEnum.InProgress
).length
}
value={mockProjectTasks.filter((t) => t.status === TaskStatusEnum.InProgress).length}
color="yellow"
icon="FaClock"
/>
<Widget
title="Tamamlanan"
value={
mockProjectTasks.filter(
(t) => t.status === TaskStatusEnum.Completed
).length
}
value={mockProjectTasks.filter((t) => t.status === TaskStatusEnum.Completed).length}
color="green"
icon="FaCheckCircle"
/>
@ -222,9 +211,9 @@ const ProjectTasks: React.FC = () => {
mockProjectTasks.length > 0
? `${Math.round(
mockProjectTasks.reduce((sum, t) => sum + t.progress, 0) /
mockProjectTasks.length
mockProjectTasks.length,
)}%`
: "0%"
: '0%'
}
color="red"
icon="FaBullseye"
@ -260,17 +249,15 @@ const ProjectTasks: React.FC = () => {
<select
value={statusFilter}
onChange={(e) =>
setStatusFilter(e.target.value as TaskStatusEnum | "")
}
onChange={(e) => setStatusFilter(e.target.value as TaskStatusEnum | '')}
className="w-full px-2.5 py-1 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="">Tüm Durumlar</option>
<option value={TaskStatusEnum.NotStarted}>Başlanmadı</option>
<option value={TaskStatusEnum.InProgress}>Devam Ediyor</option>
<option value={TaskStatusEnum.Completed}>Tamamlandı</option>
<option value={TaskStatusEnum.OnHold}>Beklemede</option>
<option value={TaskStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(TaskStatusEnum).map((status) => (
<option key={status} value={status}>
{getTaskStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -316,25 +303,21 @@ const ProjectTasks: React.FC = () => {
<tr
key={task.id}
className={`hover:bg-blue-50 transition-colors duration-200 ${
index % 2 === 0 ? "bg-white" : "bg-gray-50"
index % 2 === 0 ? 'bg-white' : 'bg-gray-50'
}`}
>
<td className="px-2 py-1 whitespace-nowrap">
<div>
<div className="text-sm font-medium text-blue-700">
{(() => {
const project = mockProjects.find(
(p) => p.id === task.projectId
);
return project?.name || `Proje ID: ${task.projectId}`;
const project = mockProjects.find((p) => p.id === task.projectId)
return project?.name || `Proje ID: ${task.projectId}`
})()}
</div>
<div className="text-xs text-gray-500">
{(() => {
const project = mockProjects.find(
(p) => p.id === task.projectId
);
return project?.code || task.projectId;
const project = mockProjects.find((p) => p.id === task.projectId)
return project?.code || task.projectId
})()}
</div>
</div>
@ -344,19 +327,15 @@ const ProjectTasks: React.FC = () => {
<div className="text-sm font-medium text-green-700">
{task.phase?.name ||
(() => {
const phase = mockProjectPhases.find(
(p) => p.id === task.phaseId
);
return phase?.name || `Aşama ID: ${task.phaseId}`;
const phase = mockProjectPhases.find((p) => p.id === task.phaseId)
return phase?.name || `Aşama ID: ${task.phaseId}`
})()}
</div>
<div className="text-xs text-gray-500">
{task.phase?.code ||
(() => {
const phase = mockProjectPhases.find(
(p) => p.id === task.phaseId
);
return phase?.code || task.phaseId;
const phase = mockProjectPhases.find((p) => p.id === task.phaseId)
return phase?.code || task.phaseId
})()}
</div>
</div>
@ -375,7 +354,7 @@ const ProjectTasks: React.FC = () => {
<td className="px-2 py-1 whitespace-nowrap">
<span
className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full text-xs font-semibold ${getTaskStatusColor(
task.status
task.status,
)}`}
>
{getTaskStatusIcon(task.status)}
@ -385,7 +364,7 @@ const ProjectTasks: React.FC = () => {
<td className="px-2 py-1 whitespace-nowrap">
<span
className={`inline-flex items-center px-1.5 py-0.5 rounded-full text-xs font-semibold ${getPriorityColor(
task.priority
task.priority,
)}`}
>
{task.priority}
@ -397,7 +376,7 @@ const ProjectTasks: React.FC = () => {
<FaUser className="w-4 h-4 text-blue-600" />
</div>
<div className="text-sm text-gray-900 font-medium">
{task.assignee?.fullName || "-"}
{task.assignee?.fullName || '-'}
</div>
</div>
</td>
@ -415,7 +394,7 @@ const ProjectTasks: React.FC = () => {
</div>
</td>
<td className="px-2 py-1 whitespace-nowrap text-sm text-gray-900 font-medium">
{task.endDate.toLocaleDateString("tr-TR")}
{task.endDate.toLocaleDateString('tr-TR')}
</td>
<td className="px-2 py-1 whitespace-nowrap text-sm font-medium">
<div className="flex gap-1 justify-center">
@ -446,12 +425,9 @@ const ProjectTasks: React.FC = () => {
<div className="w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-2">
<FaBullseye className="w-6 h-6 text-gray-400" />
</div>
<h3 className="text-base font-medium text-gray-900 mb-1">
Görev bulunamadı
</h3>
<h3 className="text-base font-medium text-gray-900 mb-1">Görev bulunamadı</h3>
<p className="text-gray-500">
Arama kriterlerinizi değiştirmeyi deneyin veya yeni bir görev
oluşturun.
Arama kriterlerinizi değiştirmeyi deneyin veya yeni bir görev oluşturun.
</p>
</div>
)}
@ -500,20 +476,17 @@ const ProjectTasks: React.FC = () => {
<div className="text-sm font-semibold text-blue-800">
{(() => {
const project = mockProjects.find(
(p) => p.id === selectedTask.projectId
);
return (
project?.name ||
`Proje ID: ${selectedTask.projectId}`
);
(p) => p.id === selectedTask.projectId,
)
return project?.name || `Proje ID: ${selectedTask.projectId}`
})()}
</div>
<div className="text-xs text-blue-600 mt-1">
{(() => {
const project = mockProjects.find(
(p) => p.id === selectedTask.projectId
);
return project?.code || selectedTask.projectId;
(p) => p.id === selectedTask.projectId,
)
return project?.code || selectedTask.projectId
})()}
</div>
</div>
@ -528,21 +501,18 @@ const ProjectTasks: React.FC = () => {
{selectedTask.phase?.name ||
(() => {
const phase = mockProjectPhases.find(
(p) => p.id === selectedTask.phaseId
);
return (
phase?.name ||
`Aşama ID: ${selectedTask.phaseId}`
);
(p) => p.id === selectedTask.phaseId,
)
return phase?.name || `Aşama ID: ${selectedTask.phaseId}`
})()}
</div>
<div className="text-xs text-green-600 mt-1">
{selectedTask.phase?.code ||
(() => {
const phase = mockProjectPhases.find(
(p) => p.id === selectedTask.phaseId
);
return phase?.code || selectedTask.phaseId;
(p) => p.id === selectedTask.phaseId,
)
return phase?.code || selectedTask.phaseId
})()}
</div>
</div>
@ -554,7 +524,7 @@ const ProjectTasks: React.FC = () => {
ıklama
</label>
<p className="text-sm text-gray-900 bg-white p-2 rounded-lg border">
{selectedTask.description || "Açıklama bulunmuyor."}
{selectedTask.description || 'Açıklama bulunmuyor.'}
</p>
</div>
@ -565,7 +535,7 @@ const ProjectTasks: React.FC = () => {
</label>
<span
className={`inline-flex items-center px-2 py-1 rounded-lg text-xs font-semibold ${getTaskTypeColor(
selectedTask.taskType
selectedTask.taskType,
)}`}
>
{selectedTask.taskType}
@ -577,7 +547,7 @@ const ProjectTasks: React.FC = () => {
</label>
<span
className={`inline-flex items-center gap-1.5 px-2 py-1 rounded-lg text-xs font-semibold ${getTaskStatusColor(
selectedTask.status
selectedTask.status,
)}`}
>
{getTaskStatusIcon(selectedTask.status)}
@ -592,7 +562,7 @@ const ProjectTasks: React.FC = () => {
</label>
<span
className={`inline-flex items-center px-2 py-1 rounded-lg text-xs font-semibold ${getPriorityColor(
selectedTask.priority
selectedTask.priority,
)}`}
>
{selectedTask.priority}
@ -612,9 +582,7 @@ const ProjectTasks: React.FC = () => {
<p className="text-sm font-medium text-gray-900">
{selectedTask.assignee.fullName}
</p>
<p className="text-sm text-gray-500">
{selectedTask.assignee.email}
</p>
<p className="text-sm text-gray-500">{selectedTask.assignee.email}</p>
</div>
</div>
) : (
@ -641,7 +609,7 @@ const ProjectTasks: React.FC = () => {
Planlanan Başlangıç
</label>
<p className="text-sm text-gray-900 font-medium">
{selectedTask.startDate.toLocaleDateString("tr-TR")}
{selectedTask.startDate.toLocaleDateString('tr-TR')}
</p>
</div>
<div className="bg-white p-2 rounded-lg border">
@ -649,9 +617,8 @@ const ProjectTasks: React.FC = () => {
Gerçek Başlangıç
</label>
<p className="text-sm text-gray-900 font-medium">
{selectedTask.actualStartDate?.toLocaleDateString(
"tr-TR"
) || "Henüz başlanmadı"}
{selectedTask.actualStartDate?.toLocaleDateString('tr-TR') ||
'Henüz başlanmadı'}
</p>
</div>
</div>
@ -662,7 +629,7 @@ const ProjectTasks: React.FC = () => {
Planlanan Bitiş
</label>
<p className="text-sm text-gray-900 font-medium">
{selectedTask.endDate.toLocaleDateString("tr-TR")}
{selectedTask.endDate.toLocaleDateString('tr-TR')}
</p>
</div>
<div className="bg-white p-2 rounded-lg border">
@ -670,9 +637,8 @@ const ProjectTasks: React.FC = () => {
Gerçek Bitiş
</label>
<p className="text-sm text-gray-900 font-medium">
{selectedTask.actualEndDate?.toLocaleDateString(
"tr-TR"
) || "Henüz tamamlanmadı"}
{selectedTask.actualEndDate?.toLocaleDateString('tr-TR') ||
'Henüz tamamlanmadı'}
</p>
</div>
</div>
@ -727,9 +693,7 @@ const ProjectTasks: React.FC = () => {
Oluşturulma
</label>
<p className="text-sm text-gray-500">
{selectedTask.creationTime.toLocaleDateString(
"tr-TR"
)}
{selectedTask.creationTime.toLocaleDateString('tr-TR')}
</p>
</div>
<div>
@ -737,9 +701,7 @@ const ProjectTasks: React.FC = () => {
Son Güncelleme
</label>
<p className="text-sm text-gray-500">
{selectedTask.lastModificationTime.toLocaleDateString(
"tr-TR"
)}
{selectedTask.lastModificationTime.toLocaleDateString('tr-TR')}
</p>
</div>
</div>
@ -759,8 +721,8 @@ const ProjectTasks: React.FC = () => {
</button>
<button
onClick={() => {
closeModal();
openEditModal(selectedTask!);
closeModal()
openEditModal(selectedTask!)
}}
className="px-3 py-1 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-1.5 shadow-sm"
>
@ -788,12 +750,12 @@ const ProjectTasks: React.FC = () => {
</div>
<div>
<h3 className="text-lg font-bold text-gray-900">
{isEditModalOpen ? "Görev Düzenle" : "Yeni Görev Oluştur"}
{isEditModalOpen ? 'Görev Düzenle' : 'Yeni Görev Oluştur'}
</h3>
<p className="text-xs text-gray-600">
{isEditModalOpen
? "Mevcut görev bilgilerini güncelleyin"
: "Yeni bir görev tanımlayın"}
? 'Mevcut görev bilgilerini güncelleyin'
: 'Yeni bir görev tanımlayın'}
</p>
</div>
</div>
@ -850,16 +812,11 @@ const ProjectTasks: React.FC = () => {
disabled={!formData.projectId}
>
<option value="">
{formData.projectId
? "Aşama seçin..."
: "Önce proje seçin"}
{formData.projectId ? 'Aşama seçin...' : 'Önce proje seçin'}
</option>
{formData.projectId &&
mockProjectPhases
.filter(
(phase) =>
phase.projectId === formData.projectId
)
.filter((phase) => phase.projectId === formData.projectId)
.map((phase) => (
<option key={phase.id} value={phase.id}>
{phase.code} - {phase.name}
@ -907,18 +864,11 @@ const ProjectTasks: React.FC = () => {
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value={TaskTypeEnum.Development}>
Geliştirme
</option>
<option value={TaskTypeEnum.Testing}>Test</option>
<option value={TaskTypeEnum.Documentation}>
Dokümantasyon
</option>
<option value={TaskTypeEnum.Review}>İnceleme</option>
<option value={TaskTypeEnum.Deployment}>
Dağıtım
</option>
<option value={TaskTypeEnum.Meeting}>Toplantı</option>
{Object.values(TaskTypeEnum).map((type) => (
<option key={type} value={type}>
{getTaskTypeText(type)}
</option>
))}
</select>
</div>
@ -932,10 +882,11 @@ const ProjectTasks: React.FC = () => {
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
@ -949,21 +900,11 @@ const ProjectTasks: React.FC = () => {
onChange={handleInputChange}
className="w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
>
<option value={TaskStatusEnum.NotStarted}>
Başlanmadı
</option>
<option value={TaskStatusEnum.InProgress}>
Devam Ediyor
</option>
<option value={TaskStatusEnum.Completed}>
Tamamlandı
</option>
<option value={TaskStatusEnum.OnHold}>
Beklemede
</option>
<option value={TaskStatusEnum.Cancelled}>
İptal Edildi
</option>
{Object.values(TaskStatusEnum).map((status) => (
<option key={status} value={status}>
{getTaskStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -994,8 +935,7 @@ const ProjectTasks: React.FC = () => {
.filter((emp) => emp.isActive)
.map((employee) => (
<option key={employee.id} value={employee.id}>
{employee.fullName} -{" "}
{employee.jobPosition?.name}
{employee.fullName} - {employee.jobPosition?.name}
</option>
))}
</select>
@ -1021,8 +961,8 @@ const ProjectTasks: React.FC = () => {
<div className="bg-blue-50 p-2 rounded-lg border border-blue-200">
{(() => {
const selectedEmployee = mockEmployees.find(
(emp) => emp.id === formData.assignedTo
);
(emp) => emp.id === formData.assignedTo,
)
return selectedEmployee ? (
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-gradient-to-br from-blue-100 to-blue-200 rounded-full flex items-center justify-center">
@ -1040,7 +980,7 @@ const ProjectTasks: React.FC = () => {
</p>
</div>
</div>
) : null;
) : null
})()}
</div>
)}
@ -1126,9 +1066,7 @@ const ProjectTasks: React.FC = () => {
<FaFlag className="w-4 h-4" />
<span className="text-sm font-medium">Görev Kodu:</span>
<span className="font-bold">
{isEditModalOpen
? editingTask?.taskCode
: generateTaskCode()}
{isEditModalOpen ? editingTask?.taskCode : generateTaskCode()}
</span>
</div>
</div>
@ -1150,7 +1088,7 @@ const ProjectTasks: React.FC = () => {
className="px-3 py-1 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-1.5 shadow-md"
>
<FaSave className="w-4 h-4" />
{isEditModalOpen ? "Güncelle" : "Oluştur"}
{isEditModalOpen ? 'Güncelle' : 'Oluştur'}
</button>
</div>
</form>
@ -1158,8 +1096,7 @@ const ProjectTasks: React.FC = () => {
</div>
)}
</Container>
)
}
);
};
export default ProjectTasks;
export default ProjectTasks

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from "react";
import { PsProjectTask, TaskTypeEnum, TaskStatusEnum } from "../../../types/ps";
import React, { useState, useEffect } from 'react'
import { PsProjectTask, TaskTypeEnum, TaskStatusEnum } from '../../../types/ps'
import {
FaPlus,
FaEdit,
@ -10,39 +10,40 @@ import {
FaUserCog,
FaSave,
FaTimesCircle,
} from "react-icons/fa";
import { mockEmployees } from "../../../mocks/mockEmployees";
import { mockProjects } from "../../../mocks/mockProjects";
import { mockProjectPhases } from "../../../mocks/mockProjectPhases";
import { PriorityEnum } from "../../../types/common";
} from 'react-icons/fa'
import { mockEmployees } from '../../../mocks/mockEmployees'
import { mockProjects } from '../../../mocks/mockProjects'
import { mockProjectPhases } from '../../../mocks/mockProjectPhases'
import { PriorityEnum } from '../../../types/common'
import { getPriorityText, getTaskStatusText, getTaskTypeText } from '@/utils/erp'
export interface TaskFormData {
name: string;
description: string;
projectId: string;
phaseId: string;
taskType: TaskTypeEnum;
status: TaskStatusEnum;
priority: PriorityEnum;
assignedTo: string;
assigneeEmail: string;
startDate: string;
endDate: string;
estimatedHours: number;
progress: number;
name: string
description: string
projectId: string
phaseId: string
taskType: TaskTypeEnum
status: TaskStatusEnum
priority: PriorityEnum
assignedTo: string
assigneeEmail: string
startDate: string
endDate: string
estimatedHours: number
progress: number
}
interface TaskEditModalProps {
isOpen: boolean;
onClose: () => void;
task?: PsProjectTask | null;
onSubmit: (taskData: TaskFormData) => void;
mode: "create" | "edit";
defaultProjectId?: string;
isOpen: boolean
onClose: () => void
task?: PsProjectTask | null
onSubmit: (taskData: TaskFormData) => void
mode: 'create' | 'edit'
defaultProjectId?: string
}
const inputClasses =
"w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors";
'w-full px-2.5 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors'
const TaskEditModal: React.FC<TaskEditModalProps> = ({
isOpen,
@ -53,91 +54,89 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
defaultProjectId,
}) => {
const [formData, setFormData] = useState<TaskFormData>({
name: "",
description: "",
projectId: "",
phaseId: "",
name: '',
description: '',
projectId: '',
phaseId: '',
taskType: TaskTypeEnum.Development,
status: TaskStatusEnum.NotStarted,
priority: PriorityEnum.Normal,
assignedTo: "",
assigneeEmail: "",
startDate: "",
endDate: "",
assignedTo: '',
assigneeEmail: '',
startDate: '',
endDate: '',
estimatedHours: 0,
progress: 0,
});
})
const generateTaskCode = () => {
const taskCount = 1; // Bu gerçek uygulamada dinamik olarak hesaplanmalı
return `TSK-${taskCount.toString().padStart(3, "0")}`;
};
const taskCount = 1 // Bu gerçek uygulamada dinamik olarak hesaplanmalı
return `TSK-${taskCount.toString().padStart(3, '0')}`
}
useEffect(() => {
if (mode === "edit" && task) {
if (mode === 'edit' && task) {
setFormData({
name: task.name,
description: task.description || "",
description: task.description || '',
projectId: task.projectId,
phaseId: task.phaseId || "",
phaseId: task.phaseId || '',
taskType: task.taskType,
status: task.status,
priority: task.priority,
assignedTo: task.assignedTo || "",
assigneeEmail: task.assignee?.email || "",
startDate: task.startDate.toISOString().split("T")[0],
endDate: task.endDate.toISOString().split("T")[0],
assignedTo: task.assignedTo || '',
assigneeEmail: task.assignee?.email || '',
startDate: task.startDate.toISOString().split('T')[0],
endDate: task.endDate.toISOString().split('T')[0],
estimatedHours: task.estimatedHours,
progress: task.progress,
});
})
} else {
// Reset form for create mode
setFormData({
name: "",
description: "",
projectId: defaultProjectId || "",
phaseId: "",
name: '',
description: '',
projectId: defaultProjectId || '',
phaseId: '',
taskType: TaskTypeEnum.Development,
status: TaskStatusEnum.NotStarted,
priority: PriorityEnum.Normal,
assignedTo: "",
assigneeEmail: "",
startDate: "",
endDate: "",
assignedTo: '',
assigneeEmail: '',
startDate: '',
endDate: '',
estimatedHours: 0,
progress: 0,
});
})
}
}, [mode, task, isOpen, defaultProjectId]);
}, [mode, task, isOpen, defaultProjectId])
const handleInputChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
) => {
const { name, value } = e.target;
const { name, value } = e.target
setFormData((prev) => ({
...prev,
[name]: value,
}));
}))
// Auto-fill email when employee is selected
if (name === "assignedTo") {
const selectedEmployee = mockEmployees.find((emp) => emp.id === value);
if (name === 'assignedTo') {
const selectedEmployee = mockEmployees.find((emp) => emp.id === value)
setFormData((prev) => ({
...prev,
assigneeEmail: selectedEmployee?.email || "",
}));
assigneeEmail: selectedEmployee?.email || '',
}))
}
};
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(formData);
onClose();
};
e.preventDefault()
onSubmit(formData)
onClose()
}
if (!isOpen) return null;
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
@ -146,7 +145,7 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
<div className="flex items-center justify-between p-2.5 border-b border-gray-200 bg-gradient-to-r from-blue-50 to-indigo-50 rounded-t-xl">
<div className="flex items-center gap-2">
<div className="w-6 h-6 bg-blue-600 rounded-md flex items-center justify-center">
{mode === "edit" ? (
{mode === 'edit' ? (
<FaEdit className="w-3.5 h-3.5 text-white" />
) : (
<FaPlus className="w-3.5 h-3.5 text-white" />
@ -154,12 +153,12 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
</div>
<div>
<h3 className="text-lg font-bold text-gray-900">
{mode === "edit" ? "Görev Düzenle" : "Yeni Görev Oluştur"}
{mode === 'edit' ? 'Görev Düzenle' : 'Yeni Görev Oluştur'}
</h3>
<p className="text-xs text-gray-600">
{mode === "edit"
? "Mevcut görev bilgilerini güncelleyin"
: "Yeni bir görev tanımlayın"}
{mode === 'edit'
? 'Mevcut görev bilgilerini güncelleyin'
: 'Yeni bir görev tanımlayın'}
</p>
</div>
</div>
@ -217,15 +216,11 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
disabled={!formData.projectId}
>
<option value="">
{formData.projectId
? "Aşama seçin..."
: "Önce proje seçin"}
{formData.projectId ? 'Aşama seçin...' : 'Önce proje seçin'}
</option>
{formData.projectId &&
mockProjectPhases
.filter(
(phase) => phase.projectId === formData.projectId
)
.filter((phase) => phase.projectId === formData.projectId)
.map((phase) => (
<option key={phase.id} value={phase.id}>
{phase.code} - {phase.name}
@ -250,9 +245,7 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
ıklama
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">ıklama</label>
<textarea
name="description"
value={formData.description}
@ -273,59 +266,43 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
onChange={handleInputChange}
className={inputClasses}
>
<option value={TaskTypeEnum.Development}>
Geliştirme
</option>
<option value={TaskTypeEnum.Testing}>Test</option>
<option value={TaskTypeEnum.Documentation}>
Dokümantasyon
</option>
<option value={TaskTypeEnum.Review}>İnceleme</option>
<option value={TaskTypeEnum.Deployment}>Dağıtım</option>
<option value={TaskTypeEnum.Meeting}>Toplantı</option>
{Object.values(TaskTypeEnum).map((type) => (
<option key={type} value={type}>
{getTaskTypeText(type)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Öncelik
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Öncelik</label>
<select
name="priority"
value={formData.priority}
onChange={handleInputChange}
className={inputClasses}
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Durum
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">Durum</label>
<select
name="status"
value={formData.status}
onChange={handleInputChange}
className={inputClasses}
>
<option value={TaskStatusEnum.NotStarted}>
Başlanmadı
</option>
<option value={TaskStatusEnum.InProgress}>
Devam Ediyor
</option>
<option value={TaskStatusEnum.Completed}>
Tamamlandı
</option>
<option value={TaskStatusEnum.OnHold}>Beklemede</option>
<option value={TaskStatusEnum.Cancelled}>
İptal Edildi
</option>
{Object.values(TaskStatusEnum).map((status) => (
<option key={status} value={status}>
{getTaskStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -363,9 +340,7 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
E-posta
</label>
<label className="block text-sm font-medium text-gray-700 mb-1">E-posta</label>
<input
type="email"
name="assigneeEmail"
@ -381,8 +356,8 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
{formData.assignedTo &&
(() => {
const selectedEmployee = mockEmployees.find(
(emp) => emp.id === formData.assignedTo
);
(emp) => emp.id === formData.assignedTo,
)
return selectedEmployee ? (
<div className="bg-blue-50 p-2 rounded-lg border border-blue-200 flex items-center gap-2">
<div className="w-10 h-10 bg-gradient-to-br from-blue-100 to-blue-200 rounded-full flex items-center justify-center shrink-0">
@ -400,7 +375,7 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
</p>
</div>
</div>
) : null;
) : null
})()}
<div className="grid grid-cols-2 gap-2.5">
@ -448,7 +423,7 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
/>
</div>
{mode === "edit" && (
{mode === 'edit' && (
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
İlerleme (%)
@ -484,7 +459,7 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
<FaFlag className="w-4 h-4" />
<span className="text-sm font-medium">Görev Kodu:</span>
<span className="font-bold">
{mode === "edit" ? task?.taskCode : generateTaskCode()}
{mode === 'edit' ? task?.taskCode : generateTaskCode()}
</span>
</div>
</div>
@ -506,13 +481,13 @@ const TaskEditModal: React.FC<TaskEditModalProps> = ({
className="px-3 py-1 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-1.5 shadow-md hover:shadow-lg"
>
<FaSave className="w-4 h-4" />
{mode === "edit" ? "Güncelle" : "Oluştur"}
{mode === 'edit' ? 'Güncelle' : 'Oluştur'}
</button>
</div>
</form>
</div>
</div>
);
};
)
}
export default TaskEditModal;
export default TaskEditModal

View file

@ -8,6 +8,7 @@ import {
} from '../../../types/mm'
import MultiSelectEmployee from '../../../components/common/MultiSelectEmployee'
import { mockDepartments } from '../../../mocks/mockDepartments'
import { getApprovalLevelText, getRequestTypeText } from '@/utils/erp'
interface ApprovalWorkflowModalProps {
isOpen: boolean
@ -195,10 +196,11 @@ const ApprovalWorkflowModal: React.FC<ApprovalWorkflowModalProps> = ({
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={RequestTypeEnum.Material}>Malzeme</option>
<option value={RequestTypeEnum.Service}>Hizmet</option>
<option value={RequestTypeEnum.WorkCenter}>İş Merkezi</option>
<option value={RequestTypeEnum.Maintenance}>Bakım</option>
{Object.values(RequestTypeEnum).map((type) => (
<option key={type} value={type}>
{getRequestTypeText(type)}
</option>
))}
</select>
</div>
@ -276,14 +278,11 @@ const ApprovalWorkflowModal: React.FC<ApprovalWorkflowModalProps> = ({
disabled={isReadOnly}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={ApprovalLevelEnum.Supervisor}>Süpervizör</option>
<option value={ApprovalLevelEnum.Manager}>Müdür</option>
<option value={ApprovalLevelEnum.Director}>Direktör</option>
<option value={ApprovalLevelEnum.GeneralManager}>Genel Müdür</option>
<option value={ApprovalLevelEnum.FinanceManager}>
Mali İşler Müdürü
</option>
<option value={ApprovalLevelEnum.TechnicalManager}>Teknik Müdür</option>
{Object.values(ApprovalLevelEnum).map((lvl) => (
<option key={lvl} value={lvl}>
{getApprovalLevelText(lvl)}
</option>
))}
</select>
</div>

View file

@ -210,15 +210,11 @@ const DeliveryTracking: React.FC = () => {
className="pl-10 pr-4 py-1.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
>
<option value="all">Tüm Durumlar</option>
<option value={DeliveryStatusEnum.Preparing}>Hazırlanıyor</option>
<option value={DeliveryStatusEnum.Shipped}>Kargoya Verildi</option>
<option value={DeliveryStatusEnum.InTransit}>Yolda</option>
<option value={DeliveryStatusEnum.OutForDelivery}>Dağıtımda</option>
<option value={DeliveryStatusEnum.Delivered}>Teslim Edildi</option>
<option value={DeliveryStatusEnum.PartiallyDelivered}>Kısmi Teslim</option>
<option value={DeliveryStatusEnum.Delayed}>Gecikmeli</option>
<option value={DeliveryStatusEnum.Returned}>İade Edildi</option>
<option value={DeliveryStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(DeliveryStatusEnum).map((status) => (
<option key={status} value={status}>
{getDeliveryStatusText(status)}
</option>
))}
</select>
</div>
</div>

View file

@ -6,6 +6,9 @@ import {
QualityStatusEnum,
MmGoodsReceiptItem,
} from '../../../types/mm'
import { mock } from 'node:test'
import { mockWarehouses } from '@/mocks/mockWarehouses'
import { getQualityStatusText, getReceiptStatusText } from '@/utils/erp'
interface DeliveryTrackingModalProps {
isOpen: boolean
@ -226,10 +229,11 @@ const DeliveryTrackingModal: React.FC<DeliveryTrackingModalProps> = ({
required
>
<option value="">Depo Seçiniz</option>
<option value="WH001">Ana Depo</option>
<option value="WH002">Hammadde Deposu</option>
<option value="WH003">Mamul Deposu</option>
<option value="WH004">Yedek Parça Deposu</option>
{mockWarehouses.map((wh) => (
<option key={wh.id} value={wh.id}>
{wh.name}
</option>
))}
</select>
</div>
@ -242,10 +246,11 @@ const DeliveryTrackingModal: React.FC<DeliveryTrackingModalProps> = ({
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={ReceiptStatusEnum.Pending}>Beklemede</option>
<option value={ReceiptStatusEnum.InProgress}>İşlemde</option>
<option value={ReceiptStatusEnum.Completed}>Tamamlandı</option>
<option value={ReceiptStatusEnum.OnHold}>Bekletildi</option>
{Object.values(ReceiptStatusEnum).map((status) => (
<option key={status} value={status}>
{getReceiptStatusText(status)}
</option>
))}
</select>
</div>
@ -402,10 +407,11 @@ const DeliveryTrackingModal: React.FC<DeliveryTrackingModalProps> = ({
disabled={isReadOnly}
className="mt-1 block w-full text-sm border border-gray-300 rounded-md px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={QualityStatusEnum.Pending}>Beklemede</option>
<option value={QualityStatusEnum.Approved}>Kabul</option>
<option value={QualityStatusEnum.Rejected}>Red</option>
<option value={QualityStatusEnum.Conditional}>Koşullu</option>
{Object.values(QualityStatusEnum).map((status) => (
<option key={status} value={status}>
{getQualityStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -1,4 +1,5 @@
import { MaterialTypeEnum, MmMaterialType } from '@/types/mm'
import { getMaterialTypeText } from '@/utils/erp'
import { useState } from 'react'
interface MaterialTypeModalProps {
@ -43,12 +44,11 @@ const MaterialTypeModal: React.FC<MaterialTypeModalProps> = ({ type, onSave, onC
className="w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent"
required
>
<option value={MaterialTypeEnum.RawMaterial}>Hammadde</option>
<option value={MaterialTypeEnum.SemiFinished}>Yarı Mamul</option>
<option value={MaterialTypeEnum.Finished}>Mamul</option>
<option value={MaterialTypeEnum.Consumable}>Sarf Malzemesi</option>
<option value={MaterialTypeEnum.Service}>Hizmet</option>
<option value={MaterialTypeEnum.Spare}>Yedek Parça</option>
{Object.values(MaterialTypeEnum).map((value) => (
<option key={value} value={value}>
{getMaterialTypeText(value)}
</option>
))}
</select>
</div>

View file

@ -2,7 +2,7 @@ import React, { useState } from 'react'
import { FaPlus, FaEdit, FaTrash, FaSearch, FaTh, FaList } from 'react-icons/fa'
import { MmMaterialType, MaterialTypeEnum } from '../../../types/mm'
import { mockMaterialTypes } from '../../../mocks/mockMaterialTypes'
import { getMaterialTypeDisplay } from '../../../utils/erp'
import { getMaterialTypeText } from '../../../utils/erp'
import { Container } from '@/components/shared'
import MaterialTypeModal from './MaterialTypeModal'
@ -151,7 +151,7 @@ const MaterialTypes: React.FC = () => {
<tr key={type.id} className="hover:bg-gray-50 text-xs">
<td className="px-3 py-1.5 whitespace-nowrap">
<span className="text-sm font-mono font-medium text-gray-900">
{getMaterialTypeDisplay(type.code)}
{getMaterialTypeText(type.code)}
</span>
</td>
<td className="px-3 py-1.5 whitespace-nowrap">
@ -206,7 +206,7 @@ const MaterialTypes: React.FC = () => {
<div className="flex items-start justify-between mb-3">
<div className="flex-1">
<span className="text-xs font-mono font-medium text-blue-600 bg-blue-50 px-2 py-1 rounded">
{getMaterialTypeDisplay(type.code)}
{getMaterialTypeText(type.code)}
</span>
</div>
<div className="flex items-center space-x-1">

View file

@ -195,15 +195,11 @@ const OrderManagement: React.FC = () => {
className="pl-10 pr-4 py-1.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="all">Tüm Durumlar</option>
<option value={OrderStatusEnum.Draft}>Taslak</option>
<option value={OrderStatusEnum.Pending}>Beklemede</option>
<option value={OrderStatusEnum.Approved}>Onaylandı</option>
<option value={OrderStatusEnum.Sent}>Gönderildi</option>
<option value={OrderStatusEnum.Confirmed}>Onaylandı</option>
<option value={OrderStatusEnum.PartiallyDelivered}>Kısmi Teslim</option>
<option value={OrderStatusEnum.Delivered}>Teslim Edildi</option>
<option value={OrderStatusEnum.Completed}>Tamamlandı</option>
<option value={OrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(OrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getOrderStatusText(status)}
</option>
))}
</select>
</div>
</div>
@ -559,14 +555,11 @@ const OrderManagement: React.FC = () => {
defaultValue=""
>
<option value="">Durum Seçiniz</option>
<option value={OrderStatusEnum.Pending}>Beklemede</option>
<option value={OrderStatusEnum.Approved}>Onaylandı</option>
<option value={OrderStatusEnum.Sent}>Gönderildi</option>
<option value={OrderStatusEnum.Confirmed}>Onaylandı</option>
<option value={OrderStatusEnum.PartiallyDelivered}>Kısmi Teslim</option>
<option value={OrderStatusEnum.Delivered}>Teslim Edildi</option>
<option value={OrderStatusEnum.Completed}>Tamamlandı</option>
<option value={OrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(OrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getOrderStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -19,6 +19,8 @@ import { mockPurchaseOrders } from '../../../mocks/mockPurchaseOrders'
import { Address, PaymentTerms } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { getOrderStatusText, getPaymentTermsText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
const OrderManagementForm: React.FC = () => {
const { id } = useParams<{ id: string }>()
@ -318,14 +320,11 @@ const OrderManagementForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={PaymentTerms.Net15}>15 Gün Vadeli</option>
<option value={PaymentTerms.Net30}>30 Gün Vadeli</option>
<option value={PaymentTerms.Net45}>45 Gün Vadeli</option>
<option value={PaymentTerms.Net60}>60 Gün Vadeli</option>
<option value={PaymentTerms.Net90}>90 Gün Vadeli</option>
<option value={PaymentTerms.COD}>Kapıda Ödeme</option>
<option value={PaymentTerms.Prepaid}>Peşin</option>
<option value={PaymentTerms.Cash}>Nakit</option>
{Object.values(PaymentTerms).map((term) => (
<option key={term} value={term}>
{getPaymentTermsText(term)}
</option>
))}
</select>
</div>
@ -338,9 +337,11 @@ const OrderManagementForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
@ -654,14 +655,11 @@ const OrderManagementForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={OrderStatusEnum.Draft}>Taslak</option>
<option value={OrderStatusEnum.Sent}>Gönderildi</option>
<option value={OrderStatusEnum.Confirmed}>Onaylandı</option>
<option value={OrderStatusEnum.PartiallyReceived}>Kısmi Teslim</option>
<option value={OrderStatusEnum.Received}>Teslim Alındı</option>
<option value={OrderStatusEnum.Invoiced}>Faturalandı</option>
<option value={OrderStatusEnum.Closed}>Kapatıldı</option>
<option value={OrderStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(OrderStatusEnum).map((status) => (
<option key={status} value={status}>
{getOrderStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -21,6 +21,8 @@ import { mockPurchaseRequests } from '../../../mocks/mockPurchaseRequests'
import { PriorityEnum } from '../../../types/common'
import { Container } from '@/components/shared'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { getPriorityText, getRequestStatusText, getRequestTypeText } from '@/utils/erp'
import { mockCurrencies } from '@/mocks/mockCurrencies'
const PurchaseRequestForm: React.FC = () => {
const { id } = useParams<{ id: string }>()
@ -198,10 +200,11 @@ const PurchaseRequestForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={RequestTypeEnum.Material}>Malzeme</option>
<option value={RequestTypeEnum.Service}>Hizmet</option>
<option value={RequestTypeEnum.WorkCenter}>İş Merkezi</option>
<option value={RequestTypeEnum.Maintenance}>Bakım</option>
{Object.values(RequestTypeEnum).map((type) => (
<option key={type} value={type}>
{getRequestTypeText(type)}
</option>
))}
</select>
</div>
@ -294,10 +297,11 @@ const PurchaseRequestForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>
@ -310,9 +314,11 @@ const PurchaseRequestForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value="TRY">TRY</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
{mockCurrencies.map((currency) => (
<option key={currency.value} value={currency.value}>
{currency.value} - {currency.label}
</option>
))}
</select>
</div>
</div>
@ -500,12 +506,11 @@ const PurchaseRequestForm: React.FC = () => {
disabled={isReadOnly}
className="mt-1 block w-full border border-gray-300 rounded-md px-2.5 py-1.5 focus:outline-none focus:ring-1 focus:ring-blue-500"
>
<option value={RequestStatusEnum.Draft}>Taslak</option>
<option value={RequestStatusEnum.Submitted}>Gönderildi</option>
<option value={RequestStatusEnum.InReview}>İncelemede</option>
<option value={RequestStatusEnum.Approved}>Onaylandı</option>
<option value={RequestStatusEnum.Rejected}>Reddedildi</option>
<option value={RequestStatusEnum.Cancelled}>İptal Edildi</option>
{Object.values(RequestStatusEnum).map((status) => (
<option key={status} value={status}>
{getRequestStatusText(status)}
</option>
))}
</select>
</div>

View file

@ -96,23 +96,24 @@ const PurchaseRequests: React.FC = () => {
onChange={(e) => setFilterStatus(e.target.value as RequestStatusEnum | 'ALL')}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="ALL">Tüm Durumlar</option>
<option value={RequestStatusEnum.Draft}>Taslak</option>
<option value={RequestStatusEnum.Submitted}>Gönderildi</option>
<option value={RequestStatusEnum.InReview}>İnceleniyor</option>
<option value={RequestStatusEnum.Approved}>Onaylandı</option>
<option value={RequestStatusEnum.Rejected}>Reddedildi</option>
<option value="All">Tüm Durumlar</option>
{Object.values(RequestStatusEnum).map((status) => (
<option key={status} value={status}>
{getRequestStatusText(status)}
</option>
))}
</select>
<select
value={filterType}
onChange={(e) => setFilterType(e.target.value as RequestTypeEnum | 'ALL')}
className="px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="ALL">Tüm Türler</option>
<option value={RequestTypeEnum.Material}>Malzeme</option>
<option value={RequestTypeEnum.Service}>Hizmet</option>
<option value={RequestTypeEnum.WorkCenter}>İş Merkezi</option>
<option value={RequestTypeEnum.Maintenance}>Bakım</option>
<option value="All">Tüm Türler</option>
{Object.values(RequestTypeEnum).map((type) => (
<option key={type} value={type}>
{getRequestTypeText(type)}
</option>
))}
</select>
</div>

View file

@ -141,11 +141,11 @@ const PurchaseRequisitionList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={RequisitionStatusEnum.Draft}>Taslak</option>
<option value={RequisitionStatusEnum.Submitted}>Gönderildi</option>
<option value={RequisitionStatusEnum.InApproval}>Onayda</option>
<option value={RequisitionStatusEnum.Approved}>Onaylandı</option>
<option value={RequisitionStatusEnum.Rejected}>Reddedildi</option>
{Object.values(RequisitionStatusEnum).map((status) => (
<option key={status} value={status}>
{getRequisitionStatusText(status)}
</option>
))}
</select>
</div>
@ -157,10 +157,11 @@ const PurchaseRequisitionList: React.FC = () => {
className="w-full border border-gray-300 rounded-lg px-3 py-1.5 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
<option value="all">Tümü</option>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
{Object.values(PriorityEnum).map((priority) => (
<option key={priority} value={priority}>
{getPriorityText(priority)}
</option>
))}
</select>
</div>

Some files were not shown because too many files have changed in this diff Show more