erp modülleri route düzenlemesi

This commit is contained in:
Sedat ÖZTÜRK 2025-09-15 13:52:02 +03:00
parent a4f4a8d338
commit 02bb117798
5 changed files with 998 additions and 387 deletions

View file

@ -4684,6 +4684,773 @@
"componentPath": "@/views/classroom/PlanningPage", "componentPath": "@/views/classroom/PlanningPage",
"routeType": "protected", "routeType": "protected",
"authority": ["App.Classroom.Planning"] "authority": ["App.Classroom.Planning"]
},
{
"key": "admin.supplychain.materialTypes",
"path": "/admin/supplychain/materials/types",
"componentPath": "@/views/supplychain/components/MaterialTypes",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.materialGroups",
"path": "/admin/supplychain/materials/groups",
"componentPath": "@/views/supplychain/components/MaterialGroups",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.materials",
"path": "/admin/supplychain/materials",
"componentPath": "@/views/supplychain/components/MaterialList",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.materialsNew",
"path": "/admin/supplychain/materials/new",
"componentPath": "@/views/supplychain/components/MaterialForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.materialsEdit",
"path": "/admin/supplychain/materials/edit/:id",
"componentPath": "@/views/supplychain/components/MaterialForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.materialsDetail",
"path": "/admin/supplychain/materials/detail/:id",
"componentPath": "@/views/supplychain/components/MaterialCard",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.suppliers",
"path": "/admin/supplychain/suppliers",
"componentPath": "@/views/supplychain/components/SupplierCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.requests",
"path": "/admin/supplychain/requests",
"componentPath": "@/views/supplychain/components/PurchaseRequests",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.requestsNew",
"path": "/admin/supplychain/requests/new",
"componentPath": "@/views/supplychain/components/PurchaseRequestForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.requestsEdit",
"path": "/admin/supplychain/requests/edit/:id",
"componentPath": "@/views/supplychain/components/PurchaseRequestForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.requestsView",
"path": "/admin/supplychain/requests/view/:id",
"componentPath": "@/views/supplychain/components/PurchaseRequestForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.quotations",
"path": "/admin/supplychain/quotations",
"componentPath": "@/views/supplychain/components/QuotationManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.quotationsNew",
"path": "/admin/supplychain/quotations/new",
"componentPath": "@/views/supplychain/components/QuotationForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.quotationsEdit",
"path": "/admin/supplychain/quotations/edit/:id",
"componentPath": "@/views/supplychain/components/QuotationForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.quotationsView",
"path": "/admin/supplychain/quotations/view/:id",
"componentPath": "@/views/supplychain/components/QuotationForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.approvals",
"path": "/admin/supplychain/approvals",
"componentPath": "@/views/supplychain/components/ApprovalWorkflows",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.orders",
"path": "/admin/supplychain/orders",
"componentPath": "@/views/supplychain/components/OrderManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.ordersNew",
"path": "/admin/supplychain/orders/new",
"componentPath": "@/views/supplychain/components/OrderManagementForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.ordersEdit",
"path": "/admin/supplychain/orders/edit/:id",
"componentPath": "@/views/supplychain/components/OrderManagementForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.ordersView",
"path": "/admin/supplychain/orders/view/:id",
"componentPath": "@/views/supplychain/components/OrderManagementForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.supplychain.delivery",
"path": "/admin/supplychain/delivery",
"componentPath": "@/views/supplychain/components/DeliveryTracking",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.equipment",
"path": "/admin/maintenance/equipment",
"componentPath": "@/views/maintenance/components/WorkCenterCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.equipmentNew",
"path": "/admin/maintenance/equipment/new",
"componentPath": "@/views/maintenance/components/WorkCenterCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.equipmentEdit",
"path": "/admin/maintenance/equipment/edit/:id",
"componentPath": "@/views/maintenance/components/WorkCenterCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.equipmentDetail",
"path": "/admin/maintenance/equipment/:id",
"componentPath": "@/views/maintenance/components/WorkCenterCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.workcenters",
"path": "/admin/maintenance/workcenters",
"componentPath": "@/views/maintenance/components/WorkCenterCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.plans",
"path": "/admin/maintenance/plans",
"componentPath": "@/views/maintenance/components/MaintenancePlans",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.calendar",
"path": "/admin/maintenance/calendar",
"componentPath": "@/views/maintenance/components/MaintenanceCalendar",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.teams",
"path": "/admin/maintenance/teams",
"componentPath": "@/views/maintenance/components/MaintenanceTeams",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.faults",
"path": "/admin/maintenance/faults",
"componentPath": "@/views/maintenance/components/FaultNotifications",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.workorders",
"path": "/admin/maintenance/workorders",
"componentPath": "@/views/maintenance/components/MaintenanceWorkOrders",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.workordersNew",
"path": "/admin/maintenance/workorders/new",
"componentPath": "@/views/maintenance/components/MaintenanceWorkOrders",
"routeType": "protected",
"authority": null
},
{
"key": "admin.maintenance.workordersDetail",
"path": "/admin/maintenance/workorders/:id",
"componentPath": "@/views/maintenance/components/MaintenanceWorkOrders",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.definitions",
"path": "/admin/warehouse/definitions",
"componentPath": "@/views/warehouse/components/WarehouseDefinitions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.tracking",
"path": "/admin/warehouse/tracking",
"componentPath": "@/views/warehouse/components/LocationTracking",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.putaway",
"path": "/admin/warehouse/putaway",
"componentPath": "@/views/warehouse/components/PutawayRules",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.receipt",
"path": "/admin/warehouse/receipt",
"componentPath": "@/views/warehouse/components/WarehouseReceipt",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.issue",
"path": "/admin/warehouse/issue",
"componentPath": "@/views/warehouse/components/WarehouseIssue",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.transfer",
"path": "/admin/warehouse/transfer",
"componentPath": "@/views/warehouse/components/WarehouseTransfer",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.inventory",
"path": "/admin/warehouse/inventory",
"componentPath": "@/views/warehouse/components/StockLevelsInventory",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.movements",
"path": "/admin/warehouse/movements",
"componentPath": "@/views/warehouse/components/MaterialMovements",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.movementDetail",
"path": "/admin/warehouse/movements/:id",
"componentPath": "@/views/warehouse/components/MaterialMovements",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.stocklevel",
"path": "/admin/warehouse/stocklevel",
"componentPath": "@/views/warehouse/components/InventoryTracking",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.warehouses",
"path": "/admin/warehouse/warehouses",
"componentPath": "@/views/warehouse/components/WarehouseDefinitions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.warehouseNew",
"path": "/admin/warehouse/new",
"componentPath": "@/views/warehouse/components/WarehouseDefinitions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.warehouseEdit",
"path": "/admin/warehouse/edit/:id",
"componentPath": "@/views/warehouse/components/WarehouseDefinitions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.warehouse.warehouseDetail",
"path": "/admin/warehouse/warehouses/:id",
"componentPath": "@/views/warehouse/components/WarehouseDefinitions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.list",
"path": "/admin/project",
"componentPath": "@/views/project/components/ProjectList",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.new",
"path": "/admin/project/new",
"componentPath": "@/views/project/components/ProjectForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.edit",
"path": "/admin/project/edit/:id",
"componentPath": "@/views/project/components/ProjectForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.detail",
"path": "/admin/project/:id",
"componentPath": "@/views/project/components/ProjectView",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.tasks",
"path": "/admin/project/tasks",
"componentPath": "@/views/project/components/ProjectTasks",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.phases",
"path": "/admin/project/phases",
"componentPath": "@/views/project/components/ProjectPhases",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.activities",
"path": "/admin/project/activities",
"componentPath": "@/views/project/components/ActivityTypes",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.workload",
"path": "/admin/project/workload",
"componentPath": "@/views/project/components/ProjectGantt",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.costTracking",
"path": "/admin/project/cost-tracking",
"componentPath": "@/views/project/components/CostTimeTracking",
"routeType": "protected",
"authority": null
},
{
"key": "admin.project.dailyUpdates",
"path": "/admin/project/daily-updates",
"componentPath": "@/views/project/components/TaskDailyUpdates",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.employees",
"path": "/admin/hr/employees",
"componentPath": "@/views/hr/components/EmployeeList",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.employeesNew",
"path": "/admin/hr/employees/new",
"componentPath": "@/views/hr/components/EmployeeForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.employeesEdit",
"path": "/admin/hr/employees/edit/:id",
"componentPath": "@/views/hr/components/EmployeeForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.employeesDetail",
"path": "/admin/hr/employees/:id",
"componentPath": "@/views/hr/components/EmployeeView",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.departments",
"path": "/admin/hr/departments",
"componentPath": "@/views/hr/components/DepartmentManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.jobPositions",
"path": "/admin/hr/job-positions",
"componentPath": "@/views/hr/components/JobPositions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.employmentTypes",
"path": "/admin/hr/employment-types",
"componentPath": "@/views/hr/components/EmploymentTypes",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.organization",
"path": "/admin/hr/organization",
"componentPath": "@/views/hr/components/OrganizationChart",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.badges",
"path": "/admin/hr/badges",
"componentPath": "@/views/hr/components/BadgeManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.leaveManagement",
"path": "/admin/hr/leave-management",
"componentPath": "@/views/hr/components/LeaveManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.overtimes",
"path": "/admin/hr/overtimes-management",
"componentPath": "@/views/hr/components/OvertimeManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.payroll",
"path": "/admin/hr/payroll",
"componentPath": "@/views/hr/components/PayrollManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.costCenters",
"path": "/admin/hr/cost-centers",
"componentPath": "@/views/hr/components/CostCenterManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.evaluationTemplates",
"path": "/admin/hr/360-templates",
"componentPath": "@/views/hr/components/Degree360Templates",
"routeType": "protected",
"authority": null
},
{
"key": "admin.hr.evaluation",
"path": "/admin/hr/360-evaluation",
"componentPath": "@/views/hr/components/Degree360Evaluation",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.customers",
"path": "/admin/crm/customers",
"componentPath": "@/views/crm/components/CustomerListWithToggle",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.customersNew",
"path": "/admin/crm/customers/new",
"componentPath": "@/views/crm/components/CustomerForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.customersEdit",
"path": "/admin/crm/customers/edit/:id",
"componentPath": "@/views/crm/components/CustomerEdit",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.customersDetail",
"path": "/admin/crm/customers/:id",
"componentPath": "@/views/crm/components/CustomerView",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesTeams",
"path": "/admin/crm/sales-teams",
"componentPath": "@/views/crm/components/SalesTeams",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesTeamsNew",
"path": "/admin/crm/sales-teams/new",
"componentPath": "@/views/crm/components/SalesTeamCreate",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesTeamsEdit",
"path": "/admin/crm/sales-teams/edit/:id",
"componentPath": "@/views/crm/components/SalesTeamEdit",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesTeamsDetail",
"path": "/admin/crm/sales-teams/:id",
"componentPath": "@/views/crm/components/SalesTeamView",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.lossReasons",
"path": "/admin/crm/loss-reasons",
"componentPath": "@/views/crm/components/LossReasons",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.opportunities",
"path": "/admin/crm/opportunities",
"componentPath": "@/views/crm/components/OpportunityManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.opportunitiesNew",
"path": "/admin/crm/opportunities/new",
"componentPath": "@/views/crm/components/OpportunityManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.opportunitiesEdit",
"path": "/admin/crm/opportunities/edit/:id",
"componentPath": "@/views/crm/components/OpportunityManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.opportunitiesDetail",
"path": "/admin/crm/opportunities/:id",
"componentPath": "@/views/crm/components/OpportunityManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.activities",
"path": "/admin/crm/activities",
"componentPath": "@/views/crm/components/ActivityRecords",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesOrders",
"path": "/admin/crm/sales-orders",
"componentPath": "@/views/crm/components/SalesOrders",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesOrdersNew",
"path": "/admin/crm/sales-orders/new",
"componentPath": "@/views/crm/components/SalesOrderForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesOrdersEdit",
"path": "/admin/crm/sales-orders/edit/:id",
"componentPath": "@/views/crm/components/SalesOrderForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.crm.salesOrdersDetail",
"path": "/admin/crm/sales-orders/:id",
"componentPath": "@/views/crm/components/SalesOrderView",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.operationTypes",
"path": "/admin/mrp/operation-types",
"componentPath": "@/views/mrp/components/OperationTypes",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.workcenters",
"path": "/admin/mrp/workcenters",
"componentPath": "@/views/maintenance/components/WorkCenterCards",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.operations",
"path": "/admin/mrp/operations",
"componentPath": "@/views/mrp/components/OperationDefinitions",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.bom",
"path": "/admin/mrp/bom",
"componentPath": "@/views/mrp/components/BOMManagement",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.productionOrders",
"path": "/admin/mrp/production-orders",
"componentPath": "@/views/mrp/components/ProductionOrderList",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.productionOrderNew",
"path": "/admin/mrp/production-orders/new",
"componentPath": "@/views/mrp/components/ProductionOrderForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.productionOrderEdit",
"path": "/admin/mrp/production-orders/:id/edit",
"componentPath": "@/views/mrp/components/ProductionOrderForm",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.productionOrderDetail",
"path": "/admin/mrp/production-orders/:id",
"componentPath": "@/views/mrp/components/ProductionOrderView",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.workOrders",
"path": "/admin/mrp/work-orders",
"componentPath": "@/views/mrp/components/WorkOrders",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.demandPlanning",
"path": "/admin/mrp/demand-planning",
"componentPath": "@/views/mrp/components/DemandPlanning",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.materialRequirements",
"path": "/admin/mrp/material-requirements",
"componentPath": "@/views/mrp/components/Requirements",
"routeType": "protected",
"authority": null
},
{
"key": "admin.mrp.planningGantt",
"path": "/admin/mrp/planning-gantt",
"componentPath": "@/views/mrp/components/PlanningGantt",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.currentAccounts",
"path": "/admin/accounting/current-accounts",
"componentPath": "@/views/accounting/CurrentAccountPage",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.waybills",
"path": "/admin/accounting/waybills",
"componentPath": "@/views/accounting/WaybillPage",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.invoices",
"path": "/admin/accounting/invoices",
"componentPath": "@/views/accounting/InvoicePage",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.invoicesNew",
"path": "/admin/accounting/invoices/new",
"componentPath": "@/views/accounting/InvoicePage",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.cash",
"path": "/admin/accounting/cash",
"componentPath": "@/views/accounting/CashPage",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.bank",
"path": "/admin/accounting/bank",
"componentPath": "@/views/accounting/BankPage",
"routeType": "protected",
"authority": null
},
{
"key": "admin.accounting.checkNote",
"path": "/admin/accounting/check-note",
"componentPath": "@/views/accounting/CheckNotePage",
"routeType": "protected",
"authority": null
} }
], ],
"Languages": [ "Languages": [

View file

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

View file

@ -1,6 +1,6 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom'
import { useQuery } from "@tanstack/react-query"; import { useQuery } from '@tanstack/react-query'
import { import {
FaCog, FaCog,
FaPlus, FaPlus,
@ -15,45 +15,44 @@ import {
FaChartLine, FaChartLine,
FaCalendar, FaCalendar,
FaArrowUp, FaArrowUp,
} from "react-icons/fa"; } from 'react-icons/fa'
import classNames from "classnames"; import classNames from 'classnames'
import { WorkCenterStatusEnum, CriticalityLevelEnum } from "../../../types/pm"; import { WorkCenterStatusEnum, CriticalityLevelEnum } from '../../../types/pm'
import dayjs from "dayjs"; import dayjs from 'dayjs'
import { mockWorkCenters } from "../../../mocks/mockWorkCenters"; import { mockWorkCenters } from '../../../mocks/mockWorkCenters'
import { import {
getWorkCenterStatusColor, getWorkCenterStatusColor,
getWorkCenterStatusIcon, getWorkCenterStatusIcon,
getWorkCenterStatusText, getWorkCenterStatusText,
getCriticalityLevelColor, getCriticalityLevelColor,
getCriticalityLevelText, getCriticalityLevelText,
} from "../../../utils/erp"; } from '../../../utils/erp'
const WorkCenterList: React.FC = () => { const WorkCenterList: React.FC = () => {
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState('')
const [filterStatus, setFilterStatus] = useState("all"); const [filterStatus, setFilterStatus] = useState('all')
const [filterCriticality, setFilterCriticality] = useState("all"); const [filterCriticality, setFilterCriticality] = useState('all')
const [showFilters, setShowFilters] = useState(false); const [showFilters, setShowFilters] = useState(false)
const { const {
data: workCenter, data: workCenter,
isLoading, isLoading,
error, error,
} = useQuery({ } = useQuery({
queryKey: ["workCenter", searchTerm, filterStatus, filterCriticality], queryKey: ['workCenter', searchTerm, filterStatus, filterCriticality],
queryFn: async () => { queryFn: async () => {
await new Promise((resolve) => setTimeout(resolve, 500)); await new Promise((resolve) => setTimeout(resolve, 500))
return mockWorkCenters.filter((eq) => { return mockWorkCenters.filter((eq) => {
const matchesSearch = const matchesSearch =
eq.code.toLowerCase().includes(searchTerm.toLowerCase()) || eq.code.toLowerCase().includes(searchTerm.toLowerCase()) ||
eq.name.toLowerCase().includes(searchTerm.toLowerCase()); eq.name.toLowerCase().includes(searchTerm.toLowerCase())
const matchesStatus = const matchesStatus = filterStatus === 'all' || eq.status === filterStatus
filterStatus === "all" || eq.status === filterStatus;
const matchesCriticality = const matchesCriticality =
filterCriticality === "all" || eq.criticality === filterCriticality; filterCriticality === 'all' || eq.criticality === filterCriticality
return matchesSearch && matchesStatus && matchesCriticality; return matchesSearch && matchesStatus && matchesCriticality
}); })
}, },
}); })
if (isLoading) { if (isLoading) {
return ( return (
@ -61,7 +60,7 @@ const WorkCenterList: React.FC = () => {
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div> <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<span className="ml-3 text-gray-600">İş Merkezleri yükleniyor...</span> <span className="ml-3 text-gray-600">İş Merkezleri yükleniyor...</span>
</div> </div>
); )
} }
if (error) { if (error) {
@ -69,12 +68,10 @@ const WorkCenterList: React.FC = () => {
<div className="bg-red-50 border border-red-200 rounded-lg p-4"> <div className="bg-red-50 border border-red-200 rounded-lg p-4">
<div className="flex items-center"> <div className="flex items-center">
<FaExclamationTriangle className="h-5 w-5 text-red-600 mr-2" /> <FaExclamationTriangle className="h-5 w-5 text-red-600 mr-2" />
<span className="text-red-800"> <span className="text-red-800">İş merkezleri yüklenirken hata oluştu.</span>
İş merkezleri yüklenirken hata oluştu.
</span>
</div> </div>
</div> </div>
); )
} }
return ( return (
@ -99,10 +96,10 @@ const WorkCenterList: React.FC = () => {
<button <button
onClick={() => setShowFilters(!showFilters)} onClick={() => setShowFilters(!showFilters)}
className={classNames( className={classNames(
"flex items-center px-4 py-2 border rounded-lg transition-colors", 'flex items-center px-4 py-2 border rounded-lg transition-colors',
showFilters showFilters
? "border-blue-500 bg-blue-50 text-blue-700" ? 'border-blue-500 bg-blue-50 text-blue-700'
: "border-gray-300 bg-white text-gray-700 hover:bg-gray-50" : 'border-gray-300 bg-white text-gray-700 hover:bg-gray-50',
)} )}
> >
<FaFilter size={16} className="mr-2" /> <FaFilter size={16} className="mr-2" />
@ -112,7 +109,7 @@ const WorkCenterList: React.FC = () => {
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<button <button
onClick={() => alert("Dışa aktarma özelliği yakında eklenecek")} onClick={() => alert('Dışa aktarma özelliği yakında eklenecek')}
className="flex items-center px-3 py-1.5 text-sm border border-gray-300 bg-white text-gray-700 rounded-lg hover:bg-gray-50 transition-colors" className="flex items-center px-3 py-1.5 text-sm border border-gray-300 bg-white text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
> >
<FaDownload size={16} className="mr-2" /> <FaDownload size={16} className="mr-2" />
@ -134,30 +131,22 @@ const WorkCenterList: React.FC = () => {
<div className="bg-white border border-gray-200 rounded-lg p-3"> <div className="bg-white border border-gray-200 rounded-lg p-3">
<div className="grid grid-cols-1 md:grid-cols-4 gap-3"> <div className="grid grid-cols-1 md:grid-cols-4 gap-3">
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">Durum</label>
Durum
</label>
<select <select
value={filterStatus} value={filterStatus}
onChange={(e) => setFilterStatus(e.target.value)} onChange={(e) => setFilterStatus(e.target.value)}
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" 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="all">Tümü</option>
<option value={WorkCenterStatusEnum.Operational}> <option value={WorkCenterStatusEnum.Operational}>Operasyonel</option>
Operasyonel <option value={WorkCenterStatusEnum.UnderMaintenance}>Bakımda</option>
</option>
<option value={WorkCenterStatusEnum.UnderMaintenance}>
Bakımda
</option>
<option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option> <option value={WorkCenterStatusEnum.OutOfOrder}>Arızalı</option>
<option value={WorkCenterStatusEnum.Retired}>Emekli</option> <option value={WorkCenterStatusEnum.Retired}>Emekli</option>
</select> </select>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">Kritiklik</label>
Kritiklik
</label>
<select <select
value={filterCriticality} value={filterCriticality}
onChange={(e) => setFilterCriticality(e.target.value)} onChange={(e) => setFilterCriticality(e.target.value)}
@ -174,9 +163,9 @@ const WorkCenterList: React.FC = () => {
<div className="flex items-end"> <div className="flex items-end">
<button <button
onClick={() => { onClick={() => {
setFilterStatus("all"); setFilterStatus('all')
setFilterCriticality("all"); setFilterCriticality('all')
setSearchTerm(""); setSearchTerm('')
}} }}
className="w-full px-3 py-1.5 text-sm border border-gray-300 bg-white text-gray-700 rounded-lg hover:bg-gray-50 transition-colors" className="w-full px-3 py-1.5 text-sm border border-gray-300 bg-white text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
> >
@ -192,12 +181,8 @@ const WorkCenterList: React.FC = () => {
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-3"> <div className="bg-white rounded-lg shadow-sm border border-gray-200 p-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-gray-600"> <p className="text-sm font-medium text-gray-600">Toplam İş Merkezi</p>
Toplam İş Merkezi <p className="text-xl font-bold text-gray-900">{workCenter?.length || 0}</p>
</p>
<p className="text-xl font-bold text-gray-900">
{workCenter?.length || 0}
</p>
</div> </div>
<FaCog className="h-8 w-8 text-blue-600" /> <FaCog className="h-8 w-8 text-blue-600" />
</div> </div>
@ -208,9 +193,8 @@ const WorkCenterList: React.FC = () => {
<div> <div>
<p className="text-sm font-medium text-gray-600">Operasyonel</p> <p className="text-sm font-medium text-gray-600">Operasyonel</p>
<p className="text-xl font-bold text-green-600"> <p className="text-xl font-bold text-green-600">
{workCenter?.filter( {workCenter?.filter((e) => e.status === WorkCenterStatusEnum.Operational).length ||
(e) => e.status === WorkCenterStatusEnum.Operational 0}
).length || 0}
</p> </p>
</div> </div>
<FaCheckCircle className="h-8 w-8 text-green-600" /> <FaCheckCircle className="h-8 w-8 text-green-600" />
@ -222,9 +206,8 @@ const WorkCenterList: React.FC = () => {
<div> <div>
<p className="text-sm font-medium text-gray-600">Bakımda</p> <p className="text-sm font-medium text-gray-600">Bakımda</p>
<p className="text-xl font-bold text-yellow-600"> <p className="text-xl font-bold text-yellow-600">
{workCenter?.filter( {workCenter?.filter((e) => e.status === WorkCenterStatusEnum.UnderMaintenance)
(e) => e.status === WorkCenterStatusEnum.UnderMaintenance .length || 0}
).length || 0}
</p> </p>
</div> </div>
<FaWrench className="h-8 w-8 text-yellow-600" /> <FaWrench className="h-8 w-8 text-yellow-600" />
@ -234,13 +217,10 @@ const WorkCenterList: React.FC = () => {
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-3"> <div className="bg-white rounded-lg shadow-sm border border-gray-200 p-3">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-medium text-gray-600"> <p className="text-sm font-medium text-gray-600">Kritik İş Merkezi</p>
Kritik İş Merkezi
</p>
<p className="text-xl font-bold text-red-600"> <p className="text-xl font-bold text-red-600">
{workCenter?.filter( {workCenter?.filter((e) => e.criticality === CriticalityLevelEnum.Critical)
(e) => e.criticality === CriticalityLevelEnum.Critical .length || 0}
).length || 0}
</p> </p>
</div> </div>
<FaExclamationTriangle className="h-8 w-8 text-red-600" /> <FaExclamationTriangle className="h-8 w-8 text-red-600" />
@ -251,9 +231,7 @@ const WorkCenterList: React.FC = () => {
{/* WorkCenter Table */} {/* WorkCenter Table */}
<div className="bg-white rounded-lg shadow-sm border border-gray-200"> <div className="bg-white rounded-lg shadow-sm border border-gray-200">
<div className="px-4 py-3 border-b border-gray-200"> <div className="px-4 py-3 border-b border-gray-200">
<h2 className="text-xl font-bold text-gray-900"> <h2 className="text-xl font-bold text-gray-900">WorkCenter Listesi</h2>
WorkCenter Listesi
</h2>
</div> </div>
<div className="overflow-x-auto"> <div className="overflow-x-auto">
@ -295,16 +273,10 @@ const WorkCenterList: React.FC = () => {
</div> </div>
</div> </div>
<div className="ml-3"> <div className="ml-3">
<div className="text-sm font-medium text-gray-900"> <div className="text-sm font-medium text-gray-900">{eq.code}</div>
{eq.code} <div className="text-sm text-gray-500 max-w-xs truncate">{eq.name}</div>
</div>
<div className="text-sm text-gray-500 max-w-xs truncate">
{eq.name}
</div>
{eq.serialNumber && ( {eq.serialNumber && (
<div className="text-xs text-gray-400 mt-1"> <div className="text-xs text-gray-400 mt-1">S/N: {eq.serialNumber}</div>
S/N: {eq.serialNumber}
</div>
)} )}
</div> </div>
</div> </div>
@ -313,25 +285,17 @@ const WorkCenterList: React.FC = () => {
<td className="px-4 py-3"> <td className="px-4 py-3">
<div> <div>
<div className="text-sm font-medium text-gray-900"> <div className="text-sm font-medium text-gray-900">
{eq.manufacturer || "-"} {eq.manufacturer || '-'}
</div>
<div className="text-sm text-gray-500">
{eq.model || "-"}
</div>
<div className="text-xs text-gray-400 mt-1">
{eq.workCenterType?.name}
</div> </div>
<div className="text-sm text-gray-500">{eq.model || '-'}</div>
<div className="text-xs text-gray-400 mt-1">{eq.workCenterType?.name}</div>
</div> </div>
</td> </td>
<td className="px-4 py-3"> <td className="px-4 py-3">
<div> <div>
<div className="text-sm font-medium text-gray-900"> <div className="text-sm font-medium text-gray-900">{eq.location}</div>
{eq.location} <div className="text-sm text-gray-500">{eq.departmentId}</div>
</div>
<div className="text-sm text-gray-500">
{eq.departmentId}
</div>
</div> </div>
</td> </td>
@ -339,19 +303,17 @@ const WorkCenterList: React.FC = () => {
<div className="space-y-2"> <div className="space-y-2">
<span <span
className={classNames( className={classNames(
"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium", 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium',
getWorkCenterStatusColor(eq.status) getWorkCenterStatusColor(eq.status),
)} )}
> >
{getWorkCenterStatusIcon(eq.status)} {getWorkCenterStatusIcon(eq.status)}
<span className="ml-1"> <span className="ml-1">{getWorkCenterStatusText(eq.status)}</span>
{getWorkCenterStatusText(eq.status)}
</span>
</span> </span>
<div <div
className={classNames( className={classNames(
"text-sm font-medium", 'text-sm font-medium',
getCriticalityLevelColor(eq.criticality) getCriticalityLevelColor(eq.criticality),
)} )}
> >
{getCriticalityLevelText(eq.criticality)} {getCriticalityLevelText(eq.criticality)}
@ -363,12 +325,11 @@ const WorkCenterList: React.FC = () => {
<div className="space-y-1"> <div className="space-y-1">
<div className="flex items-center text-sm text-gray-900"> <div className="flex items-center text-sm text-gray-900">
<FaCalendar size={14} className="mr-1" /> <FaCalendar size={14} className="mr-1" />
{dayjs(eq.installationDate).format("DD.MM.YYYY")} {dayjs(eq.installationDate).format('DD.MM.YYYY')}
</div> </div>
{eq.warrantyExpiry && ( {eq.warrantyExpiry && (
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
Garanti:{" "} Garanti: {dayjs(eq.warrantyExpiry).format('DD.MM.YYYY')}
{dayjs(eq.warrantyExpiry).format("DD.MM.YYYY")}
</div> </div>
)} )}
</div> </div>
@ -377,13 +338,8 @@ const WorkCenterList: React.FC = () => {
<td className="px-4 py-3"> <td className="px-4 py-3">
<div className="space-y-1"> <div className="space-y-1">
<div className="flex items-center"> <div className="flex items-center">
<FaChartLine <FaChartLine size={14} className="text-green-500 mr-1" />
size={14} <span className="text-sm text-green-600">98.5% Uptime</span>
className="text-green-500 mr-1"
/>
<span className="text-sm text-green-600">
98.5% Uptime
</span>
</div> </div>
<div className="flex items-center"> <div className="flex items-center">
<FaArrowUp size={14} className="text-blue-500 mr-1" /> <FaArrowUp size={14} className="text-blue-500 mr-1" />
@ -411,11 +367,7 @@ const WorkCenterList: React.FC = () => {
</Link> </Link>
<button <button
onClick={() => onClick={() => alert('Bakım emri oluşturma özelliği yakında eklenecek')}
alert(
"Bakım emri oluşturma özelliği yakında eklenecek"
)
}
className="p-1.5 text-gray-600 hover:text-green-600 hover:bg-green-50 rounded-lg transition-colors" className="p-1.5 text-gray-600 hover:text-green-600 hover:bg-green-50 rounded-lg transition-colors"
title="Bakım Emri Oluştur" title="Bakım Emri Oluştur"
> >
@ -432,12 +384,8 @@ const WorkCenterList: React.FC = () => {
{(!workCenter || workCenter.length === 0) && ( {(!workCenter || workCenter.length === 0) && (
<div className="text-center py-10"> <div className="text-center py-10">
<FaCog className="mx-auto h-10 w-10 text-gray-400" /> <FaCog className="mx-auto h-10 w-10 text-gray-400" />
<h3 className="mt-1.5 text-sm font-medium text-gray-900"> <h3 className="mt-1.5 text-sm font-medium text-gray-900">İş Merkezi bulunamadı</h3>
İş Merkezi bulunamadı <p className="mt-1 text-sm text-gray-500">Yeni merkezi ekleyerek başlayın.</p>
</h3>
<p className="mt-1 text-sm text-gray-500">
Yeni merkezi ekleyerek başlayın.
</p>
<div className="mt-4"> <div className="mt-4">
<Link <Link
to="/admin/maintenance/equipment/new" to="/admin/maintenance/equipment/new"
@ -451,7 +399,7 @@ const WorkCenterList: React.FC = () => {
)} )}
</div> </div>
</div> </div>
); )
}; }
export default WorkCenterList; export default WorkCenterList

View file

@ -1,4 +1,4 @@
import React, { useState, useMemo } from "react"; import React, { useState, useMemo } from 'react'
import { import {
FaPlus, FaPlus,
FaEdit, FaEdit,
@ -10,63 +10,52 @@ import {
FaChevronDown, FaChevronDown,
FaChevronRight, FaChevronRight,
FaAngleRight, FaAngleRight,
} from "react-icons/fa"; } from 'react-icons/fa'
import { import { mockMaterialGroups, populateParentGroups } from '../../../mocks/mockMaterialGroups'
mockMaterialGroups, import { MmMaterialGroup } from '../../../types/mm'
populateParentGroups,
} from "../../../mocks/mockMaterialGroups";
import { MmMaterialGroup } from "../../../types/mm";
interface MaterialGroupNode extends MmMaterialGroup { interface MaterialGroupNode extends MmMaterialGroup {
children: MaterialGroupNode[]; children: MaterialGroupNode[]
} }
const MaterialGroups: React.FC = () => { const MaterialGroups: React.FC = () => {
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState('')
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false)
const [editingGroup, setEditingGroup] = useState<MmMaterialGroup | null>( const [editingGroup, setEditingGroup] = useState<MmMaterialGroup | null>(null)
null const [viewMode, setViewMode] = useState<'list' | 'card' | 'tree'>('tree')
);
const [viewMode, setViewMode] = useState<"list" | "card" | "tree">("tree");
// Mock data - gerçek uygulamada API'den gelecek // Mock data - gerçek uygulamada API'den gelecek
const [materialGroups, setMaterialGroups] = const [materialGroups, setMaterialGroups] = useState<MmMaterialGroup[]>(mockMaterialGroups)
useState<MmMaterialGroup[]>(mockMaterialGroups);
const filteredGroups = materialGroups.filter( const filteredGroups = materialGroups.filter(
(group) => (group) =>
group.name.toLowerCase().includes(searchTerm.toLowerCase()) || group.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
group.code.toLowerCase().includes(searchTerm.toLowerCase()) || group.code.toLowerCase().includes(searchTerm.toLowerCase()) ||
(group.description && (group.description && group.description.toLowerCase().includes(searchTerm.toLowerCase())),
group.description.toLowerCase().includes(searchTerm.toLowerCase())) )
);
const handleAdd = () => { const handleAdd = () => {
setEditingGroup(null); setEditingGroup(null)
setIsModalOpen(true); setIsModalOpen(true)
}; }
const handleEdit = (group: MmMaterialGroup) => { const handleEdit = (group: MmMaterialGroup) => {
setEditingGroup(group); setEditingGroup(group)
setIsModalOpen(true); setIsModalOpen(true)
}; }
const handleDelete = (group: MmMaterialGroup) => { const handleDelete = (group: MmMaterialGroup) => {
if ( if (window.confirm(`${group.name} grubunu silmek istediğinizden emin misiniz?`)) {
window.confirm( setMaterialGroups((prev) => prev.filter((g) => g.id !== group.id))
`${group.name} grubunu silmek istediğinizden emin misiniz?`
)
) {
setMaterialGroups((prev) => prev.filter((g) => g.id !== group.id));
} }
}; }
const handleSave = (formData: Partial<MmMaterialGroup>) => { const handleSave = (formData: Partial<MmMaterialGroup>) => {
if (editingGroup) { if (editingGroup) {
// Mevcut grubu güncelle // Mevcut grubu güncelle
setMaterialGroups((prev) => setMaterialGroups((prev) =>
prev.map((g) => (g.id === editingGroup.id ? { ...g, ...formData } : g)) prev.map((g) => (g.id === editingGroup.id ? { ...g, ...formData } : g)),
); )
} else { } else {
// Yeni grup ekle // Yeni grup ekle
const newGroup: MmMaterialGroup = { const newGroup: MmMaterialGroup = {
@ -76,37 +65,37 @@ const MaterialGroups: React.FC = () => {
parentGroupId: formData.parentGroupId || undefined, parentGroupId: formData.parentGroupId || undefined,
description: formData.description, description: formData.description,
isActive: formData.isActive ?? true, isActive: formData.isActive ?? true,
}; }
setMaterialGroups((prev) => [...prev, newGroup]); setMaterialGroups((prev) => [...prev, newGroup])
} }
setIsModalOpen(false); setIsModalOpen(false)
}; }
// Ağaç yapısını oluşturmak için useMemo kullanıyoruz // Ağaç yapısını oluşturmak için useMemo kullanıyoruz
const groupTree = useMemo(() => { const groupTree = useMemo(() => {
const buildTree = (groups: MmMaterialGroup[]): MaterialGroupNode[] => { const buildTree = (groups: MmMaterialGroup[]): MaterialGroupNode[] => {
const groupMap = new Map<string, MaterialGroupNode>(); const groupMap = new Map<string, MaterialGroupNode>()
const roots: MaterialGroupNode[] = []; const roots: MaterialGroupNode[] = []
// Her grubu bir düğüme dönüştür ve haritaya ekle // Her grubu bir düğüme dönüştür ve haritaya ekle
groups.forEach((group) => { groups.forEach((group) => {
groupMap.set(group.id, { ...group, children: [] }); groupMap.set(group.id, { ...group, children: [] })
}); })
// Üst-alt ilişkilerini kur // Üst-alt ilişkilerini kur
groups.forEach((group) => { groups.forEach((group) => {
if (group.parentGroupId && groupMap.has(group.parentGroupId)) { if (group.parentGroupId && groupMap.has(group.parentGroupId)) {
const parent = groupMap.get(group.parentGroupId)!; const parent = groupMap.get(group.parentGroupId)!
parent.children.push(groupMap.get(group.id)!); parent.children.push(groupMap.get(group.id)!)
} else { } else {
roots.push(groupMap.get(group.id)!); roots.push(groupMap.get(group.id)!)
} }
}); })
return roots; return roots
}; }
return buildTree(filteredGroups); return buildTree(filteredGroups)
}, [filteredGroups]); }, [filteredGroups])
return ( return (
<div className="space-y-3 py-2"> <div className="space-y-3 py-2">
@ -123,33 +112,33 @@ const MaterialGroups: React.FC = () => {
{/* View Mode Toggle */} {/* View Mode Toggle */}
<div className="flex bg-gray-100 rounded-lg p-1"> <div className="flex bg-gray-100 rounded-lg p-1">
<button <button
onClick={() => setViewMode("list")} onClick={() => setViewMode('list')}
className={`p-1.5 rounded-md transition-colors ${ className={`p-1.5 rounded-md transition-colors ${
viewMode === "list" viewMode === 'list'
? "bg-white text-blue-600 shadow-sm" ? 'bg-white text-blue-600 shadow-sm'
: "text-gray-600 hover:text-gray-900" : 'text-gray-600 hover:text-gray-900'
}`} }`}
title="Liste Görünümü" title="Liste Görünümü"
> >
<FaList className="w-4 h-4" /> <FaList className="w-4 h-4" />
</button> </button>
<button <button
onClick={() => setViewMode("card")} onClick={() => setViewMode('card')}
className={`p-1.5 rounded-md transition-colors ${ className={`p-1.5 rounded-md transition-colors ${
viewMode === "card" viewMode === 'card'
? "bg-white text-blue-600 shadow-sm" ? 'bg-white text-blue-600 shadow-sm'
: "text-gray-600 hover:text-gray-900" : 'text-gray-600 hover:text-gray-900'
}`} }`}
title="Kart Görünümü" title="Kart Görünümü"
> >
<FaTh className="w-4 h-4" /> <FaTh className="w-4 h-4" />
</button> </button>
<button <button
onClick={() => setViewMode("tree")} onClick={() => setViewMode('tree')}
className={`p-1.5 rounded-md transition-colors ${ className={`p-1.5 rounded-md transition-colors ${
viewMode === "tree" viewMode === 'tree'
? "bg-white text-blue-600 shadow-sm" ? 'bg-white text-blue-600 shadow-sm'
: "text-gray-600 hover:text-gray-900" : 'text-gray-600 hover:text-gray-900'
}`} }`}
title="Ağaç Görünümü" title="Ağaç Görünümü"
> >
@ -183,7 +172,7 @@ const MaterialGroups: React.FC = () => {
</div> </div>
</div> </div>
{viewMode === "list" && ( {viewMode === 'list' && (
<div className="bg-white shadow-sm rounded-lg overflow-hidden"> <div className="bg-white shadow-sm rounded-lg overflow-hidden">
<table className="min-w-full divide-y divide-gray-200"> <table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50"> <thead className="bg-gray-50">
@ -217,29 +206,23 @@ const MaterialGroups: React.FC = () => {
</span> </span>
</td> </td>
<td className="px-3 py-1.5 whitespace-nowrap"> <td className="px-3 py-1.5 whitespace-nowrap">
<div className="text-sm font-medium text-gray-900"> <div className="text-sm font-medium text-gray-900">{group.name}</div>
{group.name}
</div>
</td> </td>
<td className="px-3 py-1.5"> <td className="px-3 py-1.5">
<div className="text-sm text-gray-900"> <div className="text-sm text-gray-900">
{group.parentGroup ? group.parentGroup.name : "-"} {group.parentGroup ? group.parentGroup.name : '-'}
</div> </div>
</td> </td>
<td className="px-3 py-1.5"> <td className="px-3 py-1.5">
<div className="text-sm text-gray-900"> <div className="text-sm text-gray-900">{group.description}</div>
{group.description}
</div>
</td> </td>
<td className="px-3 py-1.5 whitespace-nowrap"> <td className="px-3 py-1.5 whitespace-nowrap">
<span <span
className={`px-2 py-0.5 text-xs font-medium rounded-full ${ className={`px-2 py-0.5 text-xs font-medium rounded-full ${
group.isActive group.isActive ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
? "bg-green-100 text-green-800"
: "bg-red-100 text-red-800"
}`} }`}
> >
{group.isActive ? "Aktif" : "Pasif"} {group.isActive ? 'Aktif' : 'Pasif'}
</span> </span>
</td> </td>
<td className="px-3 py-1.5 whitespace-nowrap text-right text-sm font-medium"> <td className="px-3 py-1.5 whitespace-nowrap text-right text-sm font-medium">
@ -271,7 +254,7 @@ const MaterialGroups: React.FC = () => {
</div> </div>
)} )}
{viewMode === "card" && ( {viewMode === 'card' && (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-2">
{filteredGroups.map((group) => ( {filteredGroups.map((group) => (
<div <div
@ -302,14 +285,10 @@ const MaterialGroups: React.FC = () => {
</div> </div>
</div> </div>
<h3 className="font-medium text-gray-900 mb-1.5 text-sm"> <h3 className="font-medium text-gray-900 mb-1.5 text-sm">{group.name}</h3>
{group.name}
</h3>
{group.description && ( {group.description && (
<p className="text-sm text-gray-600 mb-3 line-clamp-2"> <p className="text-sm text-gray-600 mb-3 line-clamp-2">{group.description}</p>
{group.description}
</p>
)} )}
<h3 className="text-gray-900 mb-3 text-sm"> <h3 className="text-gray-900 mb-3 text-sm">
@ -324,12 +303,10 @@ const MaterialGroups: React.FC = () => {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span <span
className={`px-2 py-0.5 text-xs font-medium rounded-full ${ className={`px-2 py-0.5 text-xs font-medium rounded-full ${
group.isActive group.isActive ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
? "bg-green-100 text-green-800"
: "bg-red-100 text-red-800"
}`} }`}
> >
{group.isActive ? "Aktif" : "Pasif"} {group.isActive ? 'Aktif' : 'Pasif'}
</span> </span>
</div> </div>
</div> </div>
@ -343,21 +320,14 @@ const MaterialGroups: React.FC = () => {
</div> </div>
)} )}
{viewMode === "tree" && ( {viewMode === 'tree' && (
<div className="bg-white shadow-sm rounded-lg p-3"> <div className="bg-white shadow-sm rounded-lg p-3">
{groupTree.map((node) => ( {groupTree.map((node) => (
<GroupTreeNode <GroupTreeNode key={node.id} node={node} onEdit={handleEdit} onDelete={handleDelete} />
key={node.id}
node={node}
onEdit={handleEdit}
onDelete={handleDelete}
/>
))} ))}
{groupTree.length === 0 && ( {groupTree.length === 0 && (
<div className="text-center py-12"> <div className="text-center py-12">
<p className="text-gray-500"> <p className="text-gray-500">Ağaç görünümü için uygun malzeme grubu bulunamadı.</p>
Ağaç görünümü için uygun malzeme grubu bulunamadı.
</p>
</div> </div>
)} )}
</div> </div>
@ -372,18 +342,18 @@ const MaterialGroups: React.FC = () => {
/> />
)} )}
</div> </div>
); )
}; }
// Ağaç Düğümü Komponenti // Ağaç Düğümü Komponenti
const GroupTreeNode: React.FC<{ const GroupTreeNode: React.FC<{
node: MaterialGroupNode; node: MaterialGroupNode
level?: number; level?: number
onEdit: (group: MmMaterialGroup) => void; onEdit: (group: MmMaterialGroup) => void
onDelete: (group: MmMaterialGroup) => void; onDelete: (group: MmMaterialGroup) => void
}> = ({ node, level = 0, onEdit, onDelete }) => { }> = ({ node, level = 0, onEdit, onDelete }) => {
const [isExpanded, setIsExpanded] = useState(level < 1); // İlk seviyeyi açık başlat const [isExpanded, setIsExpanded] = useState(level < 1) // İlk seviyeyi açık başlat
const hasChildren = node.children && node.children.length > 0; const hasChildren = node.children && node.children.length > 0
return ( return (
<div className="relative"> <div className="relative">
@ -391,7 +361,7 @@ const GroupTreeNode: React.FC<{
{level > 0 && ( {level > 0 && (
<span <span
className="absolute border-l border-gray-300" className="absolute border-l border-gray-300"
style={{ left: `${level * 1.25 - 0.7}rem`, top: 0, height: "100%" }} style={{ left: `${level * 1.25 - 0.7}rem`, top: 0, height: '100%' }}
/> />
)} )}
@ -403,7 +373,7 @@ const GroupTreeNode: React.FC<{
{level > 0 && ( {level > 0 && (
<span <span
className="absolute border-t border-gray-300 w-3" className="absolute border-t border-gray-300 w-3"
style={{ left: `${level * 1.25 - 0.7}rem`, top: "1.1rem" }} style={{ left: `${level * 1.25 - 0.7}rem`, top: '1.1rem' }}
/> />
)} )}
@ -414,11 +384,7 @@ const GroupTreeNode: React.FC<{
onClick={() => setIsExpanded(!isExpanded)} onClick={() => setIsExpanded(!isExpanded)}
className="p-1 text-gray-500 hover:text-gray-800 rounded-full hover:bg-gray-200" className="p-1 text-gray-500 hover:text-gray-800 rounded-full hover:bg-gray-200"
> >
{isExpanded ? ( {isExpanded ? <FaChevronDown size={10} /> : <FaChevronRight size={10} />}
<FaChevronDown size={10} />
) : (
<FaChevronRight size={10} />
)}
</button> </button>
)} )}
</div> </div>
@ -431,12 +397,10 @@ const GroupTreeNode: React.FC<{
<span className="text-sm font-medium text-gray-800">{node.name}</span> <span className="text-sm font-medium text-gray-800">{node.name}</span>
<span <span
className={`px-2 py-0.5 text-xs font-medium rounded-full ${ className={`px-2 py-0.5 text-xs font-medium rounded-full ${
node.isActive node.isActive ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
? "bg-green-100 text-green-800"
: "bg-red-100 text-red-800"
}`} }`}
> >
{node.isActive ? "Aktif" : "Pasif"} {node.isActive ? 'Aktif' : 'Pasif'}
</span> </span>
</div> </div>
@ -472,82 +436,66 @@ const GroupTreeNode: React.FC<{
</div> </div>
)} )}
</div> </div>
); )
};
interface MaterialGroupModalProps {
group?: MmMaterialGroup | null;
onSave: (data: Partial<MmMaterialGroup>) => void;
onClose: () => void;
} }
const MaterialGroupModal: React.FC<MaterialGroupModalProps> = ({ interface MaterialGroupModalProps {
group, group?: MmMaterialGroup | null
onSave, onSave: (data: Partial<MmMaterialGroup>) => void
onClose, onClose: () => void
}) => { }
const MaterialGroupModal: React.FC<MaterialGroupModalProps> = ({ group, onSave, onClose }) => {
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
code: group?.code || "", code: group?.code || '',
name: group?.name || "", name: group?.name || '',
parentGroupId: group?.parentGroupId || "", parentGroupId: group?.parentGroupId || '',
description: group?.description || "", description: group?.description || '',
isActive: group?.isActive ?? true, isActive: group?.isActive ?? true,
}); })
const handleSubmit = (e: React.FormEvent) => { const handleSubmit = (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault()
onSave(formData); onSave(formData)
}; }
return ( return (
<div className="fixed inset-0 bg-black bg-opacity-60 flex items-center justify-center p-4 z-50"> <div className="fixed inset-0 bg-black bg-opacity-60 flex items-center justify-center p-4 z-50">
<div className="bg-white rounded-lg w-full max-w-xs"> <div className="bg-white rounded-lg w-full max-w-xs">
<div className="px-3 py-2 border-b border-gray-200"> <div className="px-3 py-2 border-b border-gray-200">
<h3 className="text-sm font-medium text-gray-900"> <h3 className="text-sm font-medium text-gray-900">
{group ? "Malzeme Grubunu Düzenle" : "Yeni Malzeme Grubu"} {group ? 'Malzeme Grubunu Düzenle' : 'Yeni Malzeme Grubu'}
</h3> </h3>
</div> </div>
<form onSubmit={handleSubmit} className="p-3 space-y-2"> <form onSubmit={handleSubmit} className="p-3 space-y-2">
<div> <div>
<label className="block text-xs font-medium text-gray-700 mb-1"> <label className="block text-xs font-medium text-gray-700 mb-1">Grup Kodu</label>
Grup Kodu
</label>
<input <input
type="text" type="text"
value={formData.code} value={formData.code}
onChange={(e) => onChange={(e) => setFormData({ ...formData, code: e.target.value.toUpperCase() })}
setFormData({ ...formData, code: e.target.value.toUpperCase() })
}
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" 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 required
/> />
</div> </div>
<div> <div>
<label className="block text-xs font-medium text-gray-700 mb-1"> <label className="block text-xs font-medium text-gray-700 mb-1">Grup Adı</label>
Grup Adı
</label>
<input <input
type="text" type="text"
value={formData.name} value={formData.name}
onChange={(e) => onChange={(e) => setFormData({ ...formData, name: e.target.value })}
setFormData({ ...formData, name: e.target.value })
}
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" 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 required
/> />
</div> </div>
<div> <div>
<label className="block text-xs font-medium text-gray-700 mb-1"> <label className="block text-xs font-medium text-gray-700 mb-1">Üst Grup</label>
Üst Grup
</label>
<select <select
value={formData.parentGroupId} value={formData.parentGroupId}
onChange={(e) => onChange={(e) => setFormData({ ...formData, parentGroupId: e.target.value })}
setFormData({ ...formData, parentGroupId: e.target.value })
}
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" 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"
> >
<option value="">Grup Seçiniz...</option> <option value="">Grup Seçiniz...</option>
@ -562,14 +510,10 @@ const MaterialGroupModal: React.FC<MaterialGroupModalProps> = ({
</div> </div>
<div> <div>
<label className="block text-xs font-medium text-gray-700 mb-1"> <label className="block text-xs font-medium text-gray-700 mb-1">ıklama</label>
ıklama
</label>
<textarea <textarea
value={formData.description} value={formData.description}
onChange={(e) => onChange={(e) => setFormData({ ...formData, description: e.target.value })}
setFormData({ ...formData, description: e.target.value })
}
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" 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"
rows={3} rows={3}
/> />
@ -580,9 +524,7 @@ const MaterialGroupModal: React.FC<MaterialGroupModalProps> = ({
type="checkbox" type="checkbox"
id="isActive" id="isActive"
checked={formData.isActive} checked={formData.isActive}
onChange={(e) => onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
setFormData({ ...formData, isActive: e.target.checked })
}
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/> />
<label htmlFor="isActive" className="ml-2 text-sm text-gray-700"> <label htmlFor="isActive" className="ml-2 text-sm text-gray-700">
@ -608,7 +550,7 @@ const MaterialGroupModal: React.FC<MaterialGroupModalProps> = ({
</form> </form>
</div> </div>
</div> </div>
); )
}; }
export default MaterialGroups; export default MaterialGroups

View file

@ -1,5 +1,5 @@
import React, { useState } from "react"; import React, { useState } from 'react'
import { useNavigate } from "react-router-dom"; import { useNavigate } from 'react-router-dom'
import { import {
FaPlus, FaPlus,
FaSearch, FaSearch,
@ -9,13 +9,9 @@ import {
FaUser, FaUser,
FaExclamationTriangle, FaExclamationTriangle,
FaEye, FaEye,
} from "react-icons/fa"; } from 'react-icons/fa'
import { import { MmPurchaseRequest, RequestTypeEnum, RequestStatusEnum } from '../../../types/mm'
MmPurchaseRequest, import { mockPurchaseRequests } from '../../../mocks/mockPurchaseRequests'
RequestTypeEnum,
RequestStatusEnum,
} from "../../../types/mm";
import { mockPurchaseRequests } from "../../../mocks/mockPurchaseRequests";
import { import {
getApprovalStatusIcon, getApprovalStatusIcon,
getPriorityColor, getPriorityColor,
@ -24,62 +20,52 @@ import {
getRequestTypeText, getRequestTypeText,
getRequestStatusColor, getRequestStatusColor,
getRequestStatusText, getRequestStatusText,
} from "../../../utils/erp"; } from '../../../utils/erp'
const PurchaseRequests: React.FC = () => { const PurchaseRequests: React.FC = () => {
const navigate = useNavigate(); const navigate = useNavigate()
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState('')
const [filterStatus, setFilterStatus] = useState<RequestStatusEnum | "ALL">( const [filterStatus, setFilterStatus] = useState<RequestStatusEnum | 'ALL'>('ALL')
"ALL" const [filterType, setFilterType] = useState<RequestTypeEnum | 'ALL'>('ALL')
);
const [filterType, setFilterType] = useState<RequestTypeEnum | "ALL">("ALL");
// Mock data - replace with actual API calls // Mock data - replace with actual API calls
const [requests] = useState<MmPurchaseRequest[]>(mockPurchaseRequests); const [requests] = useState<MmPurchaseRequest[]>(mockPurchaseRequests)
const filteredRequests = requests.filter((request) => { const filteredRequests = requests.filter((request) => {
const matchesSearch = const matchesSearch =
request.requestNumber.toLowerCase().includes(searchTerm.toLowerCase()) || request.requestNumber.toLowerCase().includes(searchTerm.toLowerCase()) ||
request.description.toLowerCase().includes(searchTerm.toLowerCase()) || request.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
request.requestedBy.toLowerCase().includes(searchTerm.toLowerCase()); request.requestedBy.toLowerCase().includes(searchTerm.toLowerCase())
const matchesStatus = const matchesStatus = filterStatus === 'ALL' || request.status === filterStatus
filterStatus === "ALL" || request.status === filterStatus; const matchesType = filterType === 'ALL' || request.requestType === filterType
const matchesType =
filterType === "ALL" || request.requestType === filterType;
return matchesSearch && matchesStatus && matchesType; return matchesSearch && matchesStatus && matchesType
}); })
const getDaysUntilRequired = (requiredDate: Date) => { const getDaysUntilRequired = (requiredDate: Date) => {
const days = Math.ceil( const days = Math.ceil((requiredDate.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24))
(requiredDate.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24) return days
); }
return days;
};
const handleEdit = (request: MmPurchaseRequest) => { const handleEdit = (request: MmPurchaseRequest) => {
navigate(`/admin/supplychain/requests/edit/${request.id}`); navigate(`/admin/supplychain/requests/edit/${request.id}`)
}; }
const handleAddNew = () => { const handleAddNew = () => {
navigate("/admin/supplychain/requests/new"); navigate('/admin/supplychain/requests/new')
}; }
const handleViewDetails = (request: MmPurchaseRequest) => { const handleViewDetails = (request: MmPurchaseRequest) => {
navigate(`/admin/supplychain/requests/view/${request.id}`); navigate(`/admin/supplychain/requests/view/${request.id}`)
}; }
return ( return (
<div className="space-y-3 pt-2"> <div className="space-y-3 pt-2">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<h2 className="text-xl font-bold text-gray-900"> <h2 className="text-xl font-bold text-gray-900">Satınalma Talepleri</h2>
Satınalma Talepleri <p className="text-sm text-gray-600">Malzeme, hizmet ve merkezi taleplerini yönetin</p>
</h2>
<p className="text-sm text-gray-600">
Malzeme, hizmet ve merkezi taleplerini yönetin
</p>
</div> </div>
<button <button
onClick={handleAddNew} onClick={handleAddNew}
@ -104,9 +90,7 @@ const PurchaseRequests: React.FC = () => {
</div> </div>
<select <select
value={filterStatus} value={filterStatus}
onChange={(e) => onChange={(e) => setFilterStatus(e.target.value as RequestStatusEnum | 'ALL')}
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" 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="ALL">Tüm Durumlar</option>
@ -118,9 +102,7 @@ const PurchaseRequests: React.FC = () => {
</select> </select>
<select <select
value={filterType} value={filterType}
onChange={(e) => onChange={(e) => setFilterType(e.target.value as RequestTypeEnum | 'ALL')}
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" 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="ALL">Tüm Türler</option>
@ -134,9 +116,7 @@ const PurchaseRequests: React.FC = () => {
<div className="space-y-4"> <div className="space-y-4">
{/* Request List */} {/* Request List */}
<div className="space-y-3 pt-2"> <div className="space-y-3 pt-2">
<h3 className="text-base font-semibold text-gray-900"> <h3 className="text-base font-semibold text-gray-900">Talep Listesi</h3>
Talep Listesi
</h3>
{filteredRequests.map((request) => ( {filteredRequests.map((request) => (
<div <div
key={request.id} key={request.id}
@ -147,27 +127,23 @@ const PurchaseRequests: React.FC = () => {
<div className="flex-1"> <div className="flex-1">
<div className="flex items-center space-x-2 mb-1.5"> <div className="flex items-center space-x-2 mb-1.5">
<FaFileAlt className="w-5 h-5 text-gray-600" /> <FaFileAlt className="w-5 h-5 text-gray-600" />
<h4 className="text-lg font-semibold text-gray-900"> <h4 className="text-lg font-semibold text-gray-900">{request.requestNumber}</h4>
{request.requestNumber}
</h4>
<span <span
className={`px-2 py-1 rounded-full text-xs font-medium ${getRequestTypeColor( className={`px-2 py-1 rounded-full text-xs font-medium ${getRequestTypeColor(
request.requestType request.requestType,
)}`} )}`}
> >
{getRequestTypeText(request.requestType)} {getRequestTypeText(request.requestType)}
</span> </span>
<span <span
className={`px-2 py-1 rounded-full text-xs font-medium ${getRequestStatusColor( className={`px-2 py-1 rounded-full text-xs font-medium ${getRequestStatusColor(
request.status request.status,
)}`} )}`}
> >
{getRequestStatusText(request.status)} {getRequestStatusText(request.status)}
</span> </span>
</div> </div>
<p className="text-sm text-gray-600 mb-1"> <p className="text-sm text-gray-600 mb-1">{request.description}</p>
{request.description}
</p>
<div className="flex items-center space-x-4 text-sm text-gray-500"> <div className="flex items-center space-x-4 text-sm text-gray-500">
<span className="flex items-center"> <span className="flex items-center">
<FaUser className="w-4 h-4 mr-1" /> <FaUser className="w-4 h-4 mr-1" />
@ -175,15 +151,15 @@ const PurchaseRequests: React.FC = () => {
</span> </span>
<span className="flex items-center"> <span className="flex items-center">
<FaCalendar className="w-4 h-4 mr-1" /> <FaCalendar className="w-4 h-4 mr-1" />
{request.requestDate.toLocaleDateString("tr-TR")} {request.requestDate.toLocaleDateString('tr-TR')}
</span> </span>
</div> </div>
</div> </div>
<div className="flex space-x-2"> <div className="flex space-x-2">
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation()
handleViewDetails(request); handleViewDetails(request)
}} }}
className="p-1.5 text-gray-400 hover:text-green-600 hover:bg-green-50 rounded-md transition-colors" className="p-1.5 text-gray-400 hover:text-green-600 hover:bg-green-50 rounded-md transition-colors"
title="Görüntüle" title="Görüntüle"
@ -192,8 +168,8 @@ const PurchaseRequests: React.FC = () => {
</button> </button>
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation()
handleEdit(request); handleEdit(request)
}} }}
className="p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors" className="p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors"
title="Düzenle" title="Düzenle"
@ -210,11 +186,7 @@ const PurchaseRequests: React.FC = () => {
</div> </div>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className="text-gray-500">Öncelik:</span> <span className="text-gray-500">Öncelik:</span>
<span <span className={`font-medium ${getPriorityColor(request.priority)}`}>
className={`font-medium ${getPriorityColor(
request.priority
)}`}
>
{getPriorityText(request.priority)} {getPriorityText(request.priority)}
</span> </span>
</div> </div>
@ -223,13 +195,13 @@ const PurchaseRequests: React.FC = () => {
<span className="font-medium"> <span className="font-medium">
{request.totalAmount {request.totalAmount
? `${request.totalAmount.toLocaleString()}` ? `${request.totalAmount.toLocaleString()}`
: "Belirtilmemiş"} : 'Belirtilmemiş'}
</span> </span>
</div> </div>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className="text-gray-500">Gerekli Tarih:</span> <span className="text-gray-500">Gerekli Tarih:</span>
<span className="font-medium"> <span className="font-medium">
{request.requiredDate.toLocaleDateString("tr-TR")} {request.requiredDate.toLocaleDateString('tr-TR')}
</span> </span>
</div> </div>
</div> </div>
@ -241,36 +213,27 @@ const PurchaseRequests: React.FC = () => {
<FaExclamationTriangle className="w-4 h-4" /> <FaExclamationTriangle className="w-4 h-4" />
<span className="text-sm"> <span className="text-sm">
{getDaysUntilRequired(request.requiredDate) <= 0 {getDaysUntilRequired(request.requiredDate) <= 0
? "Gerekli tarih geçti!" ? 'Gerekli tarih geçti!'
: `${getDaysUntilRequired( : `${getDaysUntilRequired(request.requiredDate)} gün kaldı`}
request.requiredDate
)} gün kaldı`}
</span> </span>
</div> </div>
)} )}
{/* Items Details */} {/* Items Details */}
<div className="mt-3 mb-3"> <div className="mt-3 mb-3">
<h4 className="text-sm font-medium text-gray-900 mb-1.5"> <h4 className="text-sm font-medium text-gray-900 mb-1.5">Talep Kalemleri</h4>
Talep Kalemleri
</h4>
<div className="space-y-2"> <div className="space-y-2">
{request.items.map((item) => ( {request.items.map((item) => (
<div key={item.id} className="bg-gray-50 p-2 rounded-lg"> <div key={item.id} className="bg-gray-50 p-2 rounded-lg">
<div className="flex items-center justify-between mb-1.5"> <div className="flex items-center justify-between mb-1.5">
<div className="flex-1"> <div className="flex-1">
<p className="font-medium text-gray-900"> <p className="font-medium text-gray-900">
{item.specification || "Malzeme"} {item.specification || 'Malzeme'}
</p> </p>
<p className="text-sm text-gray-600"> <p className="text-sm text-gray-600">
Malzeme ID: {item.materialId} | Miktar:{" "} Malzeme ID: {item.materialId} | Miktar: {item.quantity} {item.unit}
{item.quantity} {item.unit}
{item.estimatedPrice && ( {item.estimatedPrice && (
<> <> | Tahmini Fiyat: {item.estimatedPrice.toLocaleString()}</>
{" "}
| Tahmini Fiyat:
{item.estimatedPrice.toLocaleString()}
</>
)} )}
</p> </p>
</div> </div>
@ -281,9 +244,7 @@ const PurchaseRequests: React.FC = () => {
)} )}
</div> </div>
{item.justification && ( {item.justification && (
<div className="text-xs text-gray-500"> <div className="text-xs text-gray-500">Gerekçe: {item.justification}</div>
Gerekçe: {item.justification}
</div>
)} )}
</div> </div>
))} ))}
@ -296,19 +257,14 @@ const PurchaseRequests: React.FC = () => {
<span className="text-sm text-gray-500">Onaylar:</span> <span className="text-sm text-gray-500">Onaylar:</span>
<div className="flex space-x-1"> <div className="flex space-x-1">
{request.approvals.map((approval) => ( {request.approvals.map((approval) => (
<div <div key={approval.id} className="flex items-center space-x-1">
key={approval.id}
className="flex items-center space-x-1"
>
{getApprovalStatusIcon(approval.status)} {getApprovalStatusIcon(approval.status)}
</div> </div>
))} ))}
</div> </div>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<span className="text-xs text-gray-400"> <span className="text-xs text-gray-400">{request.items.length} kalem</span>
{request.items.length} kalem
</span>
</div> </div>
</div> </div>
</div> </div>
@ -317,9 +273,7 @@ const PurchaseRequests: React.FC = () => {
{filteredRequests.length === 0 && ( {filteredRequests.length === 0 && (
<div className="text-center py-6"> <div className="text-center py-6">
<FaFileAlt className="w-12 h-12 text-gray-400 mx-auto mb-4" /> <FaFileAlt className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<h3 className="text-lg font-medium text-gray-900 mb-2"> <h3 className="text-lg font-medium text-gray-900 mb-2">Talep bulunamadı</h3>
Talep bulunamadı
</h3>
<p className="text-gray-500"> <p className="text-gray-500">
Arama kriterlerinizi değiştirin veya yeni bir talep ekleyin. Arama kriterlerinizi değiştirin veya yeni bir talep ekleyin.
</p> </p>
@ -328,7 +282,7 @@ const PurchaseRequests: React.FC = () => {
</div> </div>
</div> </div>
</div> </div>
); )
}; }
export default PurchaseRequests; export default PurchaseRequests