lucide-react komponenti kaldırıldı.

This commit is contained in:
Sedat Öztürk 2025-08-16 22:47:24 +03:00
parent 4fada60029
commit 8ddede546d
61 changed files with 877 additions and 11810 deletions

View file

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

11051
ui/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,6 @@
"jspdf": "^3.0.1",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"lucide-react": "^0.484.0",
"react": "^18.3.1",
"react-advanced-cropper": "^0.20.0",
"react-arborist": "^3.4.0",

View file

@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from 'react'
import Editor from '@monaco-editor/react'
import { ComponentDefinition } from '../../@types/componentInfo'
import { generateSingleComponentJSX, generateUniqueId } from '@/utils/codeParser'
import { Check, Code, Loader, MousePointer, Save, Settings, X } from 'lucide-react'
import { FaCheck, FaCode, FaSpinner, FaMousePointer, FaSave, FaCog, FaTimes } from 'react-icons/fa'
interface CodeEditorProps {
code: string
@ -427,9 +427,9 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({
className="px-3 py-2 bg-gray-700 text-gray-300 rounded-lg text-xs font-medium hover:bg-gray-600 transition-colors flex items-center gap-2 disabled:opacity-50"
>
{isFormatting ? (
<Loader className="w-4 h-4 animate-spin" />
<FaSpinner className="w-4 h-4 animate-spin" />
) : (
<Code className="w-4 h-4" />
<FaCode className="w-4 h-4" />
)}
Formatla
</button>
@ -442,7 +442,7 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({
: 'bg-gray-700 text-gray-300 hover:bg-gray-600'
}`}
>
<Settings className="w-4 h-4" />
<FaCog className="w-4 h-4" />
Ayarlar
</button>
@ -450,7 +450,7 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({
onClick={handleResetChanges}
className="px-3 py-2 bg-red-600 text-white rounded-lg text-xs font-medium hover:bg-red-700 transition-colors flex items-center gap-2"
>
<X className="w-4 h-4" />
<FaTimes className="w-4 h-4" />
Sıfırla
</button>
@ -458,7 +458,7 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({
onClick={handleApplyChanges}
className="px-3 py-2 bg-green-600 text-white rounded-lg text-xs font-medium hover:bg-green-700 transition-colors flex items-center gap-2"
>
<Check className="w-4 h-4" />
<FaCheck className="w-4 h-4" />
Uygula
</button>
</div>
@ -467,7 +467,7 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({
onClick={onComponentSave}
className="flex items-center gap-2 bg-yellow-600 text-white px-4 py-2 rounded-lg hover:bg-yellow-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed shadow-sm"
>
<Save className="w-4 h-4" />
<FaSave className="w-4 h-4" />
Kaydet
</button>
</div>
@ -622,12 +622,12 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({
{hasChanges && <span className="text-orange-400"> Kaydedilmemiş değişiklikler</span>}
{showSuccessMessage && (
<span className="text-green-400 flex items-center gap-1">
<Check className="w-4 h-4" />
<FaCheck className="w-4 h-4" />
</span>
)}
{isDragOver && (
<span className="text-blue-400 flex items-center gap-1">
<MousePointer className="w-4 h-4" />
<FaMousePointer className="w-4 h-4" />
Bileşeni bırakmaya hazır
</span>
)}

View file

@ -1,8 +1,9 @@
import React, { useMemo, useState } from "react";
import { Search, Square } from "lucide-react";
import * as Icons from "lucide-react";
import { FaSquare } from 'react-icons/fa';
import { AiOutlineSearch } from 'react-icons/ai';
import { ComponentDefinition, HookInfo, PropertyInfo } from "../../@types/componentInfo";
import { getAllComponentDefinitions } from "./data/componentDefinitions";
import navigationIcon from "@/configs/navigation-icon.config";
interface ComponentLibraryProps {
onDragStart: (componentDef: ComponentDefinition, e: React.DragEvent) => void;
@ -86,9 +87,8 @@ export const ComponentLibrary: React.FC<ComponentLibraryProps> = ({
}))
.filter((cat) => cat.components.length > 0);
const getIcon = (iconName: string) => {
const IconComponent = (Icons as any)[iconName];
return IconComponent || Square;
const getIcon = (iconName: string): React.ComponentType<any> => {
return navigationIcon[iconName] || FaSquare;
};
return (
@ -96,7 +96,7 @@ export const ComponentLibrary: React.FC<ComponentLibraryProps> = ({
{/* Arama kutusu */}
<div className="p-4 border-b border-gray-700">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
<AiOutlineSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
<input
type="text"
placeholder="Search Components..."

View file

@ -1,5 +1,11 @@
import React from "react";
import { Settings, X, PanelTop as Panels, Eye, EyeOff } from "lucide-react";
import {
FaCog,
FaTimes,
FaBars,
FaEye,
FaEyeSlash
} from 'react-icons/fa';
import { PanelState } from "./data/componentDefinitions";
interface PanelManagerProps {
@ -19,8 +25,8 @@ export const PanelManager: React.FC<PanelManagerProps> = ({
if (!isOpen) return null;
const paneller = [
{ key: "toolbox" as keyof PanelState, label: "Toolbox", icon: Panels },
{ key: "properties" as keyof PanelState, label: "Properties", icon: Settings },
{ key: "toolbox" as keyof PanelState, label: "Toolbox", icon: FaBars },
{ key: "properties" as keyof PanelState, label: "Properties", icon: FaCog },
];
return (
@ -28,7 +34,7 @@ export const PanelManager: React.FC<PanelManagerProps> = ({
<div className="bg-white rounded-lg shadow-xl w-96 max-w-full mx-4">
<div className="flex items-center justify-between p-4 border-b border-gray-200">
<div className="flex items-center space-x-2">
<Panels className="w-5 h-5 text-blue-600" />
<FaBars className="w-5 h-5 text-blue-600" />
<h2 className="text-lg font-semibold text-gray-900">Panel Manager</h2>
</div>
<button
@ -36,7 +42,7 @@ export const PanelManager: React.FC<PanelManagerProps> = ({
className="p-1 hover:bg-gray-100 rounded transition-colors"
title="Kapat"
>
<X className="w-5 h-5 text-gray-500" />
<FaTimes className="w-5 h-5 text-gray-500" />
</button>
</div>
<div className="p-4">
@ -54,7 +60,7 @@ export const PanelManager: React.FC<PanelManagerProps> = ({
className={`p-1 rounded transition-colors ${panelState[key] ? "text-blue-600 hover:bg-blue-100" : "text-gray-400 hover:bg-gray-200"}`}
title={panelState[key] ? "Hide" : "Show"}
>
{panelState[key] ? <Eye className="w-4 h-4" /> : <EyeOff className="w-4 h-4" />}
{panelState[key] ? <FaEye className="w-4 h-4" /> : <FaEyeSlash className="w-4 h-4" />}
</button>
</div>
))}

View file

@ -1,105 +1,103 @@
import React, { useEffect, useState } from "react";
import * as Babel from "@babel/standalone";
import axios from "axios";
import {
Alert,
Avatar,
Badge,
Button,
Calendar,
Card,
Checkbox,
ConfigProvider,
DatePicker,
Dialog,
Drawer,
Dropdown,
FormItem,
FormContainer,
Input,
InputGroup,
Menu,
MenuItem,
Notification,
Pagination,
Progress,
Radio,
RangeCalendar,
ScrollBar,
Segment,
Select,
Skeleton,
Spinner,
Steps,
Switcher,
Table,
Tabs,
Tag,
TimeInput,
Timeline,
toast,
Tooltip,
Upload,
} from "../ui";
import { useComponents } from "../../contexts/ComponentContext";
import ErrorBoundary from "./ErrorBoundary";
import React, { useEffect, useState } from 'react'
import * as Babel from '@babel/standalone'
import axios from 'axios'
import { useComponents } from '../../contexts/ComponentContext'
import ErrorBoundary from './ErrorBoundary'
import { toast } from '../ui'
const compileComponent = (code: string, scope: Record<string, any> = {}) => {
const transpiled = Babel.transform(code, {
filename: "component.tsx",
presets: ["typescript", "react"],
plugins: ["transform-modules-commonjs"],
}).code;
filename: 'component.tsx',
presets: ['typescript', 'react'],
plugins: ['transform-modules-commonjs'],
}).code
const module = { exports: {} };
const module = { exports: {} }
const require = (moduleName: string) => {
if (moduleName === "react") return React;
if (moduleName === "axios") return axios;
throw new Error(`Modül bulunamadı: ${moduleName}`);
};
if (moduleName === 'react') return React
if (moduleName === 'axios') return axios
throw new Error(`Modül bulunamadı: ${moduleName}`)
}
const scopedEval = new Function(
"module",
"exports",
"require",
'module',
'exports',
'require',
...Object.keys(scope),
transpiled!
);
transpiled!,
)
scopedEval(module, module.exports, require, ...Object.values(scope));
scopedEval(module, module.exports, require, ...Object.values(scope))
const compiledModule = module.exports as any;
return compiledModule.default;
};
const compiledModule = module.exports as any
return compiledModule.default
}
interface DynamicRendererProps {
componentName: string;
dependencies?: string[];
componentName: string
dependencies?: string[]
}
const DynamicRenderer: React.FC<DynamicRendererProps> = ({
componentName,
dependencies: externalDeps,
}) => {
const [Component, setComponent] = useState<React.ComponentType<any> | null>(
null
);
const { getComponentByName, components } = useComponents();
// Lazy load for UI components
const Alert = React.lazy(() => import('../ui/Alert'))
const Avatar = React.lazy(() => import('../ui/Avatar'))
const Badge = React.lazy(() => import('../ui/Badge'))
const Button = React.lazy(() => import('../ui/Button'))
const Calendar = React.lazy(() => import('../ui/Calendar'))
const Card = React.lazy(() => import('../ui/Card'))
const Checkbox = React.lazy(() => import('../ui/Checkbox'))
const ConfigProvider = React.lazy(() => import('../ui/ConfigProvider'))
const DatePicker = React.lazy(() => import('../ui/DatePicker'))
const Dialog = React.lazy(() => import('../ui/Dialog'))
const Drawer = React.lazy(() => import('../ui/Drawer'))
const Dropdown = React.lazy(() => import('../ui/Dropdown'))
const FormItem = React.lazy(() => import('../ui/Form/FormItem'))
const FormContainer = React.lazy(() => import('../ui/Form/FormContainer'))
const Input = React.lazy(() => import('../ui/Input'))
const InputGroup = React.lazy(() => import('../ui/InputGroup'))
const Menu = React.lazy(() => import('../ui/Menu'))
const MenuItem = React.lazy(() => import('../ui/MenuItem'))
const Notification = React.lazy(() => import('../ui/Notification'))
const Pagination = React.lazy(() => import('../ui/Pagination'))
const Progress = React.lazy(() => import('../ui/Progress'))
const Radio = React.lazy(() => import('../ui/Radio'))
const RangeCalendar = React.lazy(() => import('../ui/RangeCalendar'))
const ScrollBar = React.lazy(() => import('../ui/ScrollBar'))
const Segment = React.lazy(() => import('../ui/Segment'))
const Select = React.lazy(() => import('../ui/Select'))
const Skeleton = React.lazy(() => import('../ui/Skeleton'))
const Spinner = React.lazy(() => import('../ui/Spinner'))
const Steps = React.lazy(() => import('../ui/Steps'))
const Switcher = React.lazy(() => import('../ui/Switcher'))
const Table = React.lazy(() => import('../ui/Table'))
const Tabs = React.lazy(() => import('../ui/Tabs'))
const Tag = React.lazy(() => import('../ui/Tag'))
const TimeInput = React.lazy(() => import('../ui/TimeInput'))
const Timeline = React.lazy(() => import('../ui/Timeline'))
const Tooltip = React.lazy(() => import('../ui/Tooltip'))
const Upload = React.lazy(() => import('../ui/Upload'))
const [Component, setComponent] = useState<React.ComponentType<any> | null>(null)
const { getComponentByName, components } = useComponents()
useEffect(() => {
setComponent(null);
setComponent(null)
const storedComponent = getComponentByName(componentName);
if (!storedComponent) return;
const storedComponent = getComponentByName(componentName)
if (!storedComponent) return
const map = new Map(
components.map((c) => {
// Parse dependencies from JSON string
let componentDeps: string[] = [];
let componentDeps: string[] = []
try {
componentDeps = c.dependencies ? JSON.parse(c.dependencies) : [];
componentDeps = c.dependencies ? JSON.parse(c.dependencies) : []
} catch {
componentDeps = [];
componentDeps = []
}
return [
@ -109,11 +107,11 @@ const DynamicRenderer: React.FC<DynamicRendererProps> = ({
jsx_code: c.code,
dependencies: Array.isArray(componentDeps) ? componentDeps : [],
},
];
})
);
]
}),
)
const compiled: Record<string, any> = {};
const compiled: Record<string, any> = {}
const staticComponents: Record<string, any> = {
Alert,
@ -154,53 +152,51 @@ const DynamicRenderer: React.FC<DynamicRendererProps> = ({
toast,
Tooltip,
Upload,
};
}
const compileWithDependencies = (name: string): any => {
if (compiled[name]) return compiled[name];
if (compiled[name]) return compiled[name]
const entry = map.get(name);
const entry = map.get(name)
if (!entry && staticComponents[name]) {
compiled[name] = staticComponents[name];
return staticComponents[name];
compiled[name] = staticComponents[name]
return staticComponents[name]
}
if (!entry) throw new Error(`Component ${name} not found`);
if (!entry) throw new Error(`Component ${name} not found`)
const depNames =
name === componentName && externalDeps
? externalDeps
: entry.dependencies || [];
name === componentName && externalDeps ? externalDeps : entry.dependencies || []
const deps: Record<string, any> = {};
const deps: Record<string, any> = {}
for (const dep of depNames) {
deps[dep] = compileWithDependencies(dep);
deps[dep] = compileWithDependencies(dep)
}
const comp = compileComponent(entry.jsx_code, {
React,
...staticComponents,
...deps,
});
compiled[name] = comp;
})
compiled[name] = comp
return comp;
};
return comp
}
try {
const RootComponent = compileWithDependencies(componentName);
setComponent(() => RootComponent);
const RootComponent = compileWithDependencies(componentName)
setComponent(() => RootComponent)
} catch (err: any) {
console.error("Compilation error:", err);
console.error('Compilation error:', err)
}
}, [componentName, externalDeps, components, getComponentByName]);
}, [componentName, externalDeps, components, getComponentByName])
if (!Component) return <div>Yükleniyor...</div>;
if (!Component) return <div>Yükleniyor...</div>
return (
<ErrorBoundary key={componentName}>
<Component />
</ErrorBoundary>
);
};
)
}
export default DynamicRenderer;
export default DynamicRenderer

View file

@ -2,20 +2,20 @@ import React, { useState } from 'react'
import { useEntities } from '../../contexts/EntityContext'
import axios from 'axios'
import {
Book,
Search,
Filter,
Globe,
Copy,
CheckCircle,
AlertCircle,
Database,
Loader2,
Send,
PlusCircle,
Edit3,
Trash2,
} from 'lucide-react'
FaBook,
FaSearch,
FaFilter,
FaGlobe,
FaCopy,
FaCheckCircle,
FaExclamationCircle,
FaDatabase,
FaSyncAlt,
FaPaperPlane,
FaPlusCircle,
FaEdit,
FaTrash
} from 'react-icons/fa';
import { useLocalization } from '@/utils/hooks/useLocalization'
interface EndpointType {
@ -378,7 +378,7 @@ const ApiManager: React.FC = () => {
</div>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2 bg-blue-100 text-blue-700 px-3 py-1 rounded-full text-sm font-medium">
<Globe className="w-4 h-4" />
<FaGlobe className="w-4 h-4" />
{translate('::App.DeveloperKit.Endpoint.SwaggerCompatible')}
</div>
</div>
@ -397,7 +397,7 @@ const ApiManager: React.FC = () => {
</p>
</div>
<div className="bg-emerald-100 text-emerald-600 p-3 rounded-lg">
<Database className="w-6 h-6" />
<FaDatabase className="w-6 h-6" />
</div>
</div>
</div>
@ -410,7 +410,7 @@ const ApiManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.byMethod.GET}</p>
</div>
<div className="bg-blue-100 text-blue-600 p-3 rounded-lg">
<Book className="w-6 h-6" />
<FaBook className="w-6 h-6" />
</div>
</div>
</div>
@ -423,7 +423,7 @@ const ApiManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.byMethod.POST}</p>
</div>
<div className="bg-purple-100 text-purple-600 p-3 rounded-lg">
<PlusCircle className="w-6 h-6" />
<FaPlusCircle className="w-6 h-6" />
</div>
</div>
</div>
@ -436,7 +436,7 @@ const ApiManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.byMethod.PUT}</p>
</div>
<div className="bg-purple-100 text-purple-600 p-3 rounded-lg">
<Edit3 className="w-6 h-6" />
<FaEdit className="w-6 h-6" />
</div>
</div>
</div>
@ -449,7 +449,7 @@ const ApiManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.byMethod.DELETE}</p>
</div>
<div className="bg-purple-100 text-purple-600 p-3 rounded-lg">
<Trash2 className="w-6 h-6" />
<FaTrash className="w-6 h-6" />
</div>
</div>
</div>
@ -459,7 +459,7 @@ const ApiManager: React.FC = () => {
<div className="bg-white rounded-lg border border-slate-200 p-6 mb-6 shadow-sm">
<div className="flex flex-col lg:flex-row gap-4">
<div className="flex-1 relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<input
type="text"
placeholder={translate('::App.DeveloperKit.Endpoint.SearchPlaceholder')}
@ -470,7 +470,7 @@ const ApiManager: React.FC = () => {
</div>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<Filter className="w-5 h-5 text-slate-500" />
<FaFilter className="w-5 h-5 text-slate-500" />
<select
value={filterMethod}
onChange={(e) =>
@ -531,7 +531,7 @@ const ApiManager: React.FC = () => {
</div>
</div>
<div className="flex items-center gap-2">
<CheckCircle className="w-5 h-5 text-green-500" />
<FaCheckCircle className="w-5 h-5 text-green-500" />
<span className="text-sm text-slate-500">{translate('::App.DeveloperKit.Endpoint.Active')}</span>
</div>
</div>
@ -561,7 +561,7 @@ const ApiManager: React.FC = () => {
className="p-2 text-slate-600 hover:text-slate-900 transition-colors"
title={translate('::App.DeveloperKit.Endpoint.CopyUrl')}
>
<Copy className="w-4 h-4" />
<FaCopy className="w-4 h-4" />
</button>
</div>
</div>
@ -636,7 +636,7 @@ const ApiManager: React.FC = () => {
className="absolute top-2 right-2 p-1 text-slate-600 hover:text-slate-900 transition-colors"
title={translate('::App.DeveloperKit.Endpoint.CopyRequestBody')}
>
<Copy className="w-3 h-3" />
<FaCopy className="w-3 h-3" />
</button>
</div>
</div>
@ -665,7 +665,7 @@ const ApiManager: React.FC = () => {
className="absolute top-2 right-2 p-1 text-slate-600 hover:text-slate-900 transition-colors"
title={translate('::App.DeveloperKit.Endpoint.CopyResponse')}
>
<Copy className="w-3 h-3" />
<FaCopy className="w-3 h-3" />
</button>
</div>
</div>
@ -680,9 +680,9 @@ const ApiManager: React.FC = () => {
className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 disabled:bg-blue-400 disabled:cursor-not-allowed transition-colors text-sm font-medium"
>
{loadingEndpoints.has(endpoint.id) ? (
<Loader2 className="w-4 h-4 animate-spin" />
<FaSyncAlt className="w-4 h-4 animate-spin" />
) : (
<Send className="w-4 h-4" />
<FaPaperPlane className="w-4 h-4" />
)}
{loadingEndpoints.has(endpoint.id) ? translate('::App.DeveloperKit.Endpoint.SendLoading') : translate('::App.DeveloperKit.Endpoint.SendRequest')}
</button>
@ -711,9 +711,9 @@ const ApiManager: React.FC = () => {
<div className="mt-6 p-4 bg-slate-100 rounded-lg">
<div className="flex items-center gap-2 mb-3">
{testResults[endpoint.id].success ? (
<CheckCircle className="w-5 h-5 text-green-500" />
<FaCheckCircle className="w-5 h-5 text-green-500" />
) : (
<AlertCircle className="w-5 h-5 text-red-500" />
<FaExclamationCircle className="w-5 h-5 text-red-500" />
)}
<h5 className="font-semibold text-slate-900">
{translate('::App.DeveloperKit.Endpoint.TestResultLabel')} ({testResults[endpoint.id].status})
@ -748,7 +748,7 @@ const ApiManager: React.FC = () => {
className="absolute top-2 right-2 p-1 text-slate-600 hover:text-slate-900 transition-colors"
title={translate('::App.DeveloperKit.Endpoint.CopyResult')}
>
<Copy className="w-3 h-3" />
<FaCopy className="w-3 h-3" />
</button>
</div>
</div>
@ -762,7 +762,7 @@ const ApiManager: React.FC = () => {
<div className="text-center py-12">
<div className="max-w-md mx-auto">
<div className="bg-slate-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
<Book className="w-8 h-8 text-slate-500" />
<FaBook className="w-8 h-8 text-slate-500" />
</div>
<h3 className="text-lg font-medium text-slate-900 mb-2">
{searchTerm || filterMethod !== 'all'

View file

@ -1,5 +1,5 @@
import { useState, useEffect, useCallback } from 'react'
import { PanelTop as Panels } from 'lucide-react'
import { FaThLarge } from 'react-icons/fa';
import {
parseReactCode,
updateComponentProp,
@ -622,7 +622,7 @@ function CodeLayout() {
className="flex items-center space-x-2 px-3 py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
title="Panel Manager"
>
<Panels className="w-4 h-4 text-gray-600" />
<FaThLarge className="w-4 h-4 text-gray-600" />
<span className="text-sm text-gray-600">Panels</span>
</button>
</div>

View file

@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useComponents } from '../../contexts/ComponentContext'
import { Save, ArrowLeft, AlertCircle, RefreshCw } from 'lucide-react'
import { FaRegSave, FaArrowLeft, FaExclamationCircle, FaSync } from 'react-icons/fa';
import { parseReactCode } from '../../utils/codeParser'
import ComponentPreview from '../../components/componentEditor/ComponentPreview'
import { EditorState } from '../../@types/componentInfo'
@ -143,7 +143,7 @@ const ComponentEditor: React.FC = () => {
return (
<div className="h-screen flex items-center justify-center">
<div className="text-center">
<RefreshCw className="w-8 h-8 text-blue-500 animate-spin mx-auto mb-3" />
<FaSync className="w-8 h-8 text-blue-500 animate-spin mx-auto mb-3" />
<p className="text-slate-600">
{translate('::App.DeveloperKit.ComponentEditor.Loading')}
</p>
@ -162,7 +162,7 @@ const ComponentEditor: React.FC = () => {
onClick={() => navigate(ROUTES_ENUM.protected.saas.developerKitComponents)}
className="flex items-center gap-2 text-slate-600 hover:text-slate-900 transition-colors"
>
<ArrowLeft className="w-4 h-4" />
<FaArrowLeft className="w-4 h-4" />
{translate('::App.DeveloperKit.ComponentEditor.Back')}
</button>
</div>
@ -221,7 +221,7 @@ const ComponentEditor: React.FC = () => {
disabled={isSaving || !name.trim()}
className="flex items-center gap-2 bg-yellow-600 text-white px-4 py-2 rounded-lg hover:bg-yellow-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed shadow-sm"
>
<Save className="w-4 h-4" />
<FaRegSave className="w-4 h-4" />
{isSaving
? translate('::App.DeveloperKit.ComponentEditor.Saving')
: translate('::App.DeveloperKit.ComponentEditor.Save')}
@ -237,7 +237,7 @@ const ComponentEditor: React.FC = () => {
<div className="mb-4 bg-red-50 border border-red-200 rounded-lg p-4">
<div className="flex items-start gap-3">
<div className="bg-red-100 rounded p-1">
<AlertCircle className="w-4 h-4 text-red-600" />
<FaExclamationCircle className="w-4 h-4 text-red-600" />
</div>
<div className="flex-1">
<p className="text-sm text-red-800 font-medium mb-2">

View file

@ -2,19 +2,18 @@ import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import { useComponents } from '../../contexts/ComponentContext'
import {
Plus,
Search,
Edit,
Trash2,
Eye,
EyeOff,
Filter,
Calendar,
Puzzle,
CheckCircle,
XCircle,
View,
} from 'lucide-react'
FaPlus,
FaSearch,
FaRegEdit,
FaTrashAlt,
FaEye,
FaEyeSlash,
FaFilter,
FaCalendarAlt,
FaPuzzlePiece,
FaCheckCircle,
FaTimesCircle,
} from 'react-icons/fa';
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -33,21 +32,21 @@ const ComponentManager: React.FC = () => {
{
name: translate('::App.DeveloperKit.Component.Total'),
value: totalComponents,
icon: Puzzle,
icon: FaPuzzlePiece,
color: 'text-purple-600',
bgColor: 'bg-purple-100',
},
{
name: translate('::App.DeveloperKit.Component.Active'),
value: activeComponents,
icon: CheckCircle,
icon: FaCheckCircle,
color: 'text-emerald-600',
bgColor: 'bg-emerald-100',
},
{
name: translate('::App.DeveloperKit.Component.Inactive'),
value: inactiveComponents,
icon: XCircle,
icon: FaTimesCircle,
color: 'text-slate-600',
bgColor: 'bg-slate-100',
},
@ -100,7 +99,7 @@ const ComponentManager: React.FC = () => {
to={ROUTES_ENUM.protected.saas.developerKitComponentsNew}
className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
{translate('::App.DeveloperKit.Component.New')}
</Link>
</div>
@ -126,7 +125,7 @@ const ComponentManager: React.FC = () => {
<div className="bg-white rounded-lg border border-slate-200 p-6 mb-6">
<div className="flex flex-col sm:flex-row gap-4">
<div className="flex-1 relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<input
type="text"
placeholder={translate('::App.DeveloperKit.Component.SearchPlaceholder')}
@ -136,7 +135,7 @@ const ComponentManager: React.FC = () => {
/>
</div>
<div className="flex items-center gap-2">
<Filter className="w-5 h-5 text-slate-500" />
<FaFilter className="w-5 h-5 text-slate-500" />
<select
value={filterActive}
onChange={(e) => setFilterActive(e.target.value as 'all' | 'active' | 'inactive')}
@ -195,7 +194,7 @@ const ComponentManager: React.FC = () => {
)}
<div className="flex items-center gap-4 text-xs text-slate-500">
<div className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
<FaCalendarAlt className="w-3 h-3" />
<span>
{component.lastModificationTime
? new Date(component.lastModificationTime).toLocaleDateString()
@ -231,12 +230,12 @@ const ComponentManager: React.FC = () => {
>
{component.isActive ? (
<>
<Eye className="w-3 h-3" />
<FaEye className="w-3 h-3" />
{translate('::App.DeveloperKit.Component.Active')}
</>
) : (
<>
<EyeOff className="w-3 h-3" />
<FaEyeSlash className="w-3 h-3" />
{translate('::App.DeveloperKit.Component.Inactive')}
</>
)}
@ -252,7 +251,7 @@ const ComponentManager: React.FC = () => {
className="p-2 text-slate-600 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors"
title={translate('::App.DeveloperKit.Component.Edit')}
>
<Edit className="w-4 h-4" />
<FaRegEdit className="w-4 h-4" />
</Link>
<Link
to={ROUTES_ENUM.protected.saas.developerKitComponentsView.replace(
@ -262,14 +261,14 @@ const ComponentManager: React.FC = () => {
className="p-2 text-slate-600 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors"
title={translate('::App.DeveloperKit.Component.View')}
>
<View className="w-4 h-4" />
<FaEye className="w-4 h-4" />
</Link>
<button
onClick={() => handleDelete(component.id, component.name)}
className="p-2 text-slate-600 hover:text-red-600 hover:bg-red-50 rounded transition-colors"
title={translate('::App.DeveloperKit.Component.Delete')}
>
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
</button>
</div>
</div>
@ -281,7 +280,7 @@ const ComponentManager: React.FC = () => {
<div className="text-center py-12">
<div className="max-w-md mx-auto">
<div className="bg-slate-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
<Plus className="w-8 h-8 text-slate-500" />
<FaPlus className="w-8 h-8 text-slate-500" />
</div>
<h3 className="text-lg font-medium text-slate-900 mb-2">
{searchTerm || filterActive !== 'all'
@ -298,7 +297,7 @@ const ComponentManager: React.FC = () => {
to={ROUTES_ENUM.protected.saas.developerKitComponentsNew}
className="inline-flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
{translate('::App.DeveloperKit.Component.Empty.Initial.Action')}
</Link>
)}

View file

@ -4,18 +4,19 @@ import { useComponents } from "../../contexts/ComponentContext";
import { useEntities } from "../../contexts/EntityContext";
import { useSystemHealth } from "../../utils/hooks/useDeveloperKit";
import {
Database,
Zap,
Server,
Puzzle,
Activity,
Code,
CheckCircle,
ArrowRight,
AlertCircle,
Wifi,
WifiOff,
} from "lucide-react";
FaDatabase,
FaBolt,
FaServer,
FaPuzzlePiece,
FaCog,
FaChartLine,
FaCode,
FaCheckCircle,
FaArrowRight,
FaExclamationCircle,
FaWifi,
FaWindowClose
} from 'react-icons/fa';
import { ROUTES_ENUM } from "@/routes/route.constant";
import { useLocalization } from "@/utils/hooks/useLocalization";
@ -30,7 +31,7 @@ const Dashboard: React.FC = () => {
name: translate('::App.DeveloperKit.Dashboard.Stats.Entities'),
value: entities.filter((e) => e.isActive).length,
total: entities.length,
icon: Database,
icon: FaDatabase,
color: "text-blue-600",
bgColor: "bg-blue-100",
href: ROUTES_ENUM.protected.saas.developerKitEntities,
@ -39,7 +40,7 @@ const Dashboard: React.FC = () => {
name: translate('::App.DeveloperKit.Dashboard.Stats.Migrations'),
value: migrations.filter((m) => m.status === "pending").length,
total: migrations.length,
icon: Zap,
icon: FaBolt,
color: "text-yellow-600",
bgColor: "bg-yellow-100",
href: ROUTES_ENUM.protected.saas.developerKitMigrations,
@ -48,7 +49,7 @@ const Dashboard: React.FC = () => {
name: translate('::App.DeveloperKit.Dashboard.Stats.APIs'),
value: generatedEndpoints.filter((e) => e.isActive).length,
total: generatedEndpoints.length,
icon: Server,
icon: FaServer,
color: "text-emerald-600",
bgColor: "bg-emerald-100",
href: ROUTES_ENUM.protected.saas.developerKitEndpoints,
@ -57,7 +58,7 @@ const Dashboard: React.FC = () => {
name: translate('::App.DeveloperKit.Dashboard.Stats.Components'),
value: components?.filter((c) => c.isActive).length,
total: components?.length,
icon: Puzzle,
icon: FaPuzzlePiece,
color: "text-purple-600",
bgColor: "bg-purple-100",
href: ROUTES_ENUM.protected.saas.developerKitComponents,
@ -69,7 +70,7 @@ const Dashboard: React.FC = () => {
step: 1,
title: translate('::App.DeveloperKit.Dashboard.Flow.CreateEntity'),
description: translate('::App.DeveloperKit.Dashboard.Flow.CreateEntity.Desc'),
icon: Database,
icon: FaDatabase,
color: "bg-blue-600",
href: ROUTES_ENUM.protected.saas.developerKitEntitiesNew,
status: "ready",
@ -78,7 +79,7 @@ const Dashboard: React.FC = () => {
step: 2,
title: translate('::App.DeveloperKit.Dashboard.Flow.GenerateMigration'),
description: translate('::App.DeveloperKit.Dashboard.Flow.GenerateMigration.Desc'),
icon: Zap,
icon: FaBolt,
color: "bg-yellow-600",
href: ROUTES_ENUM.protected.saas.developerKitMigrations,
status: entities.some((e) => e.migrationStatus === "pending")
@ -89,7 +90,7 @@ const Dashboard: React.FC = () => {
step: 3,
title: translate('::App.DeveloperKit.Dashboard.Flow.ApplyMigration'),
description: translate('::App.DeveloperKit.Dashboard.Flow.ApplyMigration.Desc'),
icon: CheckCircle,
icon: FaCheckCircle,
color: "bg-green-600",
href: ROUTES_ENUM.protected.saas.developerKitMigrations,
status: migrations.some((m) => m.status === "pending")
@ -100,7 +101,7 @@ const Dashboard: React.FC = () => {
step: 4,
title: translate('::App.DeveloperKit.Dashboard.Flow.GenerateAPI'),
description: translate('::App.DeveloperKit.Dashboard.Flow.GenerateAPI.Desc'),
icon: Server,
icon: FaServer,
color: "bg-emerald-600",
href: ROUTES_ENUM.protected.saas.developerKitEndpoints,
status: "ready",
@ -109,7 +110,7 @@ const Dashboard: React.FC = () => {
step: 5,
title: translate('::App.DeveloperKit.Dashboard.Flow.BuildComponent'),
description: translate('::App.DeveloperKit.Dashboard.Flow.BuildComponent.Desc'),
icon: Puzzle,
icon: FaPuzzlePiece,
color: "bg-purple-600",
href: ROUTES_ENUM.protected.saas.developerKitComponentsNew,
status: "ready",
@ -132,23 +133,23 @@ const Dashboard: React.FC = () => {
].slice(0, 3);
const systemHealth = [
{ name: translate('::App.DeveloperKit.Dashboard.SystemHealth.Frontend'), status: translate('::App.DeveloperKit.Dashboard.SystemHealth.Healthy'), icon: Code },
{ name: translate('::App.DeveloperKit.Dashboard.SystemHealth.Frontend'), status: translate('::App.DeveloperKit.Dashboard.SystemHealth.Healthy'), icon: FaCode },
{
name: translate('::App.DeveloperKit.Dashboard.SystemHealth.Backend'),
status: isOnline ? translate('::App.DeveloperKit.Dashboard.SystemHealth.Healthy') : translate('::App.DeveloperKit.Dashboard.SystemHealth.Offline'),
icon: Server,
icon: FaServer,
},
{
name: translate('::App.DeveloperKit.Dashboard.SystemHealth.Database'),
status: isOnline ? translate('::App.DeveloperKit.Dashboard.SystemHealth.Healthy') : translate('::App.DeveloperKit.Dashboard.SystemHealth.Unknown'),
icon: Database,
icon: FaDatabase,
},
{
name: translate('::App.DeveloperKit.Dashboard.SystemHealth.Migrations'),
status: migrations.some((m) => m.status === "failed")
? translate('::App.DeveloperKit.Dashboard.SystemHealth.Warning')
: translate('::App.DeveloperKit.Dashboard.SystemHealth.Healthy'),
icon: Zap,
icon: FaBolt,
},
];
@ -183,12 +184,12 @@ const Dashboard: React.FC = () => {
/>
{isOnline ? (
<>
<Wifi className="w-4 h-4" />
<FaWifi className="w-4 h-4" />
{translate('::App.DeveloperKit.Dashboard.SystemHealth.Online')}
</>
) : (
<>
<WifiOff className="w-4 h-4" />
<FaWindowClose className="w-4 h-4" />
{translate('::App.DeveloperKit.Dashboard.SystemHealth.OfflineStatus')}
</>
)}
@ -212,7 +213,7 @@ const Dashboard: React.FC = () => {
>
<Icon className="w-6 h-6" />
</div>
<ArrowRight className="w-4 h-4 text-slate-400 group-hover:text-slate-600 transition-colors" />
<FaArrowRight className="w-4 h-4 text-slate-400 group-hover:text-slate-600 transition-colors" />
</div>
<div>
<p className="text-sm font-medium text-slate-600">
@ -233,7 +234,7 @@ const Dashboard: React.FC = () => {
{/* Development Flow */}
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-8">
<div className="flex items-center gap-2 mb-6">
<Activity className="w-6 h-6 text-blue-600" />
<FaCog className="w-6 h-6 text-blue-600" />
<h2 className="text-xl font-semibold text-slate-900">
{translate('::App.DeveloperKit.Dashboard.Flow.Title')}
</h2>
@ -260,7 +261,7 @@ const Dashboard: React.FC = () => {
{flow.status === "action-needed" && (
<div className="absolute -top-2 -right-2">
<div className="bg-red-500 text-white rounded-full w-6 h-6 flex items-center justify-center">
<AlertCircle className="w-4 h-4" />
<FaExclamationCircle className="w-4 h-4" />
</div>
</div>
)}
@ -268,7 +269,7 @@ const Dashboard: React.FC = () => {
{index < developmentFlow.length - 1 && (
<div className="hidden lg:block absolute top-1/2 -right-3 transform -translate-y-1/2">
<ArrowRight className="w-6 h-6 text-slate-300" />
<FaArrowRight className="w-6 h-6 text-slate-300" />
</div>
)}
</Link>
@ -281,7 +282,7 @@ const Dashboard: React.FC = () => {
{/* System Health */}
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-6">
<div className="flex items-center gap-2 mb-4">
<Activity className="w-5 h-5 text-green-500" />
<FaCog className="w-5 h-5 text-green-500" />
<h3 className="text-lg font-semibold text-slate-900">
{translate('::App.DeveloperKit.Dashboard.SystemHealth.Title') }
</h3>
@ -374,14 +375,14 @@ const Dashboard: React.FC = () => {
to={ROUTES_ENUM.protected.saas.developerKitEntitiesEdit.replace(':id', entity.id)}
className="text-blue-600 hover:text-blue-700"
>
<Database className="w-4 h-4" />
<FaDatabase className="w-4 h-4" />
</Link>
</div>
</div>
))
) : (
<div className="text-center py-8">
<Database className="w-12 h-12 text-slate-300 mx-auto mb-2" />
<FaDatabase className="w-12 h-12 text-slate-300 mx-auto mb-2" />
<p className="text-slate-500 mb-2">{translate('::App.DeveloperKit.Dashboard.Empty.Entity')}</p>
<Link
to={ROUTES_ENUM.protected.saas.developerKitEntitiesNew}
@ -437,14 +438,14 @@ const Dashboard: React.FC = () => {
to={ROUTES_ENUM.protected.saas.developerKitMigrations}
className="text-yellow-600 hover:text-yellow-700"
>
<Zap className="w-4 h-4" />
<FaBolt className="w-4 h-4" />
</Link>
</div>
</div>
))
) : (
<div className="text-center py-8">
<Zap className="w-12 h-12 text-slate-300 mx-auto mb-2" />
<FaBolt className="w-12 h-12 text-slate-300 mx-auto mb-2" />
<p className="text-slate-500 mb-2">{translate('::App.DeveloperKit.Dashboard.Empty.Migration')}</p>
<Link
to={ROUTES_ENUM.protected.saas.developerKitEntitiesNew}
@ -508,14 +509,14 @@ const Dashboard: React.FC = () => {
to="/docs"
className="text-emerald-600 hover:text-emerald-700"
>
<Server className="w-4 h-4" />
<FaServer className="w-4 h-4" />
</Link>
</div>
</div>
))
) : (
<div className="text-center py-8">
<Server className="w-12 h-12 text-slate-300 mx-auto mb-2" />
<FaServer className="w-12 h-12 text-slate-300 mx-auto mb-2" />
<p className="text-slate-500 mb-2">{translate('::App.DeveloperKit.Dashboard.Empty.Endpoint')}</p>
<Link
to={ROUTES_ENUM.protected.saas.developerKitEndpointsNew}

View file

@ -1,7 +1,14 @@
import React, { useState, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { useEntities, EntityFieldType } from '../../contexts/EntityContext'
import { Save, ArrowLeft, Plus, Trash2, Database, HelpCircle } from 'lucide-react'
import {
FaSave,
FaArrowLeft,
FaPlus,
FaTrashAlt,
FaDatabase,
FaQuestionCircle
} from 'react-icons/fa';
import { CreateUpdateCustomEntityFieldDto, CustomEntityField } from '@/proxy/developerKit/models'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -172,12 +179,12 @@ const EntityEditor: React.FC = () => {
onClick={() => navigate(ROUTES_ENUM.protected.saas.developerKitEntities)}
className="flex items-center gap-2 text-slate-600 hover:text-slate-900 transition-colors"
>
<ArrowLeft className="w-4 h-4" />
<FaArrowLeft className="w-4 h-4" />
{translate('::App.DeveloperKit.EntityEditor.Back')}
</button>
<div className="h-6 w-px bg-slate-300" />
<div className="flex items-center gap-2">
<Database className="w-6 h-6 text-blue-600" />
<FaDatabase className="w-6 h-6 text-blue-600" />
<h1 className="text-xl font-semibold text-slate-900">
{isEditing
? translate('::App.DeveloperKit.EntityEditor.Title.Edit')
@ -189,12 +196,12 @@ const EntityEditor: React.FC = () => {
{/* Help Tooltip */}
<div className="relative group">
<button className="p-2 text-slate-400 hover:text-slate-600 transition-colors">
<HelpCircle className="w-4 h-4" />
<FaQuestionCircle className="w-4 h-4" />
</button>
<div className="absolute right-0 top-full mt-2 w-96 bg-slate-900 text-white text-sm rounded-lg p-4 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 shadow-xl">
<div className="absolute -top-1 right-4 w-2 h-2 bg-slate-900 rotate-45"></div>
<div className="flex items-center gap-2 mb-2">
<Database className="w-4 h-4 text-blue-400" />
<FaDatabase className="w-4 h-4 text-blue-400" />
<h4 className="font-semibold text-blue-200">{translate('::App.DeveloperKit.EntityEditor.Tooltip.Title')}</h4>
</div>
<p className="text-slate-300 leading-relaxed">
@ -208,7 +215,7 @@ const EntityEditor: React.FC = () => {
disabled={isSaving || !name.trim() || !displayName.trim() || !tableName.trim()}
className="flex items-center gap-2 bg-emerald-600 text-white px-4 py-2 rounded-lg hover:bg-emerald-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed shadow-sm"
>
<Save className="w-4 h-4" />
<FaSave className="w-4 h-4" />
{isSaving ? translate('::App.DeveloperKit.EntityEditor.Saving') : translate('::App.DeveloperKit.EntityEditor.Save')}
</button>
</div>
@ -370,7 +377,7 @@ const EntityEditor: React.FC = () => {
onClick={addField}
className="flex items-center gap-2 bg-blue-600 text-white px-3 py-2 rounded-lg hover:bg-blue-700 transition-colors text-sm"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
{translate('::App.DeveloperKit.EntityEditor.AddField')}
</button>
</div>
@ -484,7 +491,7 @@ const EntityEditor: React.FC = () => {
className="p-2 text-slate-600 hover:text-red-600 hover:bg-red-50 rounded transition-colors"
title={translate('::App.DeveloperKit.EntityEditor.RemoveField')}
>
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
</button>
</div>
</div>
@ -494,7 +501,7 @@ const EntityEditor: React.FC = () => {
{fields.length === 0 && (
<div className="text-center py-8 text-slate-500">
<Database className="w-12 h-12 mx-auto mb-2 text-slate-300" />
<FaDatabase className="w-12 h-12 mx-auto mb-2 text-slate-300" />
<p>{translate('::App.DeveloperKit.EntityEditor.NoFields')}</p>
<p className="text-sm">{translate('::App.DeveloperKit.EntityEditor.NoFieldsDescription')}</p>
</div>

View file

@ -2,19 +2,19 @@ import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { useEntities } from '../../contexts/EntityContext';
import {
Plus,
Search,
Edit,
Trash2,
Eye,
EyeOff,
Filter,
Calendar,
Database,
CheckCircle,
Table,
Zap
} from 'lucide-react';
FaPlus,
FaSearch,
FaEdit,
FaTrashAlt,
FaEye,
FaEyeSlash,
FaFilter,
FaCalendarAlt,
FaDatabase,
FaCheckCircle,
FaTable,
FaBolt
} from 'react-icons/fa';
import { ROUTES_ENUM } from '@/routes/route.constant';
import { useLocalization } from '@/utils/hooks/useLocalization';
@ -75,7 +75,7 @@ const EntityManager: React.FC = () => {
to={ROUTES_ENUM.protected.saas.developerKitEntitiesNew}
className="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"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
{translate('::App.DeveloperKit.Entity.NewEntity')}
</Link>
</div>
@ -89,7 +89,7 @@ const EntityManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.total}</p>
</div>
<div className="bg-blue-100 text-blue-600 p-3 rounded-lg">
<Database className="w-6 h-6" />
<FaDatabase className="w-6 h-6" />
</div>
</div>
</div>
@ -105,7 +105,7 @@ const EntityManager: React.FC = () => {
</p>
</div>
<div className="bg-green-100 text-green-600 p-3 rounded-lg">
<CheckCircle className="w-6 h-6" />
<FaCheckCircle className="w-6 h-6" />
</div>
</div>
</div>
@ -116,7 +116,7 @@ const EntityManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.migrationsPending}</p>
</div>
<div className="bg-purple-100 text-purple-600 p-3 rounded-lg">
<Zap className="w-6 h-6" />
<FaBolt className="w-6 h-6" />
</div>
</div>
</div>
@ -127,7 +127,7 @@ const EntityManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.endpointsApplied}</p>
</div>
<div className="bg-emerald-100 text-emerald-600 p-3 rounded-lg">
<Zap className="w-6 h-6" />
<FaBolt className="w-6 h-6" />
</div>
</div>
</div>
@ -137,7 +137,7 @@ const EntityManager: React.FC = () => {
<div className="bg-white rounded-lg border border-slate-200 p-6 mb-6 shadow-sm">
<div className="flex flex-col lg:flex-row gap-4">
<div className="flex-1 relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<input
type="text"
placeholder={translate('::App.DeveloperKit.Entity.SearchPlaceholder')}
@ -148,7 +148,7 @@ const EntityManager: React.FC = () => {
</div>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<Filter className="w-5 h-5 text-slate-500" />
<FaFilter className="w-5 h-5 text-slate-500" />
<select
value={filterActive}
onChange={(e) => setFilterActive(e.target.value as 'all' | 'active' | 'inactive')}
@ -174,7 +174,7 @@ const EntityManager: React.FC = () => {
<div className="flex-1">
<div className="flex items-center gap-3 mb-2">
<div className="bg-blue-100 text-blue-600 p-2 rounded-lg">
<Table className="w-5 h-5" />
<FaTable className="w-5 h-5" />
</div>
<div>
<h3 className="text-lg font-semibold text-slate-900">
@ -191,13 +191,13 @@ const EntityManager: React.FC = () => {
)}
<div className="flex items-center gap-4 text-xs text-slate-500 mb-3">
<div className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
<FaCalendarAlt className="w-3 h-3" />
<span>
{translate('::App.DeveloperKit.Entity.Updated')}: {entity.lastModificationTime ? new Date(entity.lastModificationTime).toLocaleDateString() : 'Never'}
</span>
</div>
<div className="flex items-center gap-1">
<Database className="w-3 h-3" />
<FaDatabase className="w-3 h-3" />
<span>{entity.fields.length} {translate('::App.DeveloperKit.Entity.Fields')}</span>
</div>
</div>
@ -270,12 +270,12 @@ const EntityManager: React.FC = () => {
>
{entity.isActive ? (
<>
<Eye className="w-3 h-3" />
<FaEye className="w-3 h-3" />
{translate('::App.DeveloperKit.Entity.Active')}
</>
) : (
<>
<EyeOff className="w-3 h-3" />
<FaEyeSlash className="w-3 h-3" />
{translate('::App.DeveloperKit.Entity.Inactive')}
</>
)}
@ -287,14 +287,14 @@ const EntityManager: React.FC = () => {
className="p-2 text-slate-600 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors"
title={translate('::App.DeveloperKit.Entity.Edit')}
>
<Edit className="w-4 h-4" />
<FaEdit className="w-4 h-4" />
</Link>
<button
onClick={() => handleDelete(entity.id, entity.displayName)}
className="p-2 text-slate-600 hover:text-red-600 hover:bg-red-50 rounded transition-colors"
title={translate('::App.DeveloperKit.Entity.Delete')}
>
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
</button>
</div>
</div>
@ -307,7 +307,7 @@ const EntityManager: React.FC = () => {
<div className="text-center py-12">
<div className="max-w-md mx-auto">
<div className="bg-slate-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
<Database className="w-8 h-8 text-slate-500" />
<FaDatabase className="w-8 h-8 text-slate-500" />
</div>
<h3 className="text-lg font-medium text-slate-900 mb-2">
{searchTerm || filterActive !== 'all' ? translate('::App.DeveloperKit.Entity.NoEntitiesFound') : translate('::App.DeveloperKit.Entity.NoEntitiesYet')}
@ -323,7 +323,7 @@ const EntityManager: React.FC = () => {
to={ROUTES_ENUM.protected.saas.developerKitEntitiesNew}
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"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
{translate('::App.DeveloperKit.Entity.CreateEntity')}
</Link>
)}

View file

@ -2,22 +2,22 @@ import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useEntities } from '../../contexts/EntityContext'
import {
Zap,
Search,
Filter,
Calendar,
Database,
Play,
CheckCircle,
AlertCircle,
Clock,
FileText,
Download,
Eye,
RefreshCw,
Trash2,
Plus,
} from 'lucide-react'
FaBolt,
FaSearch,
FaFilter,
FaCalendarAlt,
FaDatabase,
FaPlay,
FaCheckCircle,
FaRegBell,
FaRegClock,
FaRegFileAlt,
FaDownload,
FaEye,
FaSync,
FaTrashAlt,
FaPlus
} from 'react-icons/fa';
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -126,13 +126,13 @@ const MigrationManager: React.FC = () => {
const getStatusIcon = (status: string) => {
switch (status) {
case 'pending':
return Clock
return FaRegClock
case 'applied':
return CheckCircle
return FaCheckCircle
case 'failed':
return AlertCircle
return FaRegBell
default:
return Clock
return FaRegClock
}
}
@ -153,7 +153,7 @@ const MigrationManager: React.FC = () => {
{error && (
<div className="mb-6 bg-red-50 border border-red-200 rounded-lg p-4">
<div className="flex items-center gap-2 text-red-800">
<AlertCircle className="w-5 h-5" />
<FaRegBell className="w-5 h-5" />
<span className="font-medium">Error</span>
</div>
<p className="text-red-700 text-sm mt-1">{error}</p>
@ -169,12 +169,12 @@ const MigrationManager: React.FC = () => {
</div>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2 bg-blue-100 text-blue-700 px-3 py-1 rounded-full text-sm font-medium">
<Database className="w-4 h-4" />
<FaDatabase className="w-4 h-4" />
{translate('::App.DeveloperKit.Migration.SchemaManagement')}
</div>
{loading && (
<div className="flex items-center gap-2 bg-yellow-100 text-yellow-700 px-3 py-1 rounded-full text-sm font-medium">
<RefreshCw className="w-4 h-4 animate-spin" />
<FaSync className="w-4 h-4 animate-spin" />
{translate('::App.DeveloperKit.Migration.Loading')}
</div>
)}
@ -190,7 +190,7 @@ const MigrationManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.total}</p>
</div>
<div className="bg-blue-100 text-blue-600 p-3 rounded-lg">
<FileText className="w-6 h-6" />
<FaRegFileAlt className="w-6 h-6" />
</div>
</div>
</div>
@ -201,7 +201,7 @@ const MigrationManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.pending}</p>
</div>
<div className="bg-yellow-100 text-yellow-600 p-3 rounded-lg">
<Clock className="w-6 h-6" />
<FaRegClock className="w-6 h-6" />
</div>
</div>
</div>
@ -212,7 +212,7 @@ const MigrationManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.applied}</p>
</div>
<div className="bg-green-100 text-green-600 p-3 rounded-lg">
<CheckCircle className="w-6 h-6" />
<FaCheckCircle className="w-6 h-6" />
</div>
</div>
</div>
@ -223,7 +223,7 @@ const MigrationManager: React.FC = () => {
<p className="text-2xl font-bold text-slate-900 mt-1">{stats.failed}</p>
</div>
<div className="bg-red-100 text-red-600 p-3 rounded-lg">
<AlertCircle className="w-6 h-6" />
<FaRegBell className="w-6 h-6" />
</div>
</div>
</div>
@ -234,7 +234,7 @@ const MigrationManager: React.FC = () => {
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-6 mb-6">
<div className="flex items-start gap-4">
<div className="bg-yellow-100 rounded-lg p-2">
<Zap className="w-6 h-6 text-yellow-600" />
<FaBolt className="w-6 h-6 text-yellow-600" />
</div>
<div className="flex-1">
<h3 className="text-lg font-semibold text-slate-900 mb-2">
@ -271,7 +271,7 @@ const MigrationManager: React.FC = () => {
<div className="bg-white rounded-lg border border-slate-200 p-6 mb-6 shadow-sm">
<div className="flex flex-col lg:flex-row gap-4">
<div className="flex-1 relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-slate-400" />
<input
type="text"
placeholder={translate('::App.DeveloperKit.Migration.SearchPlaceholder')}
@ -282,7 +282,7 @@ const MigrationManager: React.FC = () => {
</div>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<Filter className="w-5 h-5 text-slate-500" />
<FaFilter className="w-5 h-5 text-slate-500" />
<select
value={filterStatus}
onChange={(e) =>
@ -315,7 +315,7 @@ const MigrationManager: React.FC = () => {
<div className="flex-1">
<div className="flex items-center gap-3 mb-2">
<div className="bg-blue-100 text-blue-600 p-2 rounded-lg">
<Database className="w-5 h-5" />
<FaDatabase className="w-5 h-5" />
</div>
<div>
<h3 className="text-lg font-semibold text-slate-900">
@ -332,14 +332,14 @@ const MigrationManager: React.FC = () => {
</div>
<div className="flex items-center gap-4 text-xs text-slate-500">
<div className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
<FaCalendarAlt className="w-3 h-3" />
<span>
{translate('::App.DeveloperKit.Migration.Created')} {new Date(migration.creationTime).toLocaleDateString()}
</span>
</div>
{migration.appliedAt && (
<div className="flex items-center gap-1">
<CheckCircle className="w-3 h-3" />
<FaCheckCircle className="w-3 h-3" />
<span>
{translate('::App.DeveloperKit.Migration.AppliedLabel')} {new Date(migration.appliedAt).toLocaleDateString()}
</span>
@ -364,7 +364,7 @@ const MigrationManager: React.FC = () => {
: 'text-orange-600 hover:text-orange-900 hover:bg-orange-50'
}`}
>
<Eye className="w-4 h-4" />
<FaEye className="w-4 h-4" />
{translate('::App.DeveloperKit.Migration.ViewSQL')}
{!migration.sqlScript && (
<span className="ml-1 text-xs text-orange-500">({translate('::App.DeveloperKit.Migration.NoSQL')})</span>
@ -379,7 +379,7 @@ const MigrationManager: React.FC = () => {
: 'text-slate-400 cursor-not-allowed'
}`}
>
<Download className="w-4 h-4" />
<FaDownload className="w-4 h-4" />
{translate('::App.DeveloperKit.Migration.Download')}
</button>
</div>
@ -393,12 +393,12 @@ const MigrationManager: React.FC = () => {
>
{applyingMigration === migration.id ? (
<>
<RefreshCw className="w-4 h-4 animate-spin" />
<FaSync className="w-4 h-4 animate-spin" />
{translate('::App.DeveloperKit.Migration.Applying')}
</>
) : (
<>
<Play className="w-4 h-4" />
<FaPlay className="w-4 h-4" />
{translate('::App.DeveloperKit.Migration.ApplyMigration')}
</>
)}
@ -409,9 +409,9 @@ const MigrationManager: React.FC = () => {
className="flex items-center gap-2 bg-red-600 text-white px-3 py-2 rounded-lg hover:bg-red-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{deletingMigration === migration.id ? (
<RefreshCw className="w-4 h-4 animate-spin" />
<FaSync className="w-4 h-4 animate-spin" />
) : (
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
)}
</button>
</>
@ -424,12 +424,12 @@ const MigrationManager: React.FC = () => {
>
{generatingEndpoints === migration.entityId ? (
<>
<RefreshCw className="w-4 h-4 animate-spin" />
<FaSync className="w-4 h-4 animate-spin" />
{translate('::App.DeveloperKit.Migration.Generating')}
</>
) : (
<>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
{translate('::App.DeveloperKit.Migration.GenerateCrudEndpoints')}
</>
)}
@ -451,7 +451,7 @@ const MigrationManager: React.FC = () => {
) : (
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
<div className="flex items-center gap-2 text-yellow-800">
<AlertCircle className="w-5 h-5" />
<FaRegBell className="w-5 h-5" />
<span className="font-medium">{translate('::App.DeveloperKit.Migration.NoSQLScript')}</span>
</div>
<p className="text-yellow-700 text-sm mt-1">
@ -467,7 +467,7 @@ const MigrationManager: React.FC = () => {
<div className="mt-4 pt-4 border-t border-slate-200">
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
<div className="flex items-center gap-2 text-red-800 mb-2">
<AlertCircle className="w-5 h-5" />
<FaRegBell className="w-5 h-5" />
<span className="font-medium">{translate('::App.DeveloperKit.Migration.MigrationFailed')}</span>
</div>
<p className="text-red-700 text-sm">{migration.errorMessage}</p>
@ -483,7 +483,7 @@ const MigrationManager: React.FC = () => {
<div className="text-center py-12">
<div className="max-w-md mx-auto">
<div className="bg-slate-100 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
<Zap className="w-8 h-8 text-slate-500" />
<FaBolt className="w-8 h-8 text-slate-500" />
</div>
<h3 className="text-lg font-medium text-slate-900 mb-2">
{searchTerm || filterStatus !== 'all' ? translate('::App.DeveloperKit.Migration.NoMigrationsFound') : translate('::App.DeveloperKit.Migration.NoMigrationsYet')}

View file

@ -1,5 +1,10 @@
import React, { useCallback, useState } from 'react'
import { Upload, File, X, AlertCircle } from 'lucide-react'
import {
FaUpload,
FaFile,
FaTimes,
FaRegCircle
} from 'react-icons/fa';
interface FileUploadAreaProps {
onFileUpload: (file: File) => void
@ -112,7 +117,7 @@ export const FileUploadArea: React.FC<FileUploadAreaProps> = ({
/>
<div className="text-center">
<Upload
<FaUpload
className={`mx-auto h-3 w-3 ${dragActive ? 'text-blue-500' : 'text-slate-400'}`}
/>
<div className="text-lg font-medium text-slate-700 mb-2">
@ -128,7 +133,7 @@ export const FileUploadArea: React.FC<FileUploadAreaProps> = ({
<div className="border border-slate-200 rounded-lg p-4">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3 min-w-0 flex-1">
<File className="w-8 h-8 text-blue-500 flex-shrink-0" />
<FaFile className="w-8 h-8 text-blue-500 flex-shrink-0" />
<div className="min-w-0 flex-1">
<div className="font-medium text-slate-800 truncate">{selectedFile.name}</div>
<div className="text-sm text-slate-500">{formatFileSize(selectedFile.size)}</div>
@ -138,7 +143,7 @@ export const FileUploadArea: React.FC<FileUploadAreaProps> = ({
onClick={clearFile}
className="p-2 text-slate-400 hover:text-slate-600 hover:bg-slate-100 rounded-lg transition-colors"
>
<X className="w-4 h-4" />
<FaTimes className="w-4 h-4" />
</button>
</div>
</div>
@ -146,7 +151,7 @@ export const FileUploadArea: React.FC<FileUploadAreaProps> = ({
{error && (
<div className="flex items-center space-x-2 p-3 bg-red-50 border border-red-200 rounded-lg">
<AlertCircle className="w-5 h-5 text-red-500" />
<FaRegCircle className="w-5 h-5 text-red-500" />
<span className="text-red-700">{error}</span>
</div>
)}
@ -164,7 +169,7 @@ export const FileUploadArea: React.FC<FileUploadAreaProps> = ({
</>
) : (
<>
<Upload className="w-4 h-4" />
<FaUpload className="w-4 h-4" />
<span>Upload File</span>
</>
)}

View file

@ -1,16 +1,16 @@
import React, { useState, useEffect, useMemo } from 'react'
import {
Upload,
CheckCircle,
AlertCircle,
Clock,
RefreshCw,
Eye,
Trash2,
Download,
FileSpreadsheet,
FileText,
} from 'lucide-react'
FaUpload,
FaCheckCircle,
FaRegBell,
FaClock,
FaSync,
FaEye,
FaTrashAlt,
FaDownload,
FaFileExcel,
FaFileAlt
} from 'react-icons/fa';
import { FileUploadArea } from './FileUploadArea'
import { ImportPreview } from './ImportPreview'
import { ImportProgress } from './ImportProgress'
@ -168,14 +168,14 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
const getStatusIcon = (status: string) => {
switch (status) {
case 'uploaded':
return <CheckCircle className="w-5 h-5 text-green-500" />
return <FaCheckCircle className="w-5 h-5 text-green-500" />
case 'failed':
return <AlertCircle className="w-5 h-5 text-red-500" />
return <FaRegBell className="w-5 h-5 text-red-500" />
case 'processing':
case 'validating':
return <RefreshCw className="w-5 h-5 text-blue-500 animate-spin" />
return <FaSync className="w-5 h-5 text-blue-500 animate-spin" />
default:
return <Clock className="w-5 h-5 text-yellow-500" />
return <FaClock className="w-5 h-5 text-yellow-500" />
}
}
@ -233,9 +233,9 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
: 'text-slate-600 hover:text-slate-800 hover:bg-slate-50'
}`}
>
{tab === 'import' && <Upload className="w-4 h-4" />}
{tab === 'preview' && <Eye className="w-4 h-4" />}
{tab === 'history' && <Clock className="w-4 h-4" />}
{tab === 'import' && <FaUpload className="w-4 h-4" />}
{tab === 'preview' && <FaEye className="w-4 h-4" />}
{tab === 'history' && <FaClock className="w-4 h-4" />}
<span className="capitalize">{tab}</span>
</button>
))}
@ -251,7 +251,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
<div className="bg-white rounded-xl shadow-sm border border-slate-200">
<div className="px-3 py-3 border-b flex items-center justify-between">
<h3 className="text-xl font-semibold text-slate-800 flex items-center">
<Download className="w-4 h-4 mr-2" />
<FaDownload className="w-4 h-4 mr-2" />
Template Columns ({editableColumns.length})
</h3>
@ -262,7 +262,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
disabled={generating}
className="flex items-center gap-1.5 px-3 py-1.5 border border-green-200 rounded-md hover:border-green-300 hover:bg-green-50 transition-all duration-200 group disabled:opacity-50 disabled:cursor-not-allowed bg-white text-xs"
>
<FileSpreadsheet className="w-3.5 h-3.5 text-green-500 group-hover:scale-110 transition-transform" />
<FaFileExcel className="w-3.5 h-3.5 text-green-500 group-hover:scale-110 transition-transform" />
<span className="font-medium text-slate-700">Excel Template</span>
</button>
@ -271,7 +271,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
disabled={generating}
className="flex items-center gap-1.5 px-3 py-1.5 border border-blue-200 rounded-md hover:border-blue-300 hover:bg-blue-50 transition-all duration-200 group disabled:opacity-50 disabled:cursor-not-allowed bg-white text-xs"
>
<FileText className="w-3.5 h-3.5 text-blue-500 group-hover:scale-110 transition-transform" />
<FaFileAlt className="w-3.5 h-3.5 text-blue-500 group-hover:scale-110 transition-transform" />
<span className="font-medium text-slate-700">CSV Template</span>
</button>
</div>
@ -349,7 +349,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
<div className="lg:col-span-1">
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-4 h-full">
<h2 className="text-xl font-semibold text-slate-800 mb-4 flex items-center">
<Upload className="w-5 h-5 mr-2 text-green-500" />
<FaUpload className="w-5 h-5 mr-2 text-green-500" />
Upload Data
</h2>
<FileUploadArea
@ -387,7 +387,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
) : (
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-12">
<div className="text-center text-slate-500">
<Eye className="w-16 h-16 mx-auto mb-4 text-slate-300" />
<FaEye className="w-16 h-16 mx-auto mb-4 text-slate-300" />
<div className="text-xl font-medium mb-2">No Data to Preview</div>
<div>Upload a file to see the preview here</div>
</div>
@ -400,7 +400,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
<div className="bg-white rounded-xl shadow-sm border border-slate-200">
<div className="p-3 border-b border-slate-200">
<h2 className="text-xl font-semibold text-slate-800 flex items-center">
<Clock className="w-5 h-5 mr-2 text-indigo-500" />
<FaClock className="w-5 h-5 mr-2 text-indigo-500" />
Import History
</h2>
</div>
@ -458,7 +458,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
}`}
title="View execution details"
>
<Eye className="w-4 h-4" />
<FaEye className="w-4 h-4" />
</button>
<button
onClick={async () => {
@ -487,7 +487,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
className="p-2 rounded-lg transition-colors text-slate-400 hover:text-blue-500 hover:bg-blue-50"
title="Refresh execution details"
>
<RefreshCw className="w-4 h-4" />
<FaSync className="w-4 h-4" />
</button>
<button
onClick={async () => {
@ -509,7 +509,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
: 'Delete this import session'
}
>
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
</button>
</div>
</div>
@ -521,7 +521,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
<div className="p-3">
{loadingExecutes.has(session.id) ? (
<div className="flex items-center space-x-2 text-slate-500 py-2">
<RefreshCw className="w-4 h-4 animate-spin" />
<FaSync className="w-4 h-4 animate-spin" />
<span className="text-sm">Loading execution details...</span>
</div>
) : sessionExecutes[session.id] && sessionExecutes[session.id].length > 0 ? (
@ -561,16 +561,16 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
{/* Sağ: Status */}
<div className="flex items-center space-x-2 flex-shrink-0">
{execute.status === 'completed' && (
<CheckCircle className="w-4 h-4 text-green-500" />
<FaCheckCircle className="w-4 h-4 text-green-500" />
)}
{execute.status === 'processing' && (
<RefreshCw className="w-4 h-4 text-blue-500 animate-spin" />
<FaSync className="w-4 h-4 text-blue-500 animate-spin" />
)}
{execute.status === 'validating' && (
<Clock className="w-4 h-4 text-yellow-500" />
<FaClock className="w-4 h-4 text-yellow-500" />
)}
{execute.status === 'failed' && (
<AlertCircle className="w-4 h-4 text-red-500" />
<FaRegBell className="w-4 h-4 text-red-500" />
)}
<div
className={`text-xs font-medium ${
@ -605,7 +605,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
{importHistory.length === 0 && (
<div className="p-12 text-center text-slate-500">
<Clock className="w-12 h-12 mx-auto mb-4 text-slate-300" />
<FaClock className="w-12 h-12 mx-auto mb-4 text-slate-300" />
<div className="text-lg font-medium mb-2">No import history</div>
<div>Your import history will appear here</div>
</div>

View file

@ -1,5 +1,11 @@
import React, { useState, useEffect, useRef } from 'react'
import { CheckCircle, AlertTriangle, Eye, Play, X } from 'lucide-react'
import {
FaCheckCircle,
FaExclamationTriangle,
FaEye,
FaPlay,
FaTimes
} from 'react-icons/fa';
import { ListFormImportDto } from '@/proxy/imports/models'
import { GridDto } from '@/proxy/form/models'
import { ImportService } from '@/services/import.service'
@ -149,7 +155,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-center gap-4">
{/* Başlık kısmı - Üstte mobile, solda desktop */}
<div className="flex items-center order-1 lg:order-none">
<Eye className="w-5 h-5 mr-2 text-blue-500" />
<FaEye className="w-5 h-5 mr-2 text-blue-500" />
<h3 className="text-xl font-semibold text-slate-800">Import Preview</h3>
</div>
@ -236,7 +242,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
) : previewData && previewData.headers && previewData.headers.length === 0 ? (
<div className="p-6 border-b border-slate-200">
<div className="text-center py-8">
<AlertTriangle className="w-12 h-12 mx-auto mb-4 text-yellow-500" />
<FaExclamationTriangle className="w-12 h-12 mx-auto mb-4 text-yellow-500" />
<h4 className="font-semibold text-slate-800 mb-2">No Data Found</h4>
<p className="text-slate-600">
Unable to parse data from the uploaded file. Please check the file format and content.
@ -259,7 +265,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
{showSuccessMessage && lastExecutionResult && (
<div className="mb-4 p-4 bg-green-50 border border-green-200 rounded-lg">
<div className="flex items-center space-x-2 text-green-700">
<CheckCircle className="w-5 h-5" />
<FaCheckCircle className="w-5 h-5" />
<span className="font-medium">
Import completed successfully! {lastExecutionResult.successCount} of{' '}
{lastExecutionResult.selectedCount} rows were imported.
@ -272,21 +278,21 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
<div className="flex items-center space-x-4">
{selectedRows.length === 0 && (previewData?.rows?.length || 0) > 0 && (
<div className="flex items-center space-x-2 text-orange-600">
<AlertTriangle className="w-5 h-5" />
<FaExclamationTriangle className="w-5 h-5" />
<span className="font-medium">Please select rows to import using checkboxes</span>
</div>
)}
{selectedRows.length > 0 && (
<div className="flex items-center space-x-2 text-blue-600">
<CheckCircle className="w-5 h-5" />
<FaCheckCircle className="w-5 h-5" />
<span className="font-medium">{selectedRows.length} rows selected for import</span>
</div>
)}
{(previewData?.rows?.length || 0) === 0 && (
<div className="flex items-center space-x-2 text-red-600">
<AlertTriangle className="w-5 h-5" />
<FaExclamationTriangle className="w-5 h-5" />
<span className="font-medium">No data available for import</span>
</div>
)}
@ -294,7 +300,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
<div className="flex space-x-3">
<button className="px-4 py-2 text-slate-600 hover:text-slate-800 hover:bg-slate-100 rounded-lg transition-colors flex items-center space-x-2">
<X className="w-4 h-4" />
<FaTimes className="w-4 h-4" />
<span>Cancel</span>
</button>
@ -310,7 +316,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
</>
) : (
<>
<Play className="w-4 h-4" />
<FaPlay className="w-4 h-4" />
<span>Execute Import</span>
</>
)}

View file

@ -1,5 +1,5 @@
import React from 'react'
import { RefreshCw, Upload, CheckCircle } from 'lucide-react'
import { FaSync, FaUpload, FaCheckCircle } from 'react-icons/fa';
import { ListFormImportDto } from '@/proxy/imports/models'
interface ImportProgressProps {
@ -44,14 +44,14 @@ export const ImportProgress: React.FC<ImportProgressProps> = ({ session }) => {
const getStatusIcon = () => {
switch (session.status) {
case 'uploading':
return <Upload className="w-6 h-6 text-blue-500" />
return <FaUpload className="w-6 h-6 text-blue-500" />
case 'validating':
case 'processing':
return <RefreshCw className="w-6 h-6 text-blue-500 animate-spin" />
return <FaSync className="w-6 h-6 text-blue-500 animate-spin" />
case 'uploaded':
return <CheckCircle className="w-6 h-6 text-green-500" />
return <FaCheckCircle className="w-6 h-6 text-green-500" />
default:
return <RefreshCw className="w-6 h-6 text-blue-500 animate-spin" />
return <FaSync className="w-6 h-6 text-blue-500 animate-spin" />
}
}

View file

@ -1,5 +1,5 @@
import React from 'react'
import { LayoutDashboard, Database, Zap, Server, Puzzle } from 'lucide-react'
import { FaTachometerAlt, FaDatabase, FaBolt, FaServer, FaPuzzlePiece } from 'react-icons/fa';
import { useLocalization } from '@/utils/hooks/useLocalization'
import { useLocation, useNavigate } from 'react-router-dom'
import { ROUTES_ENUM } from '@/routes/route.constant'
@ -18,31 +18,31 @@ const DeveloperLayout: React.FC<DeveloperLayoutProps> = ({ children }) => {
{
id: 'dashboard',
label: translate('::App.DeveloperKit.Dashboard'),
icon: LayoutDashboard,
icon: FaTachometerAlt,
path: ROUTES_ENUM.protected.saas.developerKit,
},
{
id: 'entities',
label: translate('::App.DeveloperKit.Entity'),
icon: Database,
icon: FaDatabase,
path: ROUTES_ENUM.protected.saas.developerKitEntities,
},
{
id: 'migrations',
label: translate('::App.DeveloperKit.Migrations'),
icon: Zap,
icon: FaBolt,
path: ROUTES_ENUM.protected.saas.developerKitMigrations,
},
{
id: 'endpoints',
label: translate('::App.DeveloperKit.Endpoints'),
icon: Server,
icon: FaServer,
path: ROUTES_ENUM.protected.saas.developerKitEndpoints,
},
{
id: 'components',
label: translate('::App.DeveloperKit.Components'),
icon: Puzzle,
icon: FaPuzzlePiece,
path: ROUTES_ENUM.protected.saas.developerKitComponents,
},
]

View file

@ -2,22 +2,23 @@ import View from '@/views/Views'
import React, { useEffect, useState } from 'react'
import { useLocation, Link } from 'react-router-dom'
import {
Menu,
X,
Home,
Info,
Package,
Briefcase,
BookOpen,
Phone,
Facebook,
Twitter,
Linkedin,
Instagram,
MapPin,
Mail,
PlayCircle,
} from 'lucide-react'
FaBars,
FaTimes,
FaHome,
FaInfoCircle,
FaVectorSquare,
FaBriefcase,
FaBook,
FaPhone,
FaFacebook,
FaTwitter,
FaLinkedin,
FaInstagram,
FaMapPin,
FaEnvelope,
FaPlayCircle,
FaBookOpen
} from 'react-icons/fa';
import Logo from '@/views/public/Logo'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -65,43 +66,43 @@ const PublicLayout = () => {
resourceKey: 'Public.nav.home',
name: translate('::Public.nav.home'),
path: ROUTES_ENUM.public.home,
icon: Home,
icon: FaHome,
},
{
resourceKey: 'Public.nav.about',
name: translate('::Public.nav.about'),
path: ROUTES_ENUM.public.about,
icon: Info,
icon: FaInfoCircle,
},
{
resourceKey: 'Public.nav.services',
name: translate('::Public.nav.services'),
path: ROUTES_ENUM.public.services,
icon: Briefcase,
icon: FaBriefcase,
},
{
resourceKey: 'Public.nav.products',
name: translate('::Public.nav.products'),
path: ROUTES_ENUM.public.products,
icon: Package,
icon: FaVectorSquare,
},
{
resourceKey: 'Public.nav.blog',
name: translate('::Public.nav.blog'),
path: ROUTES_ENUM.public.blog,
icon: BookOpen,
icon: FaBookOpen,
},
{
resourceKey: 'Public.nav.demo',
name: translate('::Public.nav.demo'),
action: () => setIsDemoOpen(true),
icon: PlayCircle,
icon: FaPlayCircle,
},
{
resourceKey: 'Public.nav.contact',
name: translate('::Public.nav.contact'),
path: ROUTES_ENUM.public.contact,
icon: Phone,
icon: FaPhone,
},
{
resourceKey: 'Public.nav.giris',
@ -162,7 +163,7 @@ const PublicLayout = () => {
{/* Mobile Menu Button */}
<button className="md:hidden text-white" onClick={toggleMenu} aria-label="Toggle menu">
{isOpen ? <X size={24} /> : <Menu size={24} />}
{isOpen ? <FaTimes size={24} /> : <FaBars size={24} />}
</button>
</div>
@ -222,7 +223,7 @@ const PublicLayout = () => {
rel="noopener noreferrer"
className="text-gray-400 hover:text-white transition-colors"
>
<Facebook size={20} />
<FaFacebook size={20} />
</a>
<a
href="https://twitter.com/sozsoft"
@ -230,7 +231,7 @@ const PublicLayout = () => {
rel="noopener noreferrer"
className="text-gray-400 hover:text-white transition-colors"
>
<Twitter size={20} />
<FaTwitter size={20} />
</a>
<a
href="https://linkedin.com/sozsoft"
@ -238,7 +239,7 @@ const PublicLayout = () => {
rel="noopener noreferrer"
className="text-gray-400 hover:text-white transition-colors"
>
<Linkedin size={20} />
<FaLinkedin size={20} />
</a>
<a
href="https://instagram.com/sozsoft"
@ -246,7 +247,7 @@ const PublicLayout = () => {
rel="noopener noreferrer"
className="text-gray-400 hover:text-white transition-colors"
>
<Instagram size={20} />
<FaInstagram size={20} />
</a>
</div>
</div>
@ -372,11 +373,11 @@ const PublicLayout = () => {
</h3>
<ul className="space-y-3">
<li className="flex items-start space-x-3">
<MapPin size={20} className="text-gray-400 mt-1 flex-shrink-0" />
<FaMapPin size={20} className="text-gray-400 mt-1 flex-shrink-0" />
<span className="text-gray-400">{translate('::Public.footer.address')}</span>
</li>
<li className="flex items-center space-x-3">
<Phone size={20} className="text-gray-400 flex-shrink-0" />
<FaPhone size={20} className="text-gray-400 flex-shrink-0" />
<a
href="tel:+905447697638"
className="text-gray-400 hover:text-white transition-colors"
@ -385,7 +386,7 @@ const PublicLayout = () => {
</a>
</li>
<li className="flex items-center space-x-3">
<Mail size={20} className="text-gray-400 flex-shrink-0" />
<FaEnvelope size={20} className="text-gray-400 flex-shrink-0" />
<a
href="mailto:destek@sozsoft.com"
className="text-gray-400 hover:text-white transition-colors"

View file

@ -1,5 +1,5 @@
import React from 'react'
import { Calendar, Clock, Minus, Plus, ShoppingCart } from 'lucide-react'
import { FaCalendar, FaClock, FaMinus, FaPlus, FaShoppingCart } from 'react-icons/fa';
import { BillingCycle } from '@/proxy/order/models'
import { CartState } from '@/utils/cartUtils'
import { useScroll } from '@/contexts/ScrollContext'
@ -41,7 +41,7 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
<div className="flex flex-col sm:flex-row items-center justify-between gap-4">
<div className="flex items-center space-x-6">
<div className="flex items-center space-x-2 rounded-lg">
<Calendar className="w-5 h-5 text-gray-600" />
<FaCalendar className="w-5 h-5 text-gray-600" />
<span className="font-medium text-gray-900">Faturalama Döngüsü:</span>
</div>
@ -84,7 +84,7 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
<div className="flex items-center space-x-6">
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-2">
<Clock className="w-5 h-5 text-gray-600" />
<FaClock className="w-5 h-5 text-gray-600" />
<span className="font-medium text-gray-900">Periyod:</span>
</div>
@ -99,7 +99,7 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
disabled={globalPeriod <= 1 || hasCartItems}
title={hasCartItems ? 'Sepette ürün varken periyod değiştirilemez' : undefined}
>
<Minus className="w-4 h-4" />
<FaMinus className="w-4 h-4" />
</button>
<div className="flex items-center space-x-2 bg-gray-50 px-4 py-2 rounded-lg">
@ -119,7 +119,7 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
disabled={hasCartItems}
title={hasCartItems ? 'Sepette ürün varken periyod değiştirilemez' : undefined}
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
</button>
</div>
</div>
@ -128,7 +128,7 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
onClick={onCartClick}
className="relative flex items-center gap-2 p-2 bg-green-600 text-white hover:bg-green-700 transition-colors rounded-lg shadow-md"
>
<ShoppingCart className="w-5 h-5" />
<FaShoppingCart className="w-5 h-5" />
<span className="font-medium text-sm">{translate('::Public.nav.basket')}</span>
{cartItemsCount > 0 && (

View file

@ -1,5 +1,11 @@
import React from 'react';
import { X, Minus, Plus, ShoppingBag, Trash2 } from 'lucide-react';
import {
FaTimes,
FaMinus,
FaPlus,
FaShoppingBag,
FaTrash
} from 'react-icons/fa';
import { BillingCycle, BasketItem } from '@/proxy/order/models';
interface CartState {
@ -60,14 +66,14 @@ export const Cart: React.FC<CartProps> = ({
className="p-2 text-red-500 hover:bg-red-50 rounded-lg transition-colors"
title="Sepeti Temizle"
>
<Trash2 className="w-5 h-5" />
<FaTrash className="w-5 h-5" />
</button>
)}
<button
onClick={onClose}
className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
>
<X className="w-5 h-5" />
<FaTimes className="w-5 h-5" />
</button>
</div>
</div>
@ -75,7 +81,7 @@ export const Cart: React.FC<CartProps> = ({
<div className="flex-1 overflow-y-auto p-6">
{cartState.items.length === 0 ? (
<div className="flex flex-col items-center justify-center h-full text-gray-500">
<ShoppingBag className="w-16 h-16 mb-4" />
<FaShoppingBag className="w-16 h-16 mb-4" />
<p className="text-lg font-medium">Sepetiniz boş</p>
<p className="text-sm">Ürün eklemek için katalogdan seçim yapın</p>
</div>
@ -91,7 +97,7 @@ export const Cart: React.FC<CartProps> = ({
onClick={() => removeItem(item.product.id)}
className="text-red-500 hover:text-red-700 ml-2"
>
<X className="w-4 h-4" />
<FaTimes className="w-4 h-4" />
</button>
</div>
@ -115,14 +121,14 @@ export const Cart: React.FC<CartProps> = ({
onClick={() => updateQuantity(item.product.id, item.quantity - 1)}
className="p-1 rounded border border-gray-300 hover:bg-gray-50"
>
<Minus className="w-3 h-3" />
<FaMinus className="w-3 h-3" />
</button>
<span className="w-8 text-center text-sm">{item.quantity}</span>
<button
onClick={() => updateQuantity(item.product.id, item.quantity + 1)}
className="p-1 rounded border border-gray-300 hover:bg-gray-50"
>
<Plus className="w-3 h-3" />
<FaPlus className="w-3 h-3" />
</button>
</div>
)}

View file

@ -1,5 +1,8 @@
import React from 'react'
import { CheckCircle, Download, ArrowLeft } from 'lucide-react'
import {
FaCheckCircle,
FaArrowLeft
} from 'react-icons/fa';
import { useNavigate } from 'react-router-dom'
import { ROUTES_ENUM } from '@/routes/route.constant'
@ -15,7 +18,7 @@ export const OrderSuccess: React.FC<OrderSuccessProps> = ({ orderId, onBackToSho
<div className="max-w-2xl mx-auto text-center">
<div className="bg-white rounded-xl shadow-lg border border-gray-200 p-8">
<div className="mb-6">
<CheckCircle className="w-16 h-16 text-green-500 mx-auto mb-4" />
<FaCheckCircle className="w-16 h-16 text-green-500 mx-auto mb-4" />
<h2 className="text-2xl font-bold text-gray-900 mb-2">Siparişiniz Başarıyla Alındı!</h2>
<p className="text-gray-600">
Sipariş numaranız: <span className="font-semibold text-blue-600">#{orderId}</span>
@ -36,7 +39,7 @@ export const OrderSuccess: React.FC<OrderSuccessProps> = ({ orderId, onBackToSho
onClick={() => navigate(ROUTES_ENUM.public.home)}
className="flex items-center justify-center px-6 py-3 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
>
<ArrowLeft className="w-4 h-4 mr-2" />
<FaArrowLeft className="w-4 h-4 mr-2" />
Ana Sayfa'ya Dön
</button>
</div>

View file

@ -1,19 +1,19 @@
import React, { useEffect, useState } from 'react'
import {
CreditCard,
Lock,
ArrowLeft,
User,
Building,
Mail,
Phone,
MapPin,
Map,
Globe,
Banknote,
BadgeDollarSign,
UserPlus,
} from 'lucide-react'
FaCreditCard,
FaLock,
FaArrowLeft,
FaUser,
FaBuilding,
FaMailBulk,
FaPhone,
FaMapMarkerAlt,
FaMap,
FaGlobe,
FaMoneyBillWave,
FaDollarSign,
FaUserPlus
} from 'react-icons/fa';
import {
BillingCycle,
BasketItem,
@ -125,42 +125,42 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({
{tenant && (
<>
<h2 className="text-lg font-semibold mb-4 flex items-center">
<User className="w-5 h-5 text-green-600 mr-2" /> Müşteri Bilgileri
<FaUser className="w-5 h-5 text-green-600 mr-2" /> Müşteri Bilgileri
</h2>
<div className="pt-4 border-t border-gray-200">
<div className="grid grid-cols-1 gap-y-3 text-sm text-gray-700">
<div className="flex items-center gap-2">
<User className="w-4 h-4 text-gray-500" />
<FaUser className="w-4 h-4 text-gray-500" />
<span className="font-medium">Kurum Kodu:</span>
<span>{tenant.name}</span>
</div>
<div className="flex items-center gap-2">
<User className="w-4 h-4 text-gray-500" />
<FaUser className="w-4 h-4 text-gray-500" />
<span className="font-medium">Kurucu:</span>
<span>{tenant.founder}</span>
</div>
<div className="flex items-center gap-2">
<Building className="w-4 h-4 text-gray-500" />
<FaBuilding className="w-4 h-4 text-gray-500" />
<span className="font-medium">Şirket:</span>
<span>{tenant.institutionName}</span>
</div>
<div className="flex items-center gap-2">
<Mail className="w-4 h-4 text-gray-500" />
<FaMailBulk className="w-4 h-4 text-gray-500" />
<span className="font-medium">E-posta:</span>
<span>{tenant.email}</span>
</div>
<div className="flex items-center gap-2">
<Phone className="w-4 h-4 text-gray-500" />
<FaPhone className="w-4 h-4 text-gray-500" />
<span className="font-medium">Telefon:</span>
<span>{tenant.phone}</span>
</div>
<div className="flex items-start gap-2">
<MapPin className="w-4 h-4 text-gray-500 mt-0.5" />
<FaMapMarkerAlt className="w-4 h-4 text-gray-500 mt-0.5" />
<div>
<span className="font-medium">Adres:</span>
<div>{tenant.address}</div>
@ -168,44 +168,44 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({
</div>
<div className="flex items-center gap-2">
<Globe className="w-4 h-4 text-gray-500" />
<FaGlobe className="w-4 h-4 text-gray-500" />
<span className="font-medium">Ülke:</span>
<span>{tenant.country}</span>
</div>
<div className="flex items-center gap-2">
<Globe className="w-4 h-4 text-gray-500" />
<FaGlobe className="w-4 h-4 text-gray-500" />
<span className="font-medium">Şehir:</span>
<span>{tenant.city}</span>
</div>
<div className="flex items-center gap-2">
<Map className="w-4 h-4 text-gray-500" />
<FaMap className="w-4 h-4 text-gray-500" />
<span className="font-medium">İlçe:</span>
<span>{tenant.district}</span>
</div>
<div className="flex items-center gap-2">
<MapPin className="w-4 h-4 text-gray-500" />
<FaMapMarkerAlt className="w-4 h-4 text-gray-500" />
<span className="font-medium">Posta Kodu:</span>
<span>{tenant.postalCode}</span>
</div>
<div className="flex items-center gap-2">
<Banknote className="w-4 h-4 text-gray-500" />
<FaMoneyBillWave className="w-4 h-4 text-gray-500" />
<span className="font-medium">Vergi Dairesi:</span>
<span>{tenant.taxOffice}</span>
</div>
<div className="flex items-center gap-2">
<BadgeDollarSign className="w-4 h-4 text-gray-500" />
<FaDollarSign className="w-4 h-4 text-gray-500" />
<span className="font-medium">Vergi No:</span>
<span>{tenant.vknTckn}</span>
</div>
{tenant.reference && (
<div className="flex items-center gap-2">
<UserPlus className="w-4 h-4 text-gray-500" />
<FaUserPlus className="w-4 h-4 text-gray-500" />
<span className="font-medium">Referans:</span>
<span>{tenant.reference}</span>
</div>
@ -221,7 +221,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({
{/* 1. Sütun: Ödeme Yöntemi */}
<div className="bg-white rounded-xl shadow border p-6">
<h2 className="text-lg font-semibold mb-4 flex items-center">
<Lock className="w-5 h-5 text-green-600 mr-2" /> Ödeme Yöntemi
<FaLock className="w-5 h-5 text-green-600 mr-2" /> Ödeme Yöntemi
</h2>
<div className="space-y-2">
{paymentMethods.map((method) => (
@ -401,14 +401,14 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({
onClick={onBack}
className="flex items-center px-6 py-3 border border-gray-300 text-gray-700 rounded-lg"
>
<ArrowLeft className="w-4 h-4 mr-2" />
<FaArrowLeft className="w-4 h-4 mr-2" />
Geri
</button>
<button
type="submit"
className="flex items-center justify-center px-6 py-3 bg-green-600 text-white rounded-lg"
>
<CreditCard className="w-5 h-5 mr-2" />
<FaCreditCard className="w-5 h-5 mr-2" />
{selectedPaymentMethod === 'bank-transfer' ? 'Siparişi Tamamla' : 'Ödeme Yap'}
</button>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Plus, Minus } from 'lucide-react';
import { FaPlus, FaMinus } from 'react-icons/fa';
import { BillingCycle, Product, ProductDto } from '@/proxy/order/models';
import { CartState } from '@/utils/cartUtils';
@ -115,14 +115,14 @@ export const ProductCard: React.FC<ProductCardProps> = ({
onClick={() => setQuantity(Math.max(1, quantity - 1))}
className="p-1 rounded-md border border-gray-300 hover:bg-gray-50 transition-colors"
>
<Minus className="w-4 h-4" />
<FaMinus className="w-4 h-4" />
</button>
<span className="w-12 text-center font-medium">{quantity}</span>
<button
onClick={() => setQuantity(quantity + 1)}
className="p-1 rounded-md border border-gray-300 hover:bg-gray-50 transition-colors"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
</button>
</div>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState, useMemo, useEffect } from 'react'
import { Filter, Search } from 'lucide-react'
import { FaFilter, FaSearch } from 'react-icons/fa';
import { ProductCard } from './ProductCard'
import { addItemToCart, CartState } from '@/utils/cartUtils'
import { BillingCycle, ProductDto } from '@/proxy/order/models'
@ -86,7 +86,7 @@ export const ProductCatalog: React.FC<ProductCatalogProps> = ({
<aside className="lg:w-64 flex-shrink-0">
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-6 sticky top-40">
<div className="flex items-center space-x-2 mb-4">
<Filter className="w-5 h-5 text-gray-600" />
<FaFilter className="w-5 h-5 text-gray-600" />
<h3 className="font-semibold text-gray-900">Kategoriler</h3>
</div>
<div className="space-y-2">
@ -117,11 +117,11 @@ export const ProductCatalog: React.FC<ProductCatalogProps> = ({
{/* Search input moved here */}
<div className="mt-6">
<div className="flex items-center space-x-2 mb-3">
<Search className="w-5 h-5 text-gray-600" />
<FaSearch className="w-5 h-5 text-gray-600" />
<h3 className="font-semibold text-gray-900">Arama</h3>
</div>
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" />
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" />
<input
type="text"
placeholder="Ürün ara..."
@ -154,7 +154,7 @@ export const ProductCatalog: React.FC<ProductCatalogProps> = ({
{filteredProducts.length === 0 && (
<div className="text-center py-12">
<div className="text-gray-400 mb-2">
<Filter className="w-12 h-12 mx-auto" />
<FaFilter className="w-12 h-12 mx-auto" />
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2">Ürün bulunamadı</h3>
<p className="text-gray-600">Arama kriterlerinizi değiştirmeyi deneyin.</p>

View file

@ -1,20 +1,20 @@
import { getTenantByNameDetail } from '@/services/tenant.service'
import { CustomTenantDto } from '@/proxy/config/models'
import {
ArrowLeft,
ArrowRight,
BadgeDollarSign,
Banknote,
Building,
Globe,
Mail,
Map,
MapPin,
Phone,
Search,
User,
UserPlus,
} from 'lucide-react'
FaArrowLeft,
FaArrowRight,
FaDollarSign,
FaMoneyBillWave,
FaBuilding,
FaGlobe,
FaEnvelope,
FaMap,
FaMapPin,
FaPhone,
FaSearch,
FaUser,
FaUserPlus,
} from 'react-icons/fa'
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
@ -73,7 +73,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div className="w-full lg:w-1/3 bg-white rounded-xl shadow-lg border border-gray-200 p-6">
<div className="mb-6">
<h2 className="text-lg font-semibold mb-4 flex items-center">
<User className="w-5 h-5 text-green-600 mr-2" /> Müşteri Bilgileri
<FaUser className="w-5 h-5 text-green-600 mr-2" /> Müşteri Bilgileri
</h2>
</div>
@ -114,7 +114,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<label className="block text-sm font-medium text-gray-700 mb-2">Kurum Kodu *</label>
<div className="relative flex flex-col sm:flex-row sm:items-stretch">
<div className="relative w-full">
<Building className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -136,7 +136,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
onClick={getTenantInfo}
className="flex items-center justify-center gap-2 px-4 py-3 bg-blue-600 text-white rounded-lg sm:rounded-r-lg sm:rounded-l-none hover:bg-blue-700 transition-colors min-w-[148px]"
>
<Search className="w-4 h-4" />
<FaSearch className="w-4 h-4" />
Kurumu Bul
</button>
</div>
@ -144,31 +144,31 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
{formData.institutionName && (
<div className="grid grid-cols-1 gap-y-3 text-sm text-gray-700 p-3">
<div className="flex items-center gap-2">
<User className="w-4 h-4 text-gray-500" />
<FaUser className="w-4 h-4 text-gray-500" />
<span className="font-medium">Kurucu:</span>
<span>{formData.founder}</span>
</div>
<div className="flex items-center gap-2">
<Building className="w-4 h-4 text-gray-500" />
<FaBuilding className="w-4 h-4 text-gray-500" />
<span className="font-medium">Şirket:</span>
<span>{formData.institutionName}</span>
</div>
<div className="flex items-center gap-2">
<Mail className="w-4 h-4 text-gray-500" />
<FaEnvelope className="w-4 h-4 text-gray-500" />
<span className="font-medium">E-posta:</span>
<span>{formData.email}</span>
</div>
<div className="flex items-center gap-2">
<Phone className="w-4 h-4 text-gray-500" />
<FaPhone className="w-4 h-4 text-gray-500" />
<span className="font-medium">Mobile:</span>
<span>{formData.mobile}</span>
</div>
<div className="flex items-start gap-2">
<MapPin className="w-4 h-4 text-gray-500 mt-0.5" />
<FaMapPin className="w-4 h-4 text-gray-500 mt-0.5" />
<div>
<span className="font-medium">Adres:</span>
<div>{formData.address}</div>
@ -176,44 +176,44 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
</div>
<div className="flex items-center gap-2">
<Globe className="w-4 h-4 text-gray-500" />
<FaGlobe className="w-4 h-4 text-gray-500" />
<span className="font-medium">Ülke:</span>
<span>{formData.country}</span>
</div>
<div className="flex items-center gap-2">
<Globe className="w-4 h-4 text-gray-500" />
<FaGlobe className="w-4 h-4 text-gray-500" />
<span className="font-medium">Şehir:</span>
<span>{formData.city}</span>
</div>
<div className="flex items-center gap-2">
<Map className="w-4 h-4 text-gray-500" />
<FaMap className="w-4 h-4 text-gray-500" />
<span className="font-medium">İlçe:</span>
<span>{formData.district}</span>
</div>
<div className="flex items-center gap-2">
<MapPin className="w-4 h-4 text-gray-500" />
<FaMapPin className="w-4 h-4 text-gray-500" />
<span className="font-medium">Posta Kodu:</span>
<span>{formData.postalCode}</span>
</div>
<div className="flex items-center gap-2">
<Banknote className="w-4 h-4 text-gray-500" />
<FaMoneyBillWave className="w-4 h-4 text-gray-500" />
<span className="font-medium">Vergi Dairesi:</span>
<span>{formData.taxOffice}</span>
</div>
<div className="flex items-center gap-2">
<BadgeDollarSign className="w-4 h-4 text-gray-500" />
<FaDollarSign className="w-4 h-4 text-gray-500" />
<span className="font-medium">Vergi No:</span>
<span>{formData.vknTckn}</span>
</div>
{formData.reference && (
<div className="flex items-center gap-2">
<UserPlus className="w-4 h-4 text-gray-500" />
<FaUserPlus className="w-4 h-4 text-gray-500" />
<span className="font-medium">Referans:</span>
<span>{formData.reference}</span>
</div>
@ -229,7 +229,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
Şirket Adı *
</label>
<div className="relative">
<Building className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -244,7 +244,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Kurucu *</label>
<div className="relative">
<User className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaUser className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -261,7 +261,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Telefon *</label>
<div className="relative">
<Phone className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaPhone className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="tel"
required
@ -275,7 +275,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">E-posta *</label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaEnvelope className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="email"
required
@ -291,7 +291,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Adres *</label>
<div className="relative">
<MapPin className="absolute left-3 top-3 text-gray-400 w-5 h-5" />
<FaMapPin className="absolute left-3 top-3 text-gray-400 w-5 h-5" />
<textarea
required
placeholder="Enter your address"
@ -307,7 +307,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Ülke</label>
<div className="relative">
<Globe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaGlobe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
placeholder="Türkiye"
@ -320,7 +320,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Şehir *</label>
<div className="relative">
<Globe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaGlobe className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -337,7 +337,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">İlçe *</label>
<div className="relative">
<Map className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -351,7 +351,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Posta Kodu *</label>
<div className="relative">
<MapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaMapPin className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -368,7 +368,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Vergi Dairesi *</label>
<div className="relative">
<Banknote className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -382,7 +382,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Vergi No *</label>
<div className="relative">
<BadgeDollarSign className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaDollarSign className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
required
@ -398,7 +398,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<div>
<label className="text-sm font-medium text-gray-700">Referans</label>
<div className="relative">
<UserPlus className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<FaUserPlus className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
placeholder="Referans kişi veya kodu"
@ -417,14 +417,14 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
onClick={() => navigate('/products')}
className="flex items-center px-6 py-3 border border-gray-300 text-gray-700 rounded-lg"
>
<ArrowLeft className="w-4 h-4 mr-2" />
<FaArrowLeft className="w-4 h-4 mr-2" />
Geri
</button>
<button
type="submit"
className="flex items-center justify-center px-6 py-3 bg-green-600 text-white rounded-lg"
>
<ArrowRight className="w-5 h-5 mr-2" />
<FaArrowRight className="w-5 h-5 mr-2" />
Devam Et
</button>
</div>

View file

@ -2,9 +2,14 @@ import React, { useState, useMemo, useEffect } from 'react'
import { TemplateEditor } from '../reports/TemplateEditor'
import { ReportGenerator } from '../reports/ReportGenerator'
import { TemplateCard } from './TemplateCard'
import { Button } from '../ui/Button'
import { Input } from '../ui/Input'
import { Plus, Search, Filter, FileText, BarChart3 } from 'lucide-react'
import { Button, Input} from '../ui'
import {
FaPlus,
FaSearch,
FaFilter,
FaFileAlt,
FaChartBar
} from 'react-icons/fa';
import { ReportCategoryDto, ReportTemplateDto } from '@/proxy/reports/models'
import { useReports } from '@/utils/hooks/useReports'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -187,7 +192,7 @@ export const Dashboard: React.FC = () => {
<div className="flex items-center space-x-4">
{/* Search Input */}
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
<Input
placeholder="Şablon ara..."
value={searchQuery}
@ -202,7 +207,7 @@ export const Dashboard: React.FC = () => {
onClick={handleCreateTemplate}
className="bg-blue-600 hover:bg-blue-700 font-medium px-6 py-2.5 rounded-lg shadow-md hover:shadow-lg transition-all duration-200 flex items-center space-x-2"
>
<Plus className="h-5 w-5" />
<FaPlus className="h-5 w-5" />
<span>Yeni Şablon</span>
</Button>
</div>
@ -219,7 +224,7 @@ export const Dashboard: React.FC = () => {
<p className="text-2xl font-bold text-gray-900">{filteredTemplates.length}</p>
</div>
<div className="bg-blue-100 p-3 rounded-full">
<FileText className="h-6 w-6 text-blue-600" />
<FaFileAlt className="h-6 w-6 text-blue-600" />
</div>
</div>
</div>
@ -231,7 +236,7 @@ export const Dashboard: React.FC = () => {
<p className="text-2xl font-bold text-gray-900">{categories.length}</p>
</div>
<div className="bg-emerald-100 p-3 rounded-full">
<Filter className="h-6 w-6 text-emerald-600" />
<FaFilter className="h-6 w-6 text-emerald-600" />
</div>
</div>
</div>
@ -247,7 +252,7 @@ export const Dashboard: React.FC = () => {
</p>
</div>
<div className="bg-purple-100 p-3 rounded-full">
<BarChart3 className="h-6 w-6 text-purple-600" />
<FaChartBar className="h-6 w-6 text-purple-600" />
</div>
</div>
</div>
@ -256,7 +261,7 @@ export const Dashboard: React.FC = () => {
{/* Templates Grid */}
{filteredTemplates.length === 0 ? (
<div className="bg-white rounded-xl shadow-md p-12 border border-gray-200 text-center">
<FileText className="h-16 w-16 text-gray-400 mx-auto mb-4" />
<FaFileAlt className="h-16 w-16 text-gray-400 mx-auto mb-4" />
<h3 className="text-lg font-medium text-gray-900 mb-2">
{templates.length === 0 ? 'Henüz şablon oluşturulmamış' : 'Şablon bulunamadı'}
</h3>

View file

@ -1,9 +1,7 @@
import React, { useState } from 'react'
import { Button } from '../ui/Button'
import { Input } from '../ui/Input'
import { FileText } from 'lucide-react'
import { Button, Input, Dialog } from '../ui'
import { FaFileAlt } from 'react-icons/fa';
import { ReportTemplateDto } from '@/proxy/reports/models'
import { Dialog } from '../ui'
interface ReportGeneratorProps {
isOpen: boolean
@ -109,7 +107,7 @@ export const ReportGenerator: React.FC<ReportGeneratorProps> = ({
</div>
) : (
<div className="py-8 text-gray-500">
<FileText className="h-12 w-12 text-gray-400 mx-auto mb-4" />
<FaFileAlt className="h-12 w-12 text-gray-400 mx-auto mb-4" />
<p>Bu şablon için parametre tanımlanmamış.</p>
<p className="text-sm">Direkt rapor oluşturabilirsiniz.</p>
</div>
@ -123,7 +121,7 @@ export const ReportGenerator: React.FC<ReportGeneratorProps> = ({
className="bg-blue-600 hover:bg-blue-700 font-medium px-2 sm:px-3 py-1.5 rounded text-xs flex items-center gap-1"
>
<FileText className="h-4 w-4 mr-2" />
<FaFileAlt className="h-4 w-4 mr-2" />
{isGenerating ? 'Oluşturuluyor...' : 'Rapor Oluştur'}
</Button>
</div>

View file

@ -1,7 +1,14 @@
import React, { useState, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { Button } from '../ui/Button'
import { ArrowLeft, Calendar, FileText, Download, ZoomIn, ZoomOut } from 'lucide-react'
import {
FaArrowLeft,
FaCalendarAlt,
FaFileAlt,
FaDownload,
FaSearchPlus,
FaSearchMinus,
} from 'react-icons/fa'
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
import { ReportGeneratedDto, ReportTemplateDto } from '@/proxy/reports/models'
@ -131,7 +138,7 @@ export const ReportViewer: React.FC = () => {
<div className="text-center">
<h1 className="text-2xl font-bold text-gray-900 mb-4">{error || 'Rapor bulunamadı'}</h1>
<Button onClick={() => navigate(ROUTES_ENUM.protected.dashboard)}>
<ArrowLeft className="h-4 w-4 mr-2" />
<FaArrowLeft className="h-4 w-4 mr-2" />
Ana Sayfaya Dön
</Button>
</div>
@ -145,7 +152,7 @@ export const ReportViewer: React.FC = () => {
<div className="text-center">
<h1 className="text-2xl font-bold text-gray-900 mb-4">Rapor bulunamadı</h1>
<Button onClick={() => navigate(ROUTES_ENUM.protected.dashboard)}>
<ArrowLeft className="h-4 w-4 mr-2" />
<FaArrowLeft className="h-4 w-4 mr-2" />
Ana Sayfaya Dön
</Button>
</div>
@ -163,7 +170,7 @@ export const ReportViewer: React.FC = () => {
Aradığınız rapor mevcut değil veya silinmiş olabilir.
</p>
<Button onClick={() => navigate(ROUTES_ENUM.protected.dashboard)}>
<ArrowLeft className="h-4 w-4 mr-2" />
<FaArrowLeft className="h-4 w-4 mr-2" />
Ana Sayfaya Dön
</Button>
</div>
@ -242,7 +249,7 @@ export const ReportViewer: React.FC = () => {
<h1 className="text-lg font-semibold text-gray-900">{report.templateName}</h1>
<div className="flex items-center space-x-4 text-sm text-gray-500">
<span className="flex items-center">
<Calendar className="h-4 w-4 mr-1" />
<FaCalendarAlt className="h-4 w-4 mr-1" />
{new Date(report.generatedAt).toLocaleDateString('tr-TR', {
year: 'numeric',
month: 'long',
@ -253,7 +260,7 @@ export const ReportViewer: React.FC = () => {
</span>
{template && (
<span className="flex items-center">
<FileText className="h-4 w-4 mr-1" />
<FaFileAlt className="h-4 w-4 mr-1" />
{template.categoryName}
</span>
)}
@ -263,23 +270,25 @@ export const ReportViewer: React.FC = () => {
<div className="flex items-center space-x-2 flex-shrink-0">
<Button variant="solid" onClick={handleZoomOut} disabled={zoomLevel <= 50} size="sm">
<ZoomOut className="h-4 w-4" />
<FaSearchMinus className="h-4 w-4" />
</Button>
<span className="text-sm text-gray-600 px-2 min-w-[4rem] text-center">
{zoomLevel}%
</span>
<Button variant="solid" onClick={handleZoomIn} disabled={zoomLevel >= 200} size="sm">
<ZoomIn className="h-4 w-4" />
<FaSearchPlus className="h-4 w-4" />
</Button>
<div className="w-px h-6 bg-gray-300 mx-2"></div>
<Button
onClick={handleDownloadPdf}
className="bg-white-600 hover:bg-white-700 font-medium px-2 sm:px-3 py-1.5 rounded text-xs flex items-center gap-1"
>
<Download className="h-4 w-4 mr-2" />
<FaDownload className="h-4 w-4 mr-2" />
PDF İndir
</Button>
<Button variant="solid" onClick={handlePrint}>Yazdır</Button>
<Button variant="solid" onClick={handlePrint}>
Yazdır
</Button>
</div>
</div>
</div>

View file

@ -1,6 +1,6 @@
import React from 'react'
import { Button } from '../ui/Button'
import { FileText, Edit, Trash2, Play } from 'lucide-react'
import { FaFileAlt, FaEdit, FaTrash, FaPlay } from 'react-icons/fa';
import { ReportTemplateDto } from '@/proxy/reports/models'
interface TemplateCardProps {
@ -27,7 +27,7 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
</div>
<div className="flex items-center gap-1 flex-shrink-0 bg-gray-50 px-2 py-1 rounded-lg">
<FileText className="h-4 w-4 text-blue-500" />
<FaFileAlt className="h-4 w-4 text-blue-500" />
<span className="text-xs text-gray-500 whitespace-nowrap">{template.parameters.length}</span>
</div>
</div>
@ -69,7 +69,7 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
onClick={() => onGenerate(template)}
className="bg-gray-600 hover:bg-gray-700 font-medium px-3 py-1.5 rounded text-xs flex items-center gap-1 flex-1 justify-center min-w-0"
>
<Play className="h-3 w-3" />
<FaPlay className="h-3 w-3" />
<span className="truncate">Göster</span>
</Button>
@ -79,7 +79,7 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
onClick={() => onEdit(template)}
className="font-medium px-3 py-1.5 rounded text-xs flex items-center gap-1 flex-1 justify-center min-w-0"
>
<Edit className="h-3 w-3" />
<FaEdit className="h-3 w-3" />
<span className="truncate">Düzenle</span>
</Button>
@ -89,7 +89,7 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
onClick={() => onDelete(template.id)}
className="bg-red-600 hover:bg-red-700 font-medium px-3 py-1.5 rounded text-xs flex items-center justify-center flex-1 min-w-0"
>
<Trash2 className="h-3 w-3" />
<FaTrash className="h-3 w-3" />
<span className="truncate">Sil</span>
</Button>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'
import { Save, X, FileText, Code, Settings } from 'lucide-react'
import { FaSave, FaTimes, FaFileAlt, FaCode, FaCog } from 'react-icons/fa'
import { ReportHtmlEditor } from './ReportHtmlEditor'
import { ReportParameterDto, ReportTemplateDto, ReportCategoryDto } from '@/proxy/reports/models'
import { Button, Input, Dialog } from '../ui'
@ -132,15 +132,15 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
setFormData((prev) => ({
...prev,
parameters: prev.parameters.map((param) =>
param.id === paramId ? { ...param, ...updates } : param
param.id === paramId ? { ...param, ...updates } : param,
),
}))
}
const tabs = [
{ id: 'info', label: translate('::Şablon Bilgileri'), icon: FileText },
{ id: 'parameters', label: translate('::Parametreler'), icon: Settings },
{ id: 'content', label: translate('::HTML İçerik'), icon: Code },
{ id: 'info', label: translate('::Şablon Bilgileri'), icon: FaFileAlt },
{ id: 'parameters', label: translate('::Parametreler'), icon: FaCog },
{ id: 'content', label: translate('::HTML İçerik'), icon: FaCode },
]
return (
@ -250,7 +250,7 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
onClick={() => removeTag(tag)}
className="ml-2 text-blue-600 hover:text-blue-800"
>
<X className="h-3 w-3" />
<FaTimes className="h-3 w-3" />
</button>
</span>
))}
@ -303,7 +303,7 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
<div className="max-w-full mx-auto">
{formData.parameters.length === 0 ? (
<div className="text-center py-12">
<Settings className="h-16 w-16 text-gray-400 mx-auto mb-4" />
<FaCog className="h-16 w-16 text-gray-400 mx-auto mb-4" />
<p className="text-gray-500 text-lg mb-2">Henüz parametre algılanmadı</p>
<p className="text-gray-400 text-sm">
HTML içeriğinde @@PARAMETRE formatında parametreler kullandığınızda burada
@ -326,7 +326,9 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
</div>
<select
value={param.type}
onChange={(e) => updateParameter(param.id, { type: e.target.value as any })}
onChange={(e) =>
updateParameter(param.id, { type: e.target.value as any })
}
className="text-xs bg-gray-100 text-gray-600 px-1.5 py-0.5 rounded-full flex-shrink-0 ml-1 border-none outline-none cursor-pointer"
>
<option value="text">text</option>
@ -341,7 +343,9 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
<input
type="text"
value={param.description || ''}
onChange={(e) => updateParameter(param.id, { description: e.target.value })}
onChange={(e) =>
updateParameter(param.id, { description: e.target.value })
}
placeholder="Parametre açıklaması"
className="w-full text-xs text-gray-600 bg-transparent border-none outline-none resize-none"
/>
@ -351,7 +355,9 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
<input
type="text"
value={param.defaultValue || ''}
onChange={(e) => updateParameter(param.id, { defaultValue: e.target.value })}
onChange={(e) =>
updateParameter(param.id, { defaultValue: e.target.value })
}
placeholder="Varsayılan değer"
className="w-full text-xs bg-gray-50 px-1.5 py-0.5 rounded border border-gray-200 outline-none"
/>
@ -362,7 +368,9 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
<input
type="checkbox"
checked={param.required}
onChange={(e) => updateParameter(param.id, { required: e.target.checked })}
onChange={(e) =>
updateParameter(param.id, { required: e.target.checked })
}
className="w-3 h-3 text-red-600 rounded border-gray-300 focus:ring-red-500"
/>
<span className="text-xs text-gray-600">Zorunlu</span>
@ -388,7 +396,7 @@ export const TemplateEditor: React.FC<TemplateEditorProps> = ({
onClick={handleSave}
className="bg-blue-600 hover:bg-blue-700 font-medium px-2 py-2 rounded-lg shadow-md hover:shadow-lg transition-all duration-200 flex items-center space-x-2"
>
<Save className="h-5 w-5" />
<FaSave className="h-5 w-5" />
{isSaving ? 'Kaydediliyor...' : template ? 'Güncelle' : 'Kaydet'}
</Button>
</div>

View file

@ -1,5 +1,7 @@
import navigationIcon from '@/configs/navigation-icon.config'
import type { ElementType, ComponentPropsWithRef } from 'react'
import React from 'react'
import { FaQuestionCircle } from 'react-icons/fa'
type HorizontalMenuIconProps = {
icon: string
@ -16,11 +18,14 @@ export const Icon = <T extends ElementType>({
}
const HorizontalMenuIcon = ({ icon }: HorizontalMenuIconProps) => {
if (typeof icon !== 'string' && !icon) {
if (typeof icon !== 'string' || !icon) {
return <></>
}
return <span className="text-xl ltr:mr-2 rtl:ml-2">{navigationIcon[icon]}</span>
// React.createElement ile dinamik ikon bileşenini render et
const IconComponent = navigationIcon[icon] || FaQuestionCircle // fallback ikon
return <span className="text-xl ltr:mr-2 rtl:ml-2">{React.createElement(IconComponent)}</span>
}
export default HorizontalMenuIcon

View file

@ -2,6 +2,8 @@ import navigationIcon from '@/configs/navigation-icon.config'
import MenuItem from '@/components/ui/MenuItem'
import HorizontalMenuNavLink from './HorizontalMenuNavLink'
import type { NavMode } from '@/@types/theme'
import React from 'react'
import { FaQuestionCircle } from 'react-icons/fa'
export type HorizontalMenuItemProps = {
nav: {
@ -19,7 +21,9 @@ export type HorizontalMenuItemProps = {
const HorizontalMenuItem = ({ nav, isLink, manuVariant }: HorizontalMenuItemProps) => {
const { title, icon, path, isExternalLink } = nav
const renderIcon = icon && <span className="text-2xl">{navigationIcon[icon]}</span>
// Dinamik ikon render etmek için createElement kullanıyoruz
const renderIcon =
icon && React.createElement(navigationIcon[icon] || FaQuestionCircle, { className: 'text-2xl' })
return (
<>

View file

@ -16,7 +16,9 @@ import {
import { useStoreState } from '@/store'
import useMenuActive from '@/utils/hooks/useMenuActive'
import isEmpty from 'lodash/isEmpty'
import React from 'react'
import { useEffect } from 'react'
import { FaQuestionCircle } from 'react-icons/fa'
import { Link, useLocation } from 'react-router-dom'
export type SelectedMenuItem = {
@ -116,7 +118,9 @@ const StackedSideNavMini = (props: StackedSideNavMiniProps) => {
})
}
>
<div className="text-2xl">{navigationIcon[nav.icon]}</div>
<div className="text-2xl">
{React.createElement(navigationIcon[nav.icon] || FaQuestionCircle)}{' '}
</div>
</Menu.MenuItem>
) : (
<Link
@ -129,7 +133,9 @@ const StackedSideNavMini = (props: StackedSideNavMiniProps) => {
}
>
<Menu.MenuItem icon={nav.icon} eventKey={nav.key} className="mb-2">
<div className="text-2xl">{navigationIcon[nav.icon]}</div>
<div className="text-2xl">
{React.createElement(navigationIcon[nav.icon] || FaQuestionCircle)}
</div>
</Menu.MenuItem>
</Link>
)}

View file

@ -1,5 +1,6 @@
import navigationIcon from '@/configs/navigation-icon.config'
import type { ElementType, ComponentPropsWithRef } from 'react'
import React from 'react'
type VerticalMenuIconProps = {
icon: string
@ -16,11 +17,23 @@ export const Icon = <T extends ElementType>({
}
const VerticalMenuIcon = ({ icon }: VerticalMenuIconProps) => {
if (typeof icon !== 'string' && !icon) {
// Eğer icon boş veya string değilse, boş bir öğe döndür
if (typeof icon !== 'string' || !icon) {
return <></>
}
return <span className="text-2xl ltr:mr-2 rtl:ml-2">{navigationIcon[icon]}</span>
// navigationIcon'dan ikonu al ve React.createElement ile render et
const IconComponent = navigationIcon[icon]
if (!IconComponent) {
return <></> // İkon bulunamazsa, boş döndür
}
return (
<span className="text-2xl ltr:mr-2 rtl:ml-2">
{React.createElement(IconComponent)} {/* İkonu dinamik olarak render et */}
</span>
)
}
export default VerticalMenuIcon

View file

@ -1,17 +1,18 @@
import { createElement } from 'react'
import * as fc from 'react-icons/fc'
import * as fa from 'react-icons/fa'
export type NavigationIcons = Record<string, JSX.Element>
export type NavigationIcons = Record<string, React.ComponentType<any>>;
const navigationIcon: NavigationIcons = {}
const navigationIcon: NavigationIcons = {};
for (const icon of Object.entries(fc)) {
navigationIcon[icon[0]] = createElement(icon[1])
// fc (Font Awesome) ikonlarıyla dinamik olarak navigationIcon nesnesini doldur
for (const [key, Icon] of Object.entries(fc)) {
navigationIcon[key] = Icon; // Icon bileşenini doğrudan kullanıyoruz
}
for (const icon of Object.entries(fa)) {
navigationIcon[icon[0]] = createElement(icon[1])
// fa (Font Awesome) ikonlarıyla navigationIcon nesnesini doldur
for (const [key, Icon] of Object.entries(fa)) {
navigationIcon[key] = Icon; // Icon bileşenini doğrudan kullanıyoruz
}
export default navigationIcon
export default navigationIcon;

View file

@ -1,5 +1,5 @@
import React, { useState, useRef, useEffect, SyntheticEvent } from 'react'
import { Bot } from 'lucide-react'
import { FaRobot } from 'react-icons/fa';
import { useStoreActions, useStoreState } from '@/store'
import { Avatar, Dropdown } from '@/components/ui'
import LoadAiPostsFromLocalStorage from './LoadAiPostsFromLocalStorage'
@ -276,7 +276,7 @@ const Assistant = () => {
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.length === 0 && (
<div className="text-center text-gray-500 mt-8">
<Bot className="w-12 h-12 mx-auto mb-4 text-gray-400" />
<FaRobot className="w-12 h-12 mx-auto mb-4 text-gray-400" />
<p className="mt-2">{translate('::AI.Welcome')}</p>
<p className="text-lg font-medium">{translate('::AI.Name')}</p>
</div>
@ -293,7 +293,7 @@ const Assistant = () => {
{msg.role === 'user' ? (
<Avatar size={32} shape="circle" src={avatar} alt="avatar" />
) : (
<Bot className="w-5 h-5 text-white" />
<FaRobot className="w-5 h-5 text-white" />
)}
</div>
<div

View file

@ -9,6 +9,7 @@ import { GridColumnData } from '../list/GridColumnData'
import { useToolbar } from '../list/useToolbar'
import { PermissionResults, RowMode } from './types'
import { GridDto } from '@/proxy/form/models'
import React from 'react'
const FormButtons = (props: {
mode: RowMode
@ -108,8 +109,13 @@ const FormButtons = (props: {
key={'toolbarButton-' + i}
variant="default"
size="sm"
{...(item.options?.icon ? { icon: navigationIcon[item.options.icon] } : {})}
// title={translate(item.options.hint)} // TODO: translate('::' + item.options.hint) mu olmalı?
{...(item.options?.icon
? {
icon: React.createElement(navigationIcon[item.options.icon], {
className: 'text-gray-400',
}),
}
: {})}
onClick={item.options.onClick}
>
{item.options.text}
@ -130,7 +136,13 @@ const FormButtons = (props: {
key={'commandColumnButton-' + i}
variant="default"
size="sm"
{...(item.icon ? { icon: navigationIcon[item.icon] } : {})}
{...(item.icon
? {
icon: React.createElement(navigationIcon[item.icon], {
className: 'text-gray-400',
}),
}
: {})}
title={item.hint}
onClick={(e: any) => {
if (item.onClick) {

View file

@ -1,5 +1,5 @@
import React, { useState } from 'react'
import { Folder, MessageSquare, FileText, Plus, BarChart3 } from 'lucide-react'
import { FaFolder, FaCommentAlt, FaFileAlt, FaChartBar } from 'react-icons/fa'
import { CategoryManagement } from './CategoryManagement'
import { TopicManagement } from './TopicManagement'
import { PostManagement } from './PostManagement'
@ -81,22 +81,22 @@ export function AdminView({
{
id: 'stats' as AdminSection,
label: translate('::App.Forum.Dashboard.Dashboard'),
icon: BarChart3,
icon: FaChartBar,
},
{
id: 'categories' as AdminSection,
label: translate('::App.Forum.Dashboard.Categories'),
icon: Folder,
icon: FaFolder,
},
{
id: 'topics' as AdminSection,
label: translate('::App.Forum.Dashboard.Topics'),
icon: MessageSquare,
icon: FaCommentAlt,
},
{
id: 'posts' as AdminSection,
label: translate('::App.Forum.Dashboard.Posts'),
icon: FileText,
icon: FaFileAlt,
},
]

View file

@ -1,5 +1,14 @@
import React, { useState } from 'react'
import { Plus, Edit2, Trash2, Lock, Unlock, Eye, EyeOff, Loader2 } from 'lucide-react'
import {
FaPlus,
FaEdit,
FaTrash,
FaLock,
FaUnlock,
FaEye,
FaEyeSlash,
FaSpinner,
} from 'react-icons/fa'
import { ForumCategory } from '@/proxy/forum/forum'
import { useStoreState } from '@/store/store'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -161,7 +170,7 @@ export function CategoryManagement({
disabled={loading}
className="flex items-center space-x-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
<span>{translate('::App.Forum.CategoryManagement.AddCategory')}</span>
</button>
</div>
@ -320,7 +329,7 @@ export function CategoryManagement({
{loading ? (
<div className="p-8 text-center">
<Loader2 className="w-8 h-8 animate-spin mx-auto mb-4 text-blue-600" />
<FaSpinner className="w-8 h-8 animate-spin mx-auto mb-4 text-blue-600" />
<p className="text-gray-500">
{translate('::App.Forum.CategoryManagement.Loadingcategories')}
</p>
@ -368,9 +377,9 @@ export function CategoryManagement({
title={category.isActive ? 'Hide Category' : 'Show Category'}
>
{category.isActive ? (
<Eye className="w-4 h-4" />
<FaEye className="w-4 h-4" />
) : (
<EyeOff className="w-4 h-4" />
<FaEyeSlash className="w-4 h-4" />
)}
</button>
@ -384,9 +393,9 @@ export function CategoryManagement({
title={category.isLocked ? 'Unlock Category' : 'Lock Category'}
>
{category.isLocked ? (
<Lock className="w-4 h-4" />
<FaLock className="w-4 h-4" />
) : (
<Unlock className="w-4 h-4" />
<FaUnlock className="w-4 h-4" />
)}
</button>
@ -395,7 +404,7 @@ export function CategoryManagement({
className="p-2 text-blue-600 hover:bg-blue-100 rounded-lg transition-colors"
title={translate('::App.Forum.CategoryManagement.EditCategory')}
>
<Edit2 className="w-4 h-4" />
<FaEdit className="w-4 h-4" />
</button>
<button
@ -403,7 +412,7 @@ export function CategoryManagement({
className="p-2 text-red-600 hover:bg-red-100 rounded-lg transition-colors"
title={translate('::App.Forum.CategoryManagement.DeleteCategory')}
>
<Trash2 className="w-4 h-4" />
<FaTrash className="w-4 h-4" />
</button>
</div>
</div>
@ -437,8 +446,7 @@ export function CategoryManagement({
setCategoryToDelete(null)
}
}}
>
</ConfirmDialog>
></ConfirmDialog>
)}
</div>
)

View file

@ -1,4 +1,4 @@
import { Folder, MessageSquare, FileText, TrendingUp } from 'lucide-react'
import { FaFolder, FaCommentDots, FaFileAlt, FaChartLine } from 'react-icons/fa';
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
import { useLocalization } from '@/utils/hooks/useLocalization'
import dayjs from 'dayjs'
@ -31,28 +31,28 @@ export function AdminStats({ categories, topics, posts }: AdminStatsProps) {
title: translate('::App.Forum.Dashboard.TotalCategories'),
value: totalCategories,
subtitle: `${activeCategories} active`,
icon: Folder,
icon: FaFolder,
color: 'bg-blue-500',
},
{
title: translate('::App.Forum.Dashboard.TotalTopics'),
value: totalTopics,
subtitle: `${solvedTopics} solved`,
icon: MessageSquare,
icon: FaCommentDots,
color: 'bg-emerald-500',
},
{
title: translate('::App.Forum.Dashboard.TotalPosts'),
value: totalPosts,
subtitle: `${acceptedAnswers} accepted answers`,
icon: FileText,
icon: FaFileAlt,
color: 'bg-orange-500',
},
{
title: translate('::App.Forum.Dashboard.EngagementRate'),
value: totalTopics > 0 ? Math.round((totalPosts / totalTopics) * 100) / 100 : 0,
subtitle: 'posts per topic',
icon: TrendingUp,
icon: FaChartLine,
color: 'bg-purple-500',
},
]

View file

@ -1,5 +1,5 @@
import React, { useState } from 'react'
import { Plus, Edit2, Trash2, CheckCircle, Circle, Heart, Loader2 } from 'lucide-react'
import { FaPlus, FaEdit, FaTrashAlt, FaCheckCircle, FaCircle, FaHeart, FaSpinner } from 'react-icons/fa';
import { ForumPost, ForumTopic } from '@/proxy/forum/forum'
import { HtmlEditor, ImageUpload, Item, MediaResizing, Toolbar } from 'devextreme-react/html-editor'
import { useStoreState } from '@/store/store'
@ -169,7 +169,7 @@ export function PostManagement({
disabled={loading}
className="flex items-center space-x-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
<span>{translate('::App.Forum.PostManagement.AddPost')}</span>
</button>
</div>
@ -351,7 +351,7 @@ export function PostManagement({
{loading ? (
<div className="p-8 text-center">
<Loader2 className="w-8 h-8 animate-spin mx-auto mb-4 text-blue-600" />
<FaSpinner className="w-8 h-8 animate-spin mx-auto mb-4 text-blue-600" />
<p className="text-gray-500">{translate('::App.Forum.PostManagement.Loadingtopics')}</p>
</div>
) : (
@ -368,7 +368,7 @@ export function PostManagement({
<h4 className="text-sm font-semibold text-gray-900">{post.authorName}</h4>
{post.isAcceptedAnswer && (
<div className="flex items-center space-x-1 bg-emerald-100 text-emerald-700 px-2 py-1 rounded-full text-xs">
<CheckCircle className="w-3 h-3" />
<FaCheckCircle className="w-3 h-3" />
<span>Accepted Answer</span>
</div>
)}
@ -389,7 +389,7 @@ export function PostManagement({
<div className="flex items-center space-x-4">
<span>{formatDate(post.creationTime)}</span>
<div className="flex items-center space-x-1">
<Heart className="w-4 h-4" />
<FaHeart className="w-4 h-4" />
<span>{post.likeCount} likes</span>
</div>
</div>
@ -411,9 +411,9 @@ export function PostManagement({
}
>
{post.isAcceptedAnswer ? (
<CheckCircle className="w-4 h-4" />
<FaCheckCircle className="w-4 h-4" />
) : (
<Circle className="w-4 h-4" />
<FaCircle className="w-4 h-4" />
)}
</button>
@ -422,7 +422,7 @@ export function PostManagement({
className="p-2 text-blue-600 hover:bg-blue-100 rounded-lg transition-colors"
title={translate('::App.Forum.PostManagement.EditPost')}
>
<Edit2 className="w-4 h-4" />
<FaEdit className="w-4 h-4" />
</button>
<button
@ -430,7 +430,7 @@ export function PostManagement({
className="p-2 text-red-600 hover:bg-red-100 rounded-lg transition-colors"
title={translate('::App.Forum.PostManagement.DeletePost')}
>
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
</button>
</div>
</div>

View file

@ -1,17 +1,17 @@
import React, { useState } from 'react'
import {
Plus,
Edit2,
Trash2,
Lock,
Unlock,
Pin,
PinOff,
CheckCircle,
Circle,
Eye,
Loader2,
} from 'lucide-react'
FaPlus,
FaEdit,
FaTrashAlt,
FaLock,
FaUnlock,
FaThumbtack,
FaCheckCircle,
FaCircle,
FaEye,
FaSpinner,
FaTree,
} from 'react-icons/fa'
import { ForumCategory, ForumTopic } from '@/proxy/forum/forum'
import { useStoreState } from '@/store/store'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -219,7 +219,7 @@ export function TopicManagement({
disabled={loading}
className="flex items-center space-x-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
<span>{translate('::App.Forum.TopicManagement.AddTopic')}</span>
</button>
</div>
@ -362,7 +362,7 @@ export function TopicManagement({
{loading ? (
<div className="p-8 text-center">
<Loader2 className="w-8 h-8 animate-spin mx-auto mb-4 text-blue-600" />
<FaSpinner className="w-8 h-8 animate-spin mx-auto mb-4 text-blue-600" />
<p className="text-gray-500">
{translate('::App.Forum.TopicManagement.Loadingtopics')}
</p>
@ -378,9 +378,9 @@ export function TopicManagement({
<div className="flex items-start justify-between">
<div className="flex-1 min-w-0">
<div className="flex items-center space-x-2 mb-2">
{topic.isPinned && <Pin className="w-4 h-4 text-orange-500" />}
{topic.isLocked && <Lock className="w-4 h-4 text-gray-400" />}
{topic.isSolved && <CheckCircle className="w-4 h-4 text-emerald-500" />}
{topic.isPinned && <FaThumbtack className="w-4 h-4 text-orange-500" />}
{topic.isLocked && <FaLock className="w-4 h-4 text-gray-400" />}
{topic.isSolved && <FaCheckCircle className="w-4 h-4 text-emerald-500" />}
<h4 className="text-lg font-semibold text-gray-900 line-clamp-1">
{topic.title}
</h4>
@ -396,7 +396,7 @@ export function TopicManagement({
</div>
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-1">
<Eye className="w-4 h-4" />
<FaEye className="w-4 h-4" />
<span>{topic.viewCount}</span>
</div>
<span>{topic.replyCount} replies</span>
@ -416,9 +416,9 @@ export function TopicManagement({
title={topic.isPinned ? 'Unpin Topic' : 'Pin Topic'}
>
{topic.isPinned ? (
<PinOff className="w-4 h-4" />
<FaThumbtack className="w-4 h-4" />
) : (
<Pin className="w-4 h-4" />
<FaTree className="w-4 h-4" />
)}
</button>
@ -432,9 +432,9 @@ export function TopicManagement({
title={topic.isLocked ? 'Unlock Topic' : 'Lock Topic'}
>
{topic.isLocked ? (
<Lock className="w-4 h-4" />
<FaLock className="w-4 h-4" />
) : (
<Unlock className="w-4 h-4" />
<FaUnlock className="w-4 h-4" />
)}
</button>
@ -448,9 +448,9 @@ export function TopicManagement({
title={topic.isSolved ? 'Mark as Unsolved' : 'Mark as Solved'}
>
{topic.isSolved ? (
<CheckCircle className="w-4 h-4" />
<FaCheckCircle className="w-4 h-4" />
) : (
<Circle className="w-4 h-4" />
<FaCircle className="w-4 h-4" />
)}
</button>
@ -459,7 +459,7 @@ export function TopicManagement({
className="p-2 text-blue-600 hover:bg-blue-100 rounded-lg transition-colors"
title={translate('::App.Forum.TopicManagement.EditTopic')}
>
<Edit2 className="w-4 h-4" />
<FaEdit className="w-4 h-4" />
</button>
<button
@ -467,7 +467,7 @@ export function TopicManagement({
className="p-2 text-red-600 hover:bg-red-100 rounded-lg transition-colors"
title={translate('::App.Forum.TopicManagement.DeleteTopic')}
>
<Trash2 className="w-4 h-4" />
<FaTrashAlt className="w-4 h-4" />
</button>
</div>
</div>
@ -501,8 +501,7 @@ export function TopicManagement({
setTopicToDelete(null)
}
}}
>
</ConfirmDialog>
></ConfirmDialog>
)}
</div>
)

View file

@ -1,4 +1,4 @@
import { X } from 'lucide-react'
import { FaTimes } from 'react-icons/fa';
import { Formik, Form, Field, FieldProps } from 'formik'
import * as Yup from 'yup'
import { HtmlEditor, ImageUpload, Item, MediaResizing, Toolbar } from 'devextreme-react/html-editor'
@ -60,7 +60,7 @@ export function CreatePostModal({ onClose, onSubmit, parentPostId }: CreatePostM
: translate('::App.Forum.PostManagement.NewPost')}
</h3>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600 transition-colors">
<X className="w-5 h-5" />
<FaTimes className="w-5 h-5" />
</button>
</div>

View file

@ -1,4 +1,4 @@
import { X } from 'lucide-react'
import { FaTimes } from 'react-icons/fa';
import { useStoreState } from '@/store/store'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Field, FieldProps, Form, Formik } from 'formik'
@ -44,7 +44,7 @@ export function CreateTopicModal({ onClose, onSubmit }: CreateTopicModalProps) {
{translate('::App.Forum.TopicManagement.NewTopic')}
</h3>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600 transition-colors">
<X className="w-5 h-5" />
<FaTimes className="w-5 h-5" />
</button>
</div>

View file

@ -1,5 +1,4 @@
import React from 'react'
import { MessageSquare, Lock, TrendingUp } from 'lucide-react'
import { FaComment, FaLock, FaArrowUp } from 'react-icons/fa';
import { ForumCategory } from '@/proxy/forum/forum'
interface CategoryCardProps {
@ -35,16 +34,16 @@ export function ForumCategoryCard({ category, onClick }: CategoryCardProps) {
<h3 className="text-lg font-semibold text-gray-900 group-hover:text-blue-600 transition-colors">
{category.name}
</h3>
{category.isLocked && <Lock className="w-4 h-4 text-gray-400" />}
{category.isLocked && <FaLock className="w-4 h-4 text-gray-400" />}
</div>
<p className="text-gray-600 text-sm mb-3 line-clamp-2">{category.description}</p>
<div className="flex items-center space-x-4 text-sm text-gray-500">
<div className="flex items-center space-x-1">
<MessageSquare className="w-4 h-4" />
<FaComment className="w-4 h-4" />
<span>{category.topicCount} topics</span>
</div>
<div className="flex items-center space-x-1">
<TrendingUp className="w-4 h-4" />
<FaArrowUp className="w-4 h-4" />
<span>{category.postCount} posts</span>
</div>
</div>

View file

@ -1,5 +1,5 @@
import React from 'react'
import { Heart, User, CheckCircle, Reply } from 'lucide-react'
import { FaHeart, FaCheckCircle, FaReply } from 'react-icons/fa';
import { ForumPost } from '@/proxy/forum/forum'
import { AVATAR_URL } from '@/constants/app.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -56,7 +56,7 @@ export function ForumPostCard({
<h4 className="text-sm font-semibold text-gray-900">{post.authorName}</h4>
{post.isAcceptedAnswer && (
<div className="flex items-center space-x-1 bg-emerald-100 text-emerald-700 px-2 py-1 rounded-full text-xs">
<CheckCircle className="w-3 h-3" />
<FaCheckCircle className="w-3 h-3" />
<span>{translate('::App.Forum.PostManagement.AcceptedAnswer')}</span>
</div>
)}
@ -80,7 +80,7 @@ export function ForumPostCard({
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
}`}
>
<Heart className={`w-4 h-4 ${isLiked ? 'fill-current' : ''}`} />
<FaHeart className={`w-4 h-4 ${isLiked ? 'fill-current' : ''}`} />
<span>{post.likeCount}</span>
</button>
@ -89,7 +89,7 @@ export function ForumPostCard({
onClick={() => onReply(post.id)}
className="flex items-center space-x-1 px-3 py-1 rounded-full text-sm bg-gray-100 text-gray-600 hover:bg-gray-200 transition-colors"
>
<Reply className="w-4 h-4" />
<FaReply className="w-4 h-4" />
<span>{translate('::App.Forum.PostManagement.PostReply')}</span>
</button>
)}

View file

@ -1,5 +1,4 @@
import React from 'react'
import { MessageSquare, Heart, Eye, Pin, Lock, CheckCircle } from 'lucide-react'
import { FaComment, FaHeart, FaEye, FaThumbtack, FaLock, FaCheckCircle } from 'react-icons/fa';
import { ForumTopic } from '@/proxy/forum/forum'
import { AVATAR_URL } from '@/constants/app.constant'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -34,9 +33,9 @@ export function ForumTopicCard({ topic, onClick }: TopicCardProps) {
{/* Sol taraf: Başlık, içerik, istatistik */}
<div className="flex-1 min-w-0 pr-4">
<div className="flex items-center space-x-2 mb-2">
{topic.isPinned && <Pin className="w-4 h-4 text-orange-500" />}
{topic.isLocked && <Lock className="w-4 h-4 text-gray-400" />}
{topic.isSolved && <CheckCircle className="w-4 h-4 text-emerald-500" />}
{topic.isPinned && <FaThumbtack className="w-4 h-4 text-orange-500" />}
{topic.isLocked && <FaLock className="w-4 h-4 text-gray-400" />}
{topic.isSolved && <FaCheckCircle className="w-4 h-4 text-emerald-500" />}
<h3 className="text-lg font-semibold text-gray-900 group-hover:text-blue-600 transition-colors line-clamp-1">
{topic.title}
</h3>
@ -46,15 +45,15 @@ export function ForumTopicCard({ topic, onClick }: TopicCardProps) {
<div className="flex items-center space-x-4 text-sm text-gray-500">
<div className="flex items-center space-x-1" title="Views">
<Eye className="w-4 h-4" />
<FaEye className="w-4 h-4" />
<span>{topic.viewCount}</span>
</div>
<div className="flex items-center space-x-1" title="Replies">
<MessageSquare className="w-4 h-4" />
<FaComment className="w-4 h-4" />
<span>{topic.replyCount}</span>
</div>
<div className="flex items-center space-x-1" title="Likes">
<Heart className="w-4 h-4" />
<FaHeart className="w-4 h-4" />
<span>{topic.likeCount}</span>
</div>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState } from 'react'
import { ArrowLeft, Plus, Loader2, Search } from 'lucide-react'
import { FaArrowLeft, FaPlus, FaSpinner, FaSearch } from 'react-icons/fa';
import { CreateTopicModal } from './CreateTopicModal'
import { CreatePostModal } from './CreatePostModal'
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
@ -292,7 +292,7 @@ export function ForumView({
return (
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div className="flex items-center justify-center h-64">
<Loader2 className="w-8 h-8 animate-spin text-blue-600" />
<FaSpinner className="w-8 h-8 animate-spin text-blue-600" />
<span className="ml-2 text-gray-600">Loading forum data...</span>
</div>
</div>
@ -311,7 +311,7 @@ export function ForumView({
onClick={handleBack}
className="flex items-center space-x-1 text-blue-600 hover:text-blue-700 transition-colors"
>
<ArrowLeft className="w-4 h-4" />
<FaArrowLeft className="w-4 h-4" />
<span>Back</span>
</button>
)}
@ -357,7 +357,7 @@ export function ForumView({
onClick={() => setShowCreateTopic(true)}
className="flex items-center space-x-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
<span>{translate('::App.Forum.TopicManagement.NewTopic')}</span>
</button>
)}
@ -366,7 +366,7 @@ export function ForumView({
onClick={() => setShowCreatePost(true)}
className="flex items-center space-x-2 bg-emerald-600 text-white px-4 py-2 rounded-lg hover:bg-emerald-700 transition-colors"
>
<Plus className="w-4 h-4" />
<FaPlus className="w-4 h-4" />
<span>{translate('::App.Forum.PostManagement.NewPost')}</span>
</button>
)}
@ -376,7 +376,7 @@ export function ForumView({
onClick={() => setIsSearchModalOpen(true)}
className="hidden md:flex items-center space-x-2 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
>
<Search className="w-4 h-4 text-gray-400" />
<FaSearch className="w-4 h-4 text-gray-400" />
<span className="text-gray-500">{translate('::App.Forum.TopicManagement.Searchtopics')}</span>
<kbd className="hidden sm:inline-block px-2 py-1 text-xs font-semibold text-gray-500 bg-gray-100 border border-gray-200 rounded">
K
@ -387,7 +387,7 @@ export function ForumView({
onClick={() => setIsSearchModalOpen(true)}
className="md:hidden p-2 text-gray-400 hover:text-gray-600 transition-colors"
>
<Search className="w-5 h-5" />
<FaSearch className="w-5 h-5" />
</button>
</div>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'
import { X, Search, Folder, MessageSquare, FileText, User } from 'lucide-react'
import { FaTimes, FaSearch, FaFolder, FaRegComment, FaFileAlt } from 'react-icons/fa'
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
import { useForumSearch } from '@/utils/hooks/useForumSearch'
@ -107,7 +107,7 @@ export function SearchModal({
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-start justify-center pt-20 p-4 z-50">
<div className="bg-white rounded-xl shadow-xl max-w-2xl w-full max-h-[70vh] overflow-hidden">
<div className="flex items-center p-4 border-b border-gray-200">
<Search className="w-5 h-5 text-gray-400 mr-3" />
<FaSearch className="w-5 h-5 text-gray-400 mr-3" />
<input
type="text"
value={searchQuery}
@ -121,14 +121,14 @@ export function SearchModal({
onClick={onClose}
className="text-gray-400 hover:text-gray-600 transition-colors ml-3"
>
<X className="w-5 h-5" />
<FaTimes className="w-5 h-5" />
</button>
</div>
<div className="overflow-y-auto max-h-96">
{!searchQuery.trim() ? (
<div className="p-8 text-center text-gray-500">
<Search className="w-12 h-12 mx-auto mb-4 text-gray-300" />
<FaSearch className="w-12 h-12 mx-auto mb-4 text-gray-300" />
<p>Start typing to search categories, topics, and posts...</p>
</div>
) : !hasResults ? (
@ -157,7 +157,7 @@ export function SearchModal({
<div className="flex items-center space-x-3 flex-1">
<div className="flex-shrink-0">
<div className="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center">
<Folder className="w-4 h-4 text-blue-600" />
<FaFolder className="w-4 h-4 text-blue-600" />
</div>
</div>
<div className="text-left">
@ -197,7 +197,7 @@ export function SearchModal({
<div className="flex items-center space-x-3 flex-1">
<div className="flex-shrink-0">
<div className="w-8 h-8 bg-emerald-100 rounded-lg flex items-center justify-center">
<MessageSquare className="w-4 h-4 text-emerald-600" />
<FaRegComment className="w-4 h-4 text-emerald-600" />
</div>
</div>
<div className="text-left">
@ -241,7 +241,7 @@ export function SearchModal({
<div className="flex items-center space-x-3 flex-1">
<div className="flex-shrink-0">
<div className="w-8 h-8 bg-orange-100 rounded-lg flex items-center justify-center">
<FileText className="w-4 h-4 text-orange-600" />
<FaFileAlt className="w-4 h-4 text-orange-600" />
</div>
</div>
<div className="text-left">

View file

@ -20,7 +20,11 @@ import {
import { Field, FieldProps, Form, Formik } from 'formik'
import { SelectBoxOption } from '@/shared/types'
import * as Yup from 'yup'
import { ExternalLink, FileText, Plus, Trash2 } from 'lucide-react'
import {
FaExternalLinkAlt,
FaPlus,
FaTrashAlt
} from 'react-icons/fa';
import { MenuDto } from '@/proxy/menus/models'
interface MenuItemComponentProps {
@ -124,17 +128,21 @@ export const MenuItemComponent: React.FC<MenuItemComponentProps> = ({
{isDesignMode && (
<div className="flex gap-2 items-center mr-2">
<button onClick={() => setIsModalOpen(true)} title="New Item">
<Plus size={16} className="text-green-600 hover:text-green-800" />
<FaPlus size={16} className="text-green-600 hover:text-green-800" />
</button>
<button onClick={handleDelete} title="Delete Item">
<Trash2 size={16} className="text-red-600 hover:text-red-800" />
<FaTrashAlt size={16} className="text-red-600 hover:text-red-800" />
</button>
</div>
)}
<div className="flex items-center gap-3 flex-1 min-w-0">
<div className="flex-shrink-0 text-gray-600 text-xl">
{navigationIcon[item.icon || ''] ?? <FaQuestionCircle className="text-gray-400" />}
{navigationIcon[item.icon || ''] ? (
React.createElement(navigationIcon[item.icon || ''], { className: 'text-gray-400' })
) : (
<FaQuestionCircle className="text-gray-400" />
)}
</div>
<span
@ -146,7 +154,7 @@ export const MenuItemComponent: React.FC<MenuItemComponentProps> = ({
{translate('::' + item.displayName)}
</span>
{item.url && <ExternalLink size={12} className="flex-shrink-0 text-gray-400" />}
{item.url && <FaExternalLinkAlt size={12} className="flex-shrink-0 text-gray-400" />}
</div>
<div className="flex items-center gap-2 flex-shrink-0">

View file

@ -2,7 +2,12 @@ import React, { useState } from 'react'
import { SortableMenuTree } from './SortableMenuTree'
import { MenuItem } from '@/@types/menu'
import { useMenuData } from '@/utils/hooks/useMenuData'
import { AlertCircle, Loader2, Menu, Save } from 'lucide-react'
import {
FaRegBell,
FaSpinner,
FaBars,
FaRegSave
} from 'react-icons/fa';
import { Container } from '@/components/shared'
import { Helmet } from 'react-helmet'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -53,7 +58,7 @@ export const MenuManager = () => {
return (
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
<div className="flex items-center gap-3 text-gray-600">
<Loader2 size={24} className="animate-spin" />
<FaSpinner className="animate-spin" />
<span className="text-lg">Loading menu configuration...</span>
</div>
</div>
@ -65,7 +70,7 @@ export const MenuManager = () => {
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
<div className="bg-white p-8 rounded-lg shadow-md max-w-md w-full mx-4">
<div className="flex items-center gap-3 text-red-600 mb-4">
<AlertCircle size={24} />
<FaRegBell size={24} />
<h2 className="text-lg font-semibold">Error Loading Menu</h2>
</div>
<p className="text-gray-600 mb-6">{error}</p>
@ -92,7 +97,7 @@ export const MenuManager = () => {
<div className="flex items-center justify-between mb-6 flex-wrap gap-4">
{/* Sol kısım: Başlık */}
<div className="flex items-center gap-2">
<Menu size={20} className="text-gray-600" />
<FaBars size={20} className="text-gray-600" />
<h2 className="text-lg font-semibold text-gray-900">Menu Manager</h2>
<span className="text-sm text-gray-500">({menuItems.length} root items)</span>
</div>
@ -133,12 +138,12 @@ export const MenuManager = () => {
>
{isSaving ? (
<>
<Loader2 size={16} className="animate-spin" />
<FaSpinner size={16} className="animate-spin" />
Saving...
</>
) : (
<>
<Save size={16} />
<FaRegSave size={16} />
Save Changes
</>
)}
@ -156,7 +161,7 @@ export const MenuManager = () => {
/>
) : (
<div className="text-center py-12 text-gray-500">
<Menu size={24} className="mx-auto mb-4 text-gray-300" />
<FaBars size={24} className="mx-auto mb-4 text-gray-300" />
<p className="text-lg">No menu items found</p>
<p className="text-sm">Try refreshing the page or contact your administrator</p>
</div>

View file

@ -1,5 +1,10 @@
import React from 'react'
import { Users, Award, Clock, Globe2 } from 'lucide-react'
import {
FaUsers,
FaAward,
FaClock,
FaGlobe
} from 'react-icons/fa';
import { useLocalization } from '@/utils/hooks/useLocalization'
import { useCountUp } from '@/utils/hooks/useCountUp'
import { Helmet } from 'react-helmet'
@ -45,26 +50,26 @@ const About: React.FC = () => {
<div className="container mx-auto px-4">
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
<div className="text-center" ref={clientsCount.elementRef}>
<Users className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<FaUsers className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<div className="text-4xl font-bold text-gray-900 mb-2">
{clientsCount.displayValue}
</div>
<div className="text-gray-600">{translate('::Public.about.stats.clients')}</div>
</div>
<div className="text-center" ref={experienceCount.elementRef}>
<Award className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<FaAward className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<div className="text-4xl font-bold text-gray-900 mb-2">
{experienceCount.displayValue}
</div>
<div className="text-gray-600">{translate('::Public.about.stats.experience')}</div>
</div>
<div className="text-center">
<Clock className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<FaClock className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<div className="text-4xl font-bold text-gray-900 mb-2">7/24</div>
<div className="text-gray-600">{translate('::Public.about.stats.support')}</div>
</div>
<div className="text-center" ref={countriesCount.elementRef}>
<Globe2 className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<FaGlobe className="w-12 h-12 text-blue-600 mx-auto mb-4" />
<div className="text-4xl font-bold text-gray-900 mb-2">
{countriesCount.displayValue}
</div>

View file

@ -1,6 +1,11 @@
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Calendar, Clock, User, Tag, Search } from 'lucide-react'
import {
FaCalendarAlt,
FaUser,
FaTag,
FaSearch
} from 'react-icons/fa';
import dayjs from 'dayjs'
import 'dayjs/locale/tr'
import { BlogCategory, BlogPost } from '@/proxy/blog/blog'
@ -110,7 +115,7 @@ const Blog = () => {
placeholder="Blog yazılarında ara..."
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<Search className="absolute left-3 top-2.5 h-5 w-5 text-gray-400" />
<FaSearch className="absolute left-3 top-2.5 h-5 w-5 text-gray-400" />
</div>
</form>
@ -181,7 +186,7 @@ const Blog = () => {
key={index}
className="inline-flex items-center text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded"
>
<Tag className="w-3 h-3 mr-1" />
<FaTag className="w-3 h-3 mr-1" />
{tag}
</span>
))}
@ -190,11 +195,11 @@ const Blog = () => {
<div className="flex items-center text-sm text-gray-500 space-x-4">
<div className="flex items-center">
<User size={16} className="mr-1" />
<FaUser size={16} className="mr-1" />
{post.author.name}
</div>
<div className="flex items-center">
<Calendar size={16} className="mr-1" />
<FaCalendarAlt size={16} className="mr-1" />
{dayjs(post.publishedAt || post.creationTime).format('DD MMM YYYY')}
</div>
</div>

View file

@ -1,14 +1,14 @@
import React from 'react'
import {
Mail,
Phone,
MapPin,
FileText,
Building,
CalendarDays,
CalendarCheck,
MessageCircle,
} from 'lucide-react'
FaMailBulk,
FaPhone,
FaMapPin,
FaFileAlt,
FaBuilding,
FaCalendarAlt,
FaCalendarCheck,
FaRegComment
} from 'react-icons/fa';
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Helmet } from 'react-helmet'
@ -53,19 +53,19 @@ const Contact: React.FC = () => {
</h2>
<div className="space-y-6">
<div className="flex items-start space-x-4">
<MapPin className="w-6 h-6 text-blue-600 flex-shrink-0 mt-1" />
<FaMapPin className="w-6 h-6 text-blue-600 flex-shrink-0 mt-1" />
<div>
<p className="text-gray-600">{translate('::Public.contact.address.full')}</p>
</div>
</div>
<div className="flex items-start space-x-4">
<Phone className="w-6 h-6 text-blue-600 flex-shrink-0" />
<FaPhone className="w-6 h-6 text-blue-600 flex-shrink-0" />
<div>
<p className="text-gray-600">+90 (544) 769 7 638</p>
</div>
</div>
<div className="flex items-start space-x-4">
<Mail className="w-6 h-6 text-blue-600 flex-shrink-0" />
<FaMailBulk className="w-6 h-6 text-blue-600 flex-shrink-0" />
<div>
<p className="text-gray-600">
<a
@ -78,13 +78,13 @@ const Contact: React.FC = () => {
</div>
</div>
<div className="flex items-start space-x-4">
<Building className="w-6 h-6 text-blue-600 flex-shrink-0" />
<FaBuilding className="w-6 h-6 text-blue-600 flex-shrink-0" />
<div>
<p className="text-gray-600">Kozyatağı</p>
</div>
</div>
<div className="flex items-start space-x-4">
<FileText className="w-6 h-6 text-blue-600 flex-shrink-0" />
<FaFileAlt className="w-6 h-6 text-blue-600 flex-shrink-0" />
<div>
<p className="text-gray-600">32374982750</p>
</div>
@ -124,19 +124,19 @@ const Contact: React.FC = () => {
<div className="flex items-start space-x-4">
<div className="space-y-2">
<div className="flex items-center space-x-2">
<CalendarDays className="w-5 h-5 text-blue-500" />
<FaCalendarAlt className="w-5 h-5 text-blue-500" />
<p className="text-gray-600">
{translate('::Public.contact.workHours.weekday')}
</p>
</div>
<div className="flex items-center space-x-2">
<CalendarCheck className="w-5 h-5 text-blue-500" />
<FaCalendarCheck className="w-5 h-5 text-blue-500" />
<p className="text-gray-600">
{translate('::Public.contact.workHours.weekend')}
</p>
</div>
<div className="flex items-center space-x-2">
<MessageCircle className="w-5 h-5 text-green-500" />
<FaRegComment className="w-5 h-5 text-green-500" />
<p className="text-gray-600">
{translate('::Public.contact.workHours.whatsapp')}
</p>

View file

@ -1,15 +1,15 @@
import React, { useEffect, useState } from "react";
import {
Building2,
User,
Mail,
Phone,
MapPin,
Users,
MessageSquare,
Send,
CheckCircle,
} from "lucide-react";
FaBuilding,
FaUser,
FaEnvelope,
FaPhone,
FaMapPin,
FaUsers,
FaRegComment,
FaPaperPlane,
FaCheckCircle
} from 'react-icons/fa';
import { useLocalization } from "@/utils/hooks/useLocalization";
interface DemoModalProps {
@ -131,7 +131,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
</button>
<div className="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-6">
<CheckCircle className="w-8 h-8 text-white" />
<FaCheckCircle className="w-8 h-8 text-white" />
</div>
<h2 className="text-2xl font-bold text-gray-800 mb-4">
Teşekkürler!
@ -189,7 +189,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.company')} *
</label>
<div className="relative">
<Building2 className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaBuilding className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
autoFocus
@ -212,7 +212,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.fullName')} *
</label>
<div className="relative">
<User className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaUser className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
name="fullName"
@ -235,7 +235,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.email')} *
</label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaEnvelope className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="email"
name="email"
@ -256,7 +256,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.phone')} *
</label>
<div className="relative">
<Phone className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaPhone className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="tel"
name="phone"
@ -279,7 +279,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.address')} *
</label>
<div className="relative">
<MapPin className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaMapPin className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="text"
name="address"
@ -302,7 +302,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.branchCount')} *
</label>
<div className="relative">
<Building2 className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaBuilding className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="number"
name="numberOfBranches"
@ -324,7 +324,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.userCount')} *
</label>
<div className="relative">
<Users className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<FaUsers className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
<input
type="number"
name="numberOfUsers"
@ -348,7 +348,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
{translate('::Public.common.message')} *
</label>
<div className="relative">
<MessageSquare className="absolute left-3 top-3 w-5 h-5 text-gray-400" />
<FaRegComment className="absolute left-3 top-3 w-5 h-5 text-gray-400" />
<textarea
name="message"
value={formData.message}
@ -369,7 +369,7 @@ const Demo: React.FC<DemoModalProps> = ({ isOpen, onClose }) => {
type="submit"
className="w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white font-semibold py-4 px-6 rounded-xl transition-all duration-300 transform hover:scale-[1.02] hover:shadow-lg flex items-center justify-center gap-2"
>
<Send className="w-5 h-5" />
<FaPaperPlane className="w-5 h-5" />
{translate('::Public.demo.send')}
</button>
</div>

View file

@ -1,20 +1,20 @@
import React from 'react'
import { Link } from 'react-router-dom'
import {
ArrowRight,
Calendar,
Users,
Shield,
Monitor,
Smartphone,
Server,
Database,
BarChart,
BookOpen,
CreditCard,
MessageSquare,
Phone,
} from 'lucide-react'
FaArrowRight,
FaCalendarAlt,
FaUsers,
FaShieldAlt,
FaDesktop,
FaMobileAlt,
FaServer,
FaDatabase,
FaChartBar,
FaBookOpen,
FaCreditCard,
FaRegComment,
FaPhone
} from 'react-icons/fa';
import { useLocalization } from '@/utils/hooks/useLocalization'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { Helmet } from 'react-helmet'
@ -24,42 +24,42 @@ const Home: React.FC = () => {
const features = [
{
icon: <Users className="w-12 h-12 text-blue-500" />,
icon: <FaUsers className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.reliable'),
description: translate('::Public.features.reliable.desc'),
},
{
icon: <Calendar className="w-12 h-12 text-blue-500" />,
icon: <FaCalendarAlt className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.rapid'),
description: translate('::Public.features.rapid.desc'),
},
{
icon: <BookOpen className="w-12 h-12 text-blue-500" />,
icon: <FaBookOpen className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.expert'),
description: translate('::Public.features.expert.desc'),
},
{
icon: <CreditCard className="w-12 h-12 text-blue-500" />,
icon: <FaCreditCard className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.muhasebe'),
description: translate('::Public.features.muhasebe.desc'),
},
{
icon: <MessageSquare className="w-12 h-12 text-blue-500" />,
icon: <FaRegComment className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.iletisim'),
description: translate('::Public.features.iletisim.desc'),
},
{
icon: <Phone className="w-12 h-12 text-blue-500" />,
icon: <FaPhone className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.mobil'),
description: translate('::Public.features.mobil.desc'),
},
{
icon: <BarChart className="w-12 h-12 text-blue-500" />,
icon: <FaChartBar className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.scalable'),
description: translate('::Public.features.scalable.desc'),
},
{
icon: <Shield className="w-12 h-12 text-blue-500" />,
icon: <FaShieldAlt className="w-12 h-12 text-blue-500" />,
title: translate('::Public.features.guvenlik'),
description: translate('::Public.features.guvenlik.desc'),
},
@ -67,25 +67,25 @@ const Home: React.FC = () => {
const solutions = [
{
icon: <Monitor className="w-16 h-16 text-white" />,
icon: <FaDesktop className="w-16 h-16 text-white" />,
title: translate('::Public.solutions.web.title'),
description: translate('::Public.solutions.web.desc'),
color: 'bg-blue-600',
},
{
icon: <Smartphone className="w-16 h-16 text-white" />,
icon: <FaMobileAlt className="w-16 h-16 text-white" />,
title: translate('::Public.solutions.mobile.title'),
description: translate('::Public.solutions.mobile.desc'),
color: 'bg-purple-600',
},
{
icon: <Server className="w-16 h-16 text-white" />,
icon: <FaServer className="w-16 h-16 text-white" />,
title: translate('::Public.solutions.custom.title'),
description: translate('::Public.solutions.custom.desc'),
color: 'bg-green-600',
},
{
icon: <Database className="w-16 h-16 text-white" />,
icon: <FaDatabase className="w-16 h-16 text-white" />,
title: translate('::Public.solutions.database.title'),
description: translate('::Public.solutions.database.desc'),
color: 'bg-red-600',
@ -128,7 +128,7 @@ const Home: React.FC = () => {
className="inline-flex items-center justify-center px-8 py-4 bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600 text-white rounded-lg font-semibold transition-all transform hover:scale-105"
>
{translate('::Public.hero.cta.consultation')}{' '}
<ArrowRight className="ml-2" size={20} />
<FaArrowRight className="ml-2" size={20} />
</Link>
<Link
to={ROUTES_ENUM.public.products}
@ -140,21 +140,21 @@ const Home: React.FC = () => {
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-4xl mx-auto">
<div className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all">
<Calendar className="mx-auto mb-4 text-blue-400" size={40} />
<FaCalendarAlt className="mx-auto mb-4 text-blue-400" size={40} />
<h3 className="text-xl font-semibold mb-3 text-white">
{translate('::Public.hero.service1.title')}
</h3>
<p className="text-gray-300">{translate('::Public.hero.service1.desc')}</p>
</div>
<div className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all">
<Users className="mx-auto mb-4 text-purple-400" size={40} />
<FaUsers className="mx-auto mb-4 text-purple-400" size={40} />
<h3 className="text-xl font-semibold mb-3 text-white">
{translate('::Public.hero.service2.title')}
</h3>
<p className="text-gray-300">{translate('::Public.hero.service2.desc')}</p>
</div>
<div className="bg-white/5 backdrop-blur-sm rounded-2xl p-8 text-center hover:scale-105 hover:bg-white/10 transition-all">
<Shield className="mx-auto mb-4 text-indigo-400" size={40} />
<FaShieldAlt className="mx-auto mb-4 text-indigo-400" size={40} />
<h3 className="text-xl font-semibold mb-3 text-white">
{translate('::Public.hero.service3.title')}
</h3>

View file

@ -1,5 +1,5 @@
import React from 'react';
import { Frown } from 'lucide-react'; // Lucide-react kütüphanesinden Frown ikonunu import et
import { FaFrown } from 'react-icons/fa';
import { ROUTES_ENUM } from '@/routes/route.constant';
import { useLocalization } from '@/utils/hooks/useLocalization';
@ -8,7 +8,7 @@ const NotFound: React.FC = () => {
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-white text-gray-700 p-4"> {/* Arka plan ve metin rengi güncellendi, padding eklendi */}
<Frown size={128} className="text-blue-600 mb-6" /> {/* İkon boyutu ve rengi güncellendi */}
<FaFrown size={128} className="text-blue-600 mb-6" /> {/* İkon boyutu ve rengi güncellendi */}
<h1 className="text-7xl font-bold text-gray-900 mb-4">404</h1> {/* Başlık boyutu ve rengi güncellendi */}
<p className="text-xl text-gray-600 mb-8 text-center max-w-md"> {/* Metin rengi, margin ve max-width güncellendi */}
{translate('::Public.notFound.message')}

View file

@ -1,5 +1,5 @@
import React from 'react'
import { Code2, Globe2, Server, Users, Shield, Settings, CheckCircle } from 'lucide-react'
import { FaCode, FaGlobe, FaServer, FaUsers, FaShieldAlt, FaCog, FaCheckCircle } from 'react-icons/fa';
import { Link } from 'react-router-dom'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { ROUTES_ENUM } from '@/routes/route.constant'
@ -10,7 +10,7 @@ const Services: React.FC = () => {
const services = [
{
icon: <Code2 className="w-12 h-12 text-blue-600" />,
icon: <FaCode className="w-12 h-12 text-blue-600" />,
title: translate('::Public.services.software.title'),
description: translate('::Public.services.software.desc'),
features: [
@ -22,7 +22,7 @@ const Services: React.FC = () => {
],
},
{
icon: <Users className="w-12 h-12 text-purple-600" />,
icon: <FaUsers className="w-12 h-12 text-purple-600" />,
title: translate('::Public.services.web.title'),
description: translate('::Public.services.web.desc'),
features: [
@ -34,7 +34,7 @@ const Services: React.FC = () => {
],
},
{
icon: <Shield className="w-12 h-12 text-green-600" />,
icon: <FaShieldAlt className="w-12 h-12 text-green-600" />,
title: translate('::Public.services.mobile.title'),
description: translate('::Public.services.mobile.desc'),
features: [
@ -46,7 +46,7 @@ const Services: React.FC = () => {
],
},
{
icon: <Server className="w-12 h-12 text-red-600" />,
icon: <FaServer className="w-12 h-12 text-red-600" />,
title: translate('::Public.services.database.title'),
description: translate('::Public.services.database.desc'),
features: [
@ -58,7 +58,7 @@ const Services: React.FC = () => {
],
},
{
icon: <Globe2 className="w-12 h-12 text-yellow-600" />,
icon: <FaGlobe className="w-12 h-12 text-yellow-600" />,
title: translate('::Public.services.integration.title'),
description: translate('::Public.services.integration.desc'),
features: [
@ -70,7 +70,7 @@ const Services: React.FC = () => {
],
},
{
icon: <Settings className="w-12 h-12 text-indigo-600" />,
icon: <FaCog className="w-12 h-12 text-indigo-600" />,
title: translate('::Public.services.consulting.title'),
description: translate('::Public.services.consulting.desc'),
features: [
@ -189,7 +189,7 @@ const Services: React.FC = () => {
<ul className="space-y-3 mb-8">
{plan.features.map((feature, fIndex) => (
<li key={fIndex} className="flex items-center space-x-2 text-gray-700">
<CheckCircle className="w-5 h-5 text-green-500 flex-shrink-0" />
<FaCheckCircle className="w-5 h-5 text-green-500 flex-shrink-0" />
<span>{feature}</span>
</li>
))}