Genel hata kontrolü ve düzenlemeler

npx tsc --noEmit --pretty false
dotnet build --no-restore --nologo --verbosity quiet
This commit is contained in:
Sedat ÖZTÜRK 2026-07-10 11:18:20 +03:00
parent 7f7c6fab36
commit d982a3ce42
46 changed files with 735 additions and 2220 deletions

View file

@ -107,9 +107,31 @@ public partial class LanguageTextCreateUpdateDtoToLanguageTextMapper : MapperBas
public partial class LanguageKeyToLanguageTextTranslatedDtoMapper : MapperBase<LanguageKey, LanguageTextTranslatedDto>
{
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.Id))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.BaseCultureName))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.BaseValue))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.TargetCultureName))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.TargetValue))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.IsDeleted))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.DeleterId))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.DeletionTime))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.LastModificationTime))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.LastModifierId))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.CreationTime))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.CreatorId))]
public override partial LanguageTextTranslatedDto Map(LanguageKey source);
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.Id))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.BaseCultureName))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.BaseValue))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.TargetCultureName))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.TargetValue))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.IsDeleted))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.DeleterId))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.DeletionTime))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.LastModificationTime))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.LastModifierId))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.CreationTime))]
[MapperIgnoreTarget(nameof(LanguageTextTranslatedDto.CreatorId))]
public override partial void Map(LanguageKey source, LanguageTextTranslatedDto destination);
public override void BeforeMap(LanguageKey source)

View file

@ -1542,12 +1542,6 @@
"en": "Charts",
"tr": "Grafikler"
},
{
"resourceName": "Platform",
"key": "App.Listforms.ImportManager.Uploading",
"en": "Uploading...",
"tr": "Yükleniyor..."
},
{
"resourceName": "Platform",
"key": "App.Listforms.ImportManager.Validating",
@ -8252,37 +8246,37 @@
},
{
"resourceName": "Platform",
"key": "Public.cart.title",
"key": "Public.basket.title",
"tr": "Sepetim",
"en": "My Cart"
"en": "My Basket"
},
{
"resourceName": "Platform",
"key": "Public.cart.clearConfirm",
"key": "Public.basket.clearConfirm",
"tr": "Sepetteki tüm ürünleri silmek istediğinizden emin misiniz?",
"en": "Are you sure you want to remove all items from the cart?"
"en": "Are you sure you want to remove all items from the basket?"
},
{
"resourceName": "Platform",
"key": "Public.cart.clear",
"key": "Public.basket.clear",
"tr": "Sepeti Temizle",
"en": "Clear Cart"
"en": "Clear Basket"
},
{
"resourceName": "Platform",
"key": "Public.cart.empty.title",
"key": "Public.basket.empty.title",
"tr": "Sepetiniz boş",
"en": "Your cart is empty"
"en": "Your basket is empty"
},
{
"resourceName": "Platform",
"key": "Public.cart.empty.subtitle",
"key": "Public.basket.empty.subtitle",
"tr": "Ürün eklemek için katalogdan seçim yapın",
"en": "Add products from the catalog"
},
{
"resourceName": "Platform",
"key": "Public.cart.checkout",
"key": "Public.basket.checkout",
"tr": "Ödemeye Geç",
"en": "Proceed to Checkout"
},
@ -8324,15 +8318,15 @@
},
{
"resourceName": "Platform",
"key": "Public.products.addToCart",
"key": "Public.products.addToBasket",
"tr": "Sepete Ekle",
"en": "Add to Cart"
"en": "Add to Basket"
},
{
"resourceName": "Platform",
"key": "Public.products.inCart",
"key": "Public.products.inBasket",
"tr": "Sepette Mevcut",
"en": "Already in Cart"
"en": "Already in Basket"
},
{
"resourceName": "Platform",
@ -11634,12 +11628,6 @@
"tr": "Değiştir",
"en": "Replace"
},
{
"resourceName": "Platform",
"key": "App.Platform.Loading",
"tr": "Yükleniyor...",
"en": "Loading..."
},
{
"resourceName": "Platform",
"key": "App.Platform.FailedtoloadDatasources",
@ -12258,12 +12246,6 @@
"tr": "Farklı filtreler deneyin veya yeni bir kayıt ekleyin.",
"en": "Try different filters or add a new record."
},
{
"resourceName": "Platform",
"key": "App.Platform.Card.Loading",
"tr": "Yükleniyor...",
"en": "Loading..."
},
{
"resourceName": "Platform",
"key": "App.Platform.Card.TotalRecords",
@ -17490,6 +17472,18 @@
"en": "Website",
"tr": "Web Sitesi"
},
{
"resourceName": "Platform",
"key": "App.WebSite.PatternError",
"en": "Invalid website URL",
"tr": "Geçersiz web sitesi adresi"
},
{
"resourceName": "Platform",
"key": "App.Email.PatternError",
"en": "Invalid email address",
"tr": "Geçersiz email adresi"
},
{
"resourceName": "Platform",
"key": "App.Listform.ListformField.Wednesday",
@ -18306,12 +18300,6 @@
"en": "Select icon...",
"tr": "İkon seç..."
},
{
"resourceName": "Platform",
"key": "ListForms.Wizard.Step2.Loading",
"en": "Loading...",
"tr": "Yükleniyor..."
},
{
"resourceName": "Platform",
"key": "ListForms.Wizard.Step2.SelectKeyColumn",
@ -18642,12 +18630,6 @@
"en": "e.g. Product, User, Order",
"tr": "örn. Product, User, Order"
},
{
"resourceName": "Platform",
"key": "App.SqlQueryManager.Loading",
"en": "Loading...",
"tr": "Yükleniyor..."
},
{
"resourceName": "Platform",
"key": "App.SqlQueryManager.LoadingFkConstraints",
@ -18912,12 +18894,6 @@
"en": "Data source of the CRUD endpoints",
"tr": "CRUD endpointlerinin veri kaynağı"
},
{
"resourceName": "Platform",
"key": "App.DeveloperKit.CrudEndpoints.Loading",
"en": "Loading...",
"tr": "Yükleniyor..."
},
{
"resourceName": "Platform",
"key": "App.DeveloperKit.CrudEndpoints.SearchTable",

View file

@ -509,132 +509,11 @@
"IsDisabled": false,
"ShortName": "Sas"
},
{
"ParentCode": "App.Saas",
"Code": "App.Public",
"DisplayName": "App.Public",
"Order": 1,
"Url": null,
"Icon": "FcTemplate",
"RequiredPermissionName": null,
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Home",
"DisplayName": "App.Home",
"Order": 0,
"Url": "/admin/public/home/designer",
"Icon": "FcHome",
"RequiredPermissionName": "App.Home",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.About",
"DisplayName": "App.About",
"Order": 1,
"Url": "/admin/public/about/designer",
"Icon": "FcAbout",
"RequiredPermissionName": "App.About",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Services",
"DisplayName": "App.Services",
"Order": 2,
"Url": "/admin/public/services/designer",
"Icon": "FcServices",
"RequiredPermissionName": "App.Services",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.Products",
"DisplayName": "App.Orders.Products",
"Order": 3,
"Url": "/admin/list/App.Orders.Products",
"Icon": "FcDiploma1",
"RequiredPermissionName": "App.Orders.Products",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.PaymentMethods",
"DisplayName": "App.Orders.PaymentMethods",
"Order": 4,
"Url": "/admin/list/App.Orders.PaymentMethods",
"Icon": "FcFeedIn",
"RequiredPermissionName": "App.Orders.PaymentMethods",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.InstallmentOptions",
"DisplayName": "App.Orders.InstallmentOptions",
"Order": 5,
"Url": "/admin/list/App.Orders.InstallmentOptions",
"Icon": "FcProcess",
"RequiredPermissionName": "App.Orders.InstallmentOptions",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.SalesOrders",
"DisplayName": "App.Orders.SalesOrders",
"Order": 6,
"Url": "/admin/list/App.Orders.SalesOrders",
"Icon": "FcCollect",
"RequiredPermissionName": "App.Orders.SalesOrders",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.BlogManagement.Category",
"DisplayName": "App.BlogManagement.Category",
"Order": 7,
"Url": "/admin/list/App.BlogManagement.Category",
"Icon": "FaCertificate",
"RequiredPermissionName": "App.BlogManagement.Category",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.BlogManagement.Posts",
"DisplayName": "App.BlogManagement.Posts",
"Order": 8,
"Url": "/admin/list/App.BlogManagement.Posts",
"Icon": "FaWeixin",
"RequiredPermissionName": "App.BlogManagement.Posts",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Demos",
"DisplayName": "App.Demos",
"Order": 9,
"Url": "/admin/list/App.Demos",
"Icon": "FcMissedCall",
"RequiredPermissionName": "App.Demos",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Contact",
"DisplayName": "App.Contact",
"Order": 10,
"Url": "/admin/public/contact/designer",
"Icon": "FcContacts",
"RequiredPermissionName": "App.Contact",
"IsDisabled": false
},
{
"ParentCode": "App.Saas",
"Code": "App.Saas.Definitions",
"DisplayName": "App.Definitions",
"Order": 2,
"Order": 1,
"Url": null,
"Icon": "FcFilingCabinet",
"RequiredPermissionName": null,
@ -750,7 +629,126 @@
"RequiredPermissionName": "App.Definitions.Sequence",
"IsDisabled": false
},
{
"ParentCode": "App.Saas",
"Code": "App.Public",
"DisplayName": "App.Public",
"Order": 2,
"Url": null,
"Icon": "FcTemplate",
"RequiredPermissionName": null,
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Home",
"DisplayName": "App.Home",
"Order": 0,
"Url": "/admin/public/home/designer",
"Icon": "FcHome",
"RequiredPermissionName": "App.Home",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.About",
"DisplayName": "App.About",
"Order": 1,
"Url": "/admin/public/about/designer",
"Icon": "FcAbout",
"RequiredPermissionName": "App.About",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Services",
"DisplayName": "App.Services",
"Order": 2,
"Url": "/admin/public/services/designer",
"Icon": "FcServices",
"RequiredPermissionName": "App.Services",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.Products",
"DisplayName": "App.Orders.Products",
"Order": 3,
"Url": "/admin/list/App.Orders.Products",
"Icon": "FcDiploma1",
"RequiredPermissionName": "App.Orders.Products",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.PaymentMethods",
"DisplayName": "App.Orders.PaymentMethods",
"Order": 4,
"Url": "/admin/list/App.Orders.PaymentMethods",
"Icon": "FcFeedIn",
"RequiredPermissionName": "App.Orders.PaymentMethods",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.InstallmentOptions",
"DisplayName": "App.Orders.InstallmentOptions",
"Order": 5,
"Url": "/admin/list/App.Orders.InstallmentOptions",
"Icon": "FcProcess",
"RequiredPermissionName": "App.Orders.InstallmentOptions",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Orders.SalesOrders",
"DisplayName": "App.Orders.SalesOrders",
"Order": 6,
"Url": "/admin/list/App.Orders.SalesOrders",
"Icon": "FcCollect",
"RequiredPermissionName": "App.Orders.SalesOrders",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.BlogManagement.Category",
"DisplayName": "App.BlogManagement.Category",
"Order": 7,
"Url": "/admin/list/App.BlogManagement.Category",
"Icon": "FaCertificate",
"RequiredPermissionName": "App.BlogManagement.Category",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.BlogManagement.Posts",
"DisplayName": "App.BlogManagement.Posts",
"Order": 8,
"Url": "/admin/list/App.BlogManagement.Posts",
"Icon": "FaWeixin",
"RequiredPermissionName": "App.BlogManagement.Posts",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Demos",
"DisplayName": "App.Demos",
"Order": 9,
"Url": "/admin/list/App.Demos",
"Icon": "FcMissedCall",
"RequiredPermissionName": "App.Demos",
"IsDisabled": false
},
{
"ParentCode": "App.Public",
"Code": "App.Contact",
"DisplayName": "App.Contact",
"Order": 10,
"Url": "/admin/public/contact/designer",
"Icon": "FcContacts",
"RequiredPermissionName": "App.Contact",
"IsDisabled": false
},
{
"ParentCode": "App.Saas",
"Code": "AbpTenantManagement.Tenants",
@ -1043,21 +1041,11 @@
"IsDisabled": false,
"ShortName": "Adm"
},
{
"ParentCode": "App.Administration",
"Code": "App.Setting",
"DisplayName": "App.Setting",
"Order": 1,
"Url": "/admin/settings",
"Icon": "FcSettings",
"RequiredPermissionName": "App.Setting",
"IsDisabled": false
},
{
"ParentCode": "App.Administration",
"Code": "App.Administration.Definitions",
"DisplayName": "App.Definitions",
"Order": 2,
"Order": 1,
"Url": null,
"Icon": "FcFilingCabinet",
"RequiredPermissionName": null,
@ -1103,6 +1091,16 @@
"RequiredPermissionName": "App.Definitions.OrgChart",
"IsDisabled": false
},
{
"ParentCode": "App.Administration",
"Code": "App.Setting",
"DisplayName": "App.Setting",
"Order": 2,
"Url": "/admin/settings",
"Icon": "FcSettings",
"RequiredPermissionName": "App.Setting",
"IsDisabled": false
},
{
"ParentCode": "App.Administration",
"Code": "App.Administration.Intranet",

View file

@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SQLitePCLRaw.lib.e_sqlite3" Version="3.53.3" />
<ProjectReference Include="..\..\src\Sozsoft.Platform.EntityFrameworkCore\Sozsoft.Platform.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\Sozsoft.Platform.TestBase\Sozsoft.Platform.TestBase.csproj" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.Sqlite" Version="10.0.0" />

334
ui/package-lock.json generated
View file

@ -90,7 +90,7 @@
"postcss": "^8.4.21",
"prettier": "^3.1.1",
"tailwindcss": "^3.4.17",
"typescript": "^4.9.3",
"typescript": "5.9",
"vite": "^7.3.6",
"vite-plugin-pwa": "^1.3.0"
}
@ -3859,6 +3859,189 @@
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz",
"integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1",
"@typescript-eslint/utils": "8.62.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz",
"integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.62.1",
"@typescript-eslint/tsconfig-utils": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/project-service": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz",
"integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.62.1",
"@typescript-eslint/types": "^8.62.1",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz",
"integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz",
"integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz",
"integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.62.1",
"@typescript-eslint/tsconfig-utils": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/project-service": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz",
"integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.62.1",
"@typescript-eslint/types": "^8.62.1",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz",
"integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.1.tgz",
@ -3884,7 +4067,35 @@
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/project-service": {
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz",
"integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.62.1",
"@typescript-eslint/tsconfig-utils": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/project-service": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.1.tgz",
"integrity": "sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==",
@ -3906,6 +4117,23 @@
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz",
"integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.1.tgz",
@ -3924,48 +4152,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.1.tgz",
"integrity": "sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.1.tgz",
"integrity": "sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1",
"@typescript-eslint/utils": "8.62.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.1.tgz",
@ -3980,58 +4166,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.1.tgz",
"integrity": "sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.62.1",
"@typescript-eslint/tsconfig-utils": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/visitor-keys": "8.62.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.1.tgz",
"integrity": "sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.62.1",
"@typescript-eslint/types": "8.62.1",
"@typescript-eslint/typescript-estree": "8.62.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.62.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.1.tgz",
@ -12756,9 +12890,9 @@
}
},
"node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@ -12766,7 +12900,7 @@
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
"node": ">=14.17"
}
},
"node_modules/unbox-primitive": {

View file

@ -39,10 +39,10 @@
"dayjs": "^1.11.13",
"devexpress-reporting-react": "^25.2.3",
"devextreme": "^25.2.3",
"devextreme-exceljs-fork": "^4.4.11",
"devextreme-react": "^25.2.3",
"easy-peasy": "^6.0.5",
"emoji-picker-react": "^4.14.1",
"devextreme-exceljs-fork": "^4.4.11",
"file-saver": "^2.0.2",
"formik": "^2.4.6",
"framer-motion": "^11.15.0",
@ -65,6 +65,7 @@
"yup": "^1.6.1"
},
"devDependencies": {
"@eslint/js": "^9.39.0",
"@tailwindcss/typography": "^0.5.15",
"@types/babel__standalone": "^7.1.9",
"@types/file-saver": "^2.0.7",
@ -75,7 +76,6 @@
"@types/react-helmet": "^6.1.9",
"@types/react-highlight-words": "^0.16.4",
"@types/react-modal": "^3.13.1",
"@eslint/js": "^9.39.0",
"@typescript-eslint/eslint-plugin": "^8.62.1",
"@typescript-eslint/parser": "^8.62.1",
"@vitejs/plugin-react": "^4.2.1",
@ -98,7 +98,7 @@
"postcss": "^8.4.21",
"prettier": "^3.1.1",
"tailwindcss": "^3.4.17",
"typescript": "^4.9.3",
"typescript": "5.9",
"vite": "^7.3.6",
"vite-plugin-pwa": "^1.3.0"
},

View file

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import classNames from "classnames";
import { iconList } from "./iconList";
import { iconList } from "../../utils/iconList";
export type colorType =
| "blue"

View file

@ -213,7 +213,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
const getSessionStatusLabel = (status: string) => {
switch (status) {
case 'uploading':
return translate('::App.Listforms.ImportManager.Uploading')
return translate('::App.Uploading')
case 'validating':
return translate('::App.Listforms.ImportManager.Validating')
case 'processing':

View file

@ -4,7 +4,7 @@ import { BillingCycle, BasketItem } from '@/proxy/order/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Button } from '@/components/ui'
interface CartState {
interface BasketData {
items: BasketItem[]
subtotal: number
vatTotal: number
@ -13,30 +13,30 @@ interface CartState {
globalPeriod: number
}
interface CartProps {
interface BasketProps {
isOpen: boolean
onClose: () => void
onCheckout: () => void
cartState: CartState
basketData: BasketData
updateQuantity: (id: string, quantity: number) => void
removeItem: (id: string) => void
clearCart: () => void
clearBasket: () => void
}
export const Cart: React.FC<CartProps> = ({
export const Basket: React.FC<BasketProps> = ({
isOpen,
onClose,
onCheckout,
cartState,
basketData,
updateQuantity,
removeItem,
clearCart,
clearBasket,
}) => {
const { translate } = useLocalization()
const handleClearCart = () => {
const handleClearBasket = () => {
if (window.confirm('Sepetteki tüm ürünleri silmek istediğinizden emin misiniz?')) {
clearCart()
clearBasket()
}
}
@ -58,17 +58,17 @@ export const Cart: React.FC<CartProps> = ({
<div className="flex flex-col h-full">
<div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
<h2 className="text-base font-semibold text-gray-900 dark:text-gray-100">
{translate('::Public.cart.title')}
{translate('::Public.basket.title')}
</h2>
<div className="flex items-center space-x-2">
{cartState.items.length > 0 && (
{basketData.items.length > 0 && (
<Button
onClick={handleClearCart}
onClick={handleClearBasket}
icon={<FaTrash className="w-3 h-3" />}
variant="twoTone"
color="red-600"
size="xs"
title={translate('::Public.cart.clear')}
title={translate('::Public.basket.clear')}
/>
)}
<Button
@ -81,15 +81,15 @@ export const Cart: React.FC<CartProps> = ({
</div>
<div className="flex-1 overflow-y-auto p-6">
{cartState.items.length === 0 ? (
{basketData.items.length === 0 ? (
<div className="flex flex-col items-center justify-center h-full text-gray-500 dark:text-gray-400">
<FaShoppingBag className="w-16 h-16 mb-4" />
<p className="text-lg font-medium">{translate('::Public.cart.empty.title')}</p>
<p className="text-sm">{translate('::Public.cart.empty.subtitle')}</p>
<p className="text-lg font-medium">{translate('::Public.basket.empty.title')}</p>
<p className="text-sm">{translate('::Public.basket.empty.subtitle')}</p>
</div>
) : (
<div className="space-y-4">
{cartState.items.map((item: BasketItem, index: number) => (
{basketData.items.map((item: BasketItem, index: number) => (
<div
key={`${item.product.id}-${item.billingCycle}-${index}`}
className="border border-gray-200 rounded-lg p-4 dark:border-gray-700 dark:bg-gray-950"
@ -120,9 +120,9 @@ export const Cart: React.FC<CartProps> = ({
: item.billingCycle === 'yearly'
? translate('::Public.products.billingcycle.yearly')
: translate('::Public.products.billingcycle.monthly')}
{cartState.globalPeriod > 1 && item.product.isQuantityBased && (
{basketData.globalPeriod > 1 && item.product.isQuantityBased && (
<span className="text-xs text-gray-500 dark:text-gray-400">
({cartState.globalPeriod}{' '}
({basketData.globalPeriod}{' '}
{item.billingCycle === 'monthly'
? translate('::Public.products.billingcycle.month')
: translate('::Public.products.billingcycle.year')}
@ -161,29 +161,29 @@ export const Cart: React.FC<CartProps> = ({
)}
</div>
{cartState.items.length > 0 && (
{basketData.items.length > 0 && (
<div className="border-t border-gray-200 p-6 dark:border-gray-700">
<div className="space-y-2 mb-4">
<div className="flex justify-between text-sm text-gray-600 dark:text-gray-300">
<span>{translate('::App.Listform.ListformField.Subtotal')}</span>
<span>{formatPrice(cartState.subtotal)}</span>
<span>{formatPrice(basketData.subtotal)}</span>
</div>
<div className="flex justify-between text-sm text-gray-600 dark:text-gray-300">
<span>{translate('::Public.products.kdv')}</span>
<span>{formatPrice(cartState.vatTotal)}</span>
<span>{formatPrice(basketData.vatTotal)}</span>
</div>
<div className="flex justify-between items-center pt-2 border-t border-gray-200 dark:border-gray-700">
<span className="text-lg font-semibold text-gray-900 dark:text-gray-100">
{translate('::App.Listform.ListformField.Total')}
</span>
<span className="text-xl font-bold text-blue-600">
{formatPrice(cartState.total)}
{formatPrice(basketData.total)}
</span>
</div>
</div>
<Button onClick={onCheckout} block variant="solid" size="md">
{translate('::Public.cart.checkout')}
{translate('::Public.basket.checkout')}
</Button>
</div>
)}

View file

@ -1,7 +1,7 @@
import React from 'react'
import { FaCalendar, FaClock, FaMinus, FaPlus, FaShoppingCart } from 'react-icons/fa'
import { BillingCycle } from '@/proxy/order/models'
import { CartState } from '@/utils/cartUtils'
import { BasketData } from '@/utils/basketUtils'
import { useScroll } from '@/contexts/ScrollContext'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Button } from '@/components/ui'
@ -11,10 +11,10 @@ interface BillingControlsProps {
globalPeriod: number
setGlobalBillingCycle: (cycle: BillingCycle) => void
setGlobalPeriod: (period: number) => void
onCartClick: () => void
onBasketClick: () => void
onNavigate: (section: string) => void
cartItemsCount: number
cartState: CartState
basketItemsCount: number
basketData: BasketData
}
export const BillingControls: React.FC<BillingControlsProps> = ({
@ -22,11 +22,11 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
globalPeriod,
setGlobalBillingCycle,
setGlobalPeriod,
onCartClick,
cartItemsCount,
cartState,
onBasketClick,
basketItemsCount,
basketData,
}) => {
const hasCartItems = cartState.items.length > 0
const hasBasketItems = basketData.items.length > 0
const isScrolled = useScroll()
const { translate } = useLocalization()
@ -48,25 +48,25 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
<div className="flex space-x-2">
<Button
onClick={() => !hasCartItems && setGlobalBillingCycle('monthly')}
disabled={hasCartItems}
onClick={() => !hasBasketItems && setGlobalBillingCycle('monthly')}
disabled={hasBasketItems}
variant={globalBillingCycle === 'monthly' ? 'solid' : 'default'}
size="xs"
className={globalBillingCycle === 'monthly' ? 'shadow-md' : ''}
title={
hasCartItems ? 'Sepette ürün varken faturalama döngüsü değiştirilemez' : undefined
hasBasketItems ? 'Sepette ürün varken faturalama döngüsü değiştirilemez' : undefined
}
>
{translate('::Public.products.billingcycle.monthly')}
</Button>
<Button
onClick={() => !hasCartItems && setGlobalBillingCycle('yearly')}
disabled={hasCartItems}
onClick={() => !hasBasketItems && setGlobalBillingCycle('yearly')}
disabled={hasBasketItems}
variant={globalBillingCycle === 'yearly' ? 'solid' : 'default'}
size="xs"
className={globalBillingCycle === 'yearly' ? 'shadow-md' : ''}
title={
hasCartItems ? 'Sepette ürün varken faturalama döngüsü değiştirilemez' : undefined
hasBasketItems ? 'Sepette ürün varken faturalama döngüsü değiştirilemez' : undefined
}
>
{translate('::Public.products.billingcycle.yearly')}
@ -85,12 +85,12 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
<div className="flex items-center space-x-2">
<Button
onClick={() => !hasCartItems && setGlobalPeriod(Math.max(1, globalPeriod - 1))}
disabled={globalPeriod <= 1 || hasCartItems}
onClick={() => !hasBasketItems && setGlobalPeriod(Math.max(1, globalPeriod - 1))}
disabled={globalPeriod <= 1 || hasBasketItems}
icon={<FaMinus className="w-4 h-4" />}
variant="default"
size="xs"
title={hasCartItems ? 'Sepette ürün varken periyod değiştirilemez' : undefined}
title={hasBasketItems ? 'Sepette ürün varken periyod değiştirilemez' : undefined}
/>
<div className="flex items-center space-x-2 bg-gray-50 px-2 py-1 rounded-lg dark:bg-gray-800">
@ -103,18 +103,18 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
</div>
<Button
onClick={() => !hasCartItems && setGlobalPeriod(globalPeriod + 1)}
disabled={hasCartItems}
onClick={() => !hasBasketItems && setGlobalPeriod(globalPeriod + 1)}
disabled={hasBasketItems}
icon={<FaPlus className="w-4 h-4" />}
variant="default"
size="xs"
title={hasCartItems ? 'Sepette ürün varken periyod değiştirilemez' : undefined}
title={hasBasketItems ? 'Sepette ürün varken periyod değiştirilemez' : undefined}
/>
</div>
</div>
<Button
onClick={onCartClick}
onClick={onBasketClick}
icon={<FaShoppingCart className="w-3 h-3" />}
variant="solid"
color="green-600"
@ -123,9 +123,9 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
>
<span className="font-medium text-sm">{translate('::Public.nav.basket')}</span>
{cartItemsCount > 0 && (
{basketItemsCount > 0 && (
<span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center font-bold">
{cartItemsCount}
{basketItemsCount}
</span>
)}
</Button>

View file

@ -11,7 +11,7 @@ import { CustomTenantDto } from '@/proxy/config/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Button } from '@/components/ui'
interface CartState {
interface BasketData {
items: BasketItem[]
subtotal: number
vatTotal: number
@ -24,10 +24,10 @@ interface PaymentFormProps {
tenant: CustomTenantDto
onBack: () => void
onComplete: (paymentData: Record<string, unknown>) => void
cartState: CartState
basketData: BasketData
}
export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, cartState }) => {
export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, basketData }) => {
const defaultPaymentMethod = 'Kredi Kartı'
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<string>(defaultPaymentMethod)
const [selectedInstallment, setSelectedInstallment] = useState<InstallmentOptionDto>()
@ -72,14 +72,14 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ca
let commission = 0
if (selectedPaymentMethod === defaultPaymentMethod && selectedInstallment) {
commission = cartState.total * selectedInstallment.commission
commission = basketData.total * selectedInstallment.commission
} else if (selectedMethod) {
commission = cartState.total * selectedMethod.commission
commission = basketData.total * selectedMethod.commission
}
const finalTotal = cartState.total + commission
const period = cartState.globalPeriod > 0 ? cartState.globalPeriod : 1
const billingCycle = cartState.globalBillingCycle || 'yearly'
const finalTotal = basketData.total + commission
const period = basketData.globalPeriod > 0 ? basketData.globalPeriod : 1
const billingCycle = basketData.globalBillingCycle || 'yearly'
const licenseEndTime = calculateLicenseEndTime(new Date(licenseStartTime), billingCycle, period)
const formatPrice = (price: number) =>
@ -91,7 +91,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ca
const vatRateLabel = (() => {
const rates = Array.from(
new Set(cartState.items.map((item) => Math.round((item.vatRate ?? 0) * 100))),
new Set(basketData.items.map((item) => Math.round((item.vatRate ?? 0) * 100))),
).filter((rate) => rate > 0)
return rates.length > 0 ? ` (${rates.map((rate) => `%${rate}`).join(', ')})` : ''
@ -290,7 +290,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ca
</div>
<div className="font-extrabold text-lg text-gray-900 dark:text-gray-100 mt-1">
{formatPrice(
(cartState.total + cartState.total * option.commission) /
(basketData.total + basketData.total * option.commission) /
option.installment,
)}
</div>
@ -356,7 +356,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ca
</h3>
<div className="space-y-4 mb-4">
{cartState.items.map((item, index) => (
{basketData.items.map((item, index) => (
<div key={`${item.product.id}-${index}`} className="text-sm">
<div className="flex items-center justify-between gap-4">
<div className="flex min-w-0 items-center gap-3">
@ -387,11 +387,11 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ca
<div className="space-y-1 text-sm border-t border-gray-200 dark:border-gray-700 pt-4 text-gray-600 dark:text-gray-300">
<div className="flex justify-between">
<span>{translate('::Public.payment.summary.subtotal')}</span>
<span>{formatPrice(cartState.subtotal)}</span>
<span>{formatPrice(basketData.subtotal)}</span>
</div>
<div className="flex justify-between">
<span>{translate('::Public.products.kdv')}{vatRateLabel}</span>
<span>{formatPrice(cartState.vatTotal)}</span>
<span>{formatPrice(basketData.vatTotal)}</span>
</div>
<div className="flex justify-between">
<span>{translate('::Public.payment.installments.commission')}</span>

View file

@ -1,7 +1,7 @@
import React, { useState } from 'react'
import { FaPlus, FaMinus } from 'react-icons/fa'
import { BillingCycle, ProductDto } from '@/proxy/order/models'
import { CartState } from '@/utils/cartUtils'
import { BasketData } from '@/utils/basketUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Button } from '@/components/ui'
@ -10,7 +10,7 @@ interface ProductCardProps {
globalBillingCycle: BillingCycle
globalPeriod: number
addItem: (product: ProductDto, quantity: number, billingCycle: BillingCycle) => void
cartState: CartState
basketData: BasketData
}
export const ProductCard: React.FC<ProductCardProps> = ({
@ -18,13 +18,12 @@ export const ProductCard: React.FC<ProductCardProps> = ({
globalBillingCycle,
globalPeriod,
addItem,
cartState,
basketData,
}) => {
const [quantity, setQuantity] = useState(1)
const { translate } = useLocalization()
// Direct check with current cart state
const isInCart = cartState.items.some(
const isInBasket = basketData.items.some(
(item) => item.product.id === product.id && item.billingCycle === globalBillingCycle,
)
@ -54,13 +53,11 @@ export const ProductCard: React.FC<ProductCardProps> = ({
return getTotalPrice() + getVatAmount()
}
const handleAddToCart = () => {
// Non-quantity products should not be added if already in cart
if (!product.isQuantityBased && isInCart) {
const handleAddToBasket = () => {
if (!product.isQuantityBased && isInBasket) {
return
}
// For non-quantity products, always use quantity 1
const quantityToAdd = !product.isQuantityBased ? 1 : quantity
addItem(product, quantityToAdd, globalBillingCycle)
setQuantity(1)
@ -180,18 +177,18 @@ export const ProductCard: React.FC<ProductCardProps> = ({
{(() => {
const isNonQuantityProduct = !product.isQuantityBased
const isDisabled = isNonQuantityProduct && isInCart
const isDisabled = isNonQuantityProduct && isInBasket
return (
<Button
onClick={handleAddToCart}
onClick={handleAddToBasket}
disabled={isDisabled}
block
variant="solid"
size="md"
className={!isDisabled ? 'hover:scale-[1.02] active:scale-[0.98]' : ''}
>
{isDisabled ? translate('::Public.products.inCart') : translate('::Public.products.addToCart')}
{isDisabled ? translate('::Public.products.inBasket') : translate('::Public.products.addToBasket')}
</Button>
)
})()}

View file

@ -1,7 +1,7 @@
import React, { useState, useMemo, useEffect } from 'react'
import { FaFilter, FaSearch } from 'react-icons/fa'
import { ProductCard } from './ProductCard'
import { addItemToCart, CartState } from '@/utils/cartUtils'
import { addItemToBasket, BasketData } from '@/utils/basketUtils'
import { BillingCycle, ProductDto } from '@/proxy/order/models'
import { OrderService } from '@/services/order.service'
import { useLocalization } from '@/utils/hooks/useLocalization'
@ -11,15 +11,15 @@ import { Button } from '@/components/ui'
interface ProductCatalogProps {
searchQuery: string
onSearchChange: (query: string) => void
cartState: CartState
setCartState: React.Dispatch<React.SetStateAction<CartState>>
basketData: BasketData
setBasketData: React.Dispatch<React.SetStateAction<BasketData>>
}
export const ProductCatalog: React.FC<ProductCatalogProps> = ({
searchQuery,
onSearchChange,
cartState,
setCartState,
basketData,
setBasketData,
}) => {
const { translate } = useLocalization()
@ -45,24 +45,24 @@ export const ProductCatalog: React.FC<ProductCatalogProps> = ({
}, [])
const handleAddItem = (product: ProductDto, quantity: number, billingCycle: BillingCycle) => {
setCartState((currentState) => addItemToCart(currentState, product, quantity, billingCycle))
setBasketData((currentState) => addItemToBasket(currentState, product, quantity, billingCycle))
}
const availableProducts = useMemo(() => {
return products.filter((product) => {
// If monthly billing is selected, only show products with monthlyPrice
if (cartState.globalBillingCycle === 'monthly') {
if (basketData.globalBillingCycle === 'monthly') {
return product.monthlyPrice !== undefined
}
// If yearly billing is selected, only show products with yearlyPrice
if (cartState.globalBillingCycle === 'yearly') {
if (basketData.globalBillingCycle === 'yearly') {
return product.yearlyPrice !== undefined
}
return true
})
}, [products, cartState.globalBillingCycle])
}, [products, basketData.globalBillingCycle])
const categories = useMemo(() => {
const cats = ['all', ...new Set(availableProducts.map((p) => p.category))]
@ -161,10 +161,10 @@ export const ProductCatalog: React.FC<ProductCatalogProps> = ({
<ProductCard
key={product.id}
product={product}
globalBillingCycle={cartState.globalBillingCycle}
globalPeriod={cartState.globalPeriod}
globalBillingCycle={basketData.globalBillingCycle}
globalPeriod={basketData.globalPeriod}
addItem={handleAddItem}
cartState={cartState}
basketData={basketData}
/>
))}
</div>

View file

@ -40,6 +40,7 @@ interface LocationOption<T> {
}
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const WEBSITE_PATTERN = /^(https?:\/\/)?(www\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/[^\s]*)?$/
const DEFAULT_PHONE_FORMAT = '000 000 000 000 000'
const TURKEY_PHONE_FORMAT = '(000) 000-0000'
const REQUIRED_NEW_CUSTOMER_FIELDS: Array<keyof CustomTenantDto> = [
@ -185,6 +186,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
const [isLoadingDistricts, setIsLoadingDistricts] = useState(false)
const [isLoadingTenant, setIsLoadingTenant] = useState(false)
const [emailError, setEmailError] = useState('')
const [websiteError, setWebsiteError] = useState('')
const [phoneError, setPhoneError] = useState('')
const [existingTenantError, setExistingTenantError] = useState('')
const [formError, setFormError] = useState('')
@ -355,6 +357,11 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
hasValidationError = true
}
if (!isExisting && !WEBSITE_PATTERN.test(formData.website || '')) {
setWebsiteError('Lütfen geçerli bir web sitesi adresi girin.')
hasValidationError = true
}
if (hasValidationError) return
onSubmit({
...formData,
@ -391,6 +398,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
setExistingTenantError('')
setFormError('')
setEmailError('')
setWebsiteError('')
setPhoneError('')
setDistricts([])
setFormData(nextIsExisting ? {} : getDefaultNewCustomerData())
@ -963,7 +971,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
setEmailError(
EMAIL_PATTERN.test(e.target.value)
? ''
: 'Lütfen geçerli bir e-posta adresi girin.',
: translate('::App.Email.PatternError'),
)
}
}}
@ -971,7 +979,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
setEmailError(
EMAIL_PATTERN.test(formData.email || '')
? ''
: 'Lütfen geçerli bir e-posta adresi girin.',
: translate('::App.Email.PatternError'),
)
}
aria-invalid={Boolean(emailError)}
@ -1001,7 +1009,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
<input
type="text"
required
placeholder="Kozyatağı"
placeholder="Sarıgazi"
value={formData.taxOffice}
onChange={(e) => handleInputChange('taxOffice', e.target.value)}
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
@ -1038,10 +1046,37 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
required
placeholder={translate('::Public.payment.customer.website')}
value={formData.website || ''}
onChange={(e) => handleInputChange('website', e.target.value)}
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
onChange={(e) => {
handleInputChange('website', e.target.value)
if (websiteError) {
setWebsiteError(
WEBSITE_PATTERN.test(e.target.value)
? ''
: translate('::App.WebSite.PatternError'),
)
}
}}
onBlur={() =>
setWebsiteError(
WEBSITE_PATTERN.test(formData.website || '')
? ''
: translate('::App.WebSite.PatternError'),
)
}
aria-invalid={Boolean(websiteError)}
aria-describedby={websiteError ? 'tenant-website-error' : undefined}
className={`w-full pl-10 pr-4 py-2 border rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
websiteError
? 'border-red-500 dark:border-red-500'
: 'border-gray-300 dark:border-gray-700'
}`}
/>
</div>
{websiteError && (
<p id="tenant-website-error" className="mt-1 text-sm text-red-600">
{websiteError}
</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">

View file

@ -6,7 +6,7 @@ import useDarkMode from '@/utils/hooks/useDarkmode'
import useNotification from '@/utils/hooks/useNotification'
import { useSetting } from '@/utils/hooks/useSetting'
import useTabFocus from '@/utils/hooks/useTabFocus'
import { useEffect } from 'react'
import { ComponentProps, useEffect } from 'react'
import { Helmet } from 'react-helmet'
import { useNavigate, useLocation } from 'react-router-dom'
import { getSetupStatus } from '@/services/setup.service'
@ -15,7 +15,6 @@ import { ROUTES_ENUM } from '@/routes/route.constant'
let didInit = false
const Theme = (props: CommonProps) => {
// ABP App Config'i uygulama acilirken al
const { getConfig } = useStoreActions((a) => a.abpConfig)
const { setSetupMode } = useStoreActions((a) => a.base.common)
const navigate = useNavigate()
@ -57,18 +56,20 @@ const Theme = (props: CommonProps) => {
const { setting } = useSetting()
const theme = useStoreState((state) => state.theme)
const locale = useStoreState(
(state) => state.abpConfig.config?.localization.currentCulture.cultureName,
)
const locale =
useStoreState((state) => state.abpConfig.config?.localization.currentCulture.cultureName) ??
'en'
useDarkMode()
useTabFocus()
useNotification()
type ConfigProviderValue = NonNullable<ComponentProps<typeof ConfigProvider>['value']>
const currentTheme = {
...themeConfig,
...theme,
...{ locale },
}
} as ConfigProviderValue
return (
<>

View file

@ -106,8 +106,7 @@ const DropdownItem = forwardRef<HTMLElement, DropdownItemProps>(
openSubmenuIfExists()
} else {
activate(e)
// Close the current menu after activation
menuControl?.closeMenu()
menuControl?.closeMenu?.()
}
},
[disabled, submenu, openSubmenuIfExists, activate, menuControl]

View file

@ -1,4 +1,4 @@
import { createContext, useState, useRef, useCallback } from 'react'
import React, { createContext, useState, useRef, useCallback } from 'react'
import isNil from 'lodash/isNil'
type Item = {
@ -12,6 +12,7 @@ type DropdownMenuContextProps = {
props: { disabled?: boolean }
) => void
unregisterItem?: (id: string) => void
closeMenu?: () => void
}
const DropdownMenuContext = createContext<DropdownMenuContextProps>({})

View file

@ -1,4 +1,4 @@
import {
import React, {
forwardRef,
useState,
useRef,
@ -266,6 +266,7 @@ const Slider = forwardRef<HTMLDivElement, SliderProps>((props, ref) => {
const resolvedMarks = marks === true
? Array.from({ length: Math.floor((max - min) / step) + 1 }, (_, i) => ({
value: min + i * step,
label: `${min + i * step}`,
}))
: Array.isArray(marks)
? marks

View file

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import React, { useEffect, useState } from 'react'
import classNames from 'classnames'
import { iconList } from './iconList'
import { iconList } from '@/utils/iconList'
export type colorType =
| 'blue'

File diff suppressed because it is too large Load diff

View file

@ -66,14 +66,14 @@ export const getMessengerMessages = (data: MessengerGetMessagesInput) =>
apiService.fetchData<MessengerMessageDto[]>({
method: 'POST',
url: '/api/app/messenger/messages',
data,
data: data as any,
})
export const sendMessengerMessage = (data: MessengerSendMessageDto) =>
apiService.fetchData<MessengerMessageDto>({
method: 'POST',
url: '/api/app/messenger/send-message',
data,
data: data as any,
})
export const deleteMessengerMessage = (messageId: string) =>
@ -89,6 +89,6 @@ export const uploadMessengerAttachment = (file: File) => {
return apiService.fetchData<MessengerAttachmentDto>({
method: 'POST',
url: '/api/app/messenger/upload-attachment',
data: formData,
data: formData as any,
})
}

View file

@ -1,24 +0,0 @@
// scripts/tenant.ts
import axios from 'axios'
import https from 'https'
// import fs from 'fs'
export type TenantDto = { name: string }
export type PagedResultDto<T> = { totalCount: number; items: T[] }
export async function fetchTenantNames(apiUrl: string): Promise<string[]> {
try {
const url = `${apiUrl.replace(/\/$/, '')}/api/app/platform-tenant?skipCount=0&maxResultCount=1000`
const isLocalHttps = /^https:\/\/localhost(:\d+)?/i.test(apiUrl)
const { data } = await axios.get<PagedResultDto<TenantDto>>(url, {
headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
httpsAgent: isLocalHttps ? new https.Agent({ rejectUnauthorized: false }) : undefined,
})
return (data.items ?? []).map((t) => t.name.trim().toLowerCase())
} catch (e) {
console.error('[vite] Tenant listesi alınamadı:', e)
return []
}
}

View file

@ -3,7 +3,7 @@ import { action } from 'easy-peasy'
import type { CustomTenantDto } from '@/proxy/config/models'
import type { OrderDto } from '@/proxy/order/models'
import type { FileItem } from '@/types/fileManagement'
import { initialCartState, type CartState } from '../utils/cartUtils'
import { initialBasketData, type BasketData } from '../utils/basketUtils'
export type TenantFormDraft = Partial<CustomTenantDto> & {
isExisting?: boolean
@ -36,14 +36,14 @@ export interface DeveloperKitState {
}
export interface ClientStoreModel {
cartState: CartState
basketData: BasketData
order: OrderState
fileManager: FileManagerState
developerKit: DeveloperKitState
}
export interface ClientStoreActions {
setCartState: Action<ClientStoreModel, CartState>
setBasketData: Action<ClientStoreModel, BasketData>
order: {
setTenantData: Action<OrderState, CustomTenantDto>
setTenantFormDraft: Action<OrderState, TenantFormDraft>
@ -63,7 +63,7 @@ export interface ClientStoreActions {
export type ClientModel = ClientStoreModel & ClientStoreActions
const initialState: ClientStoreModel = {
cartState: initialCartState,
basketData: initialBasketData,
order: {
tenantData: null,
tenantFormDraft: null,
@ -80,8 +80,8 @@ const initialState: ClientStoreModel = {
export const clientModel: ClientModel = {
...initialState,
setCartState: action((state, payload) => {
state.cartState = payload
setBasketData: action((state, payload) => {
state.basketData = payload
}),
order: {
...initialState.order,

View file

@ -1,6 +1,6 @@
import { BillingCycle, BasketItem, ProductDto } from '@/proxy/order/models'
export interface CartState {
export interface BasketData {
items: BasketItem[]
subtotal: number
vatTotal: number
@ -9,7 +9,7 @@ export interface CartState {
globalPeriod: number
}
export const initialCartState: CartState = {
export const initialBasketData: BasketData = {
items: [],
subtotal: 0,
vatTotal: 0,
@ -52,7 +52,7 @@ const withItemVat = (
}
}
const calculateCartTotals = (items: BasketItem[]) => {
const calculateBasketTotals = (items: BasketItem[]) => {
const total = roundMoney(items.reduce((sum, item) => sum + item.totalPrice, 0))
const vatTotal = roundMoney(items.reduce((sum, item) => sum + (item.vatAmount ?? 0), 0))
return {
@ -62,112 +62,112 @@ const calculateCartTotals = (items: BasketItem[]) => {
}
}
export const addItemToCart = (
cartState: CartState,
export const addItemToBasket = (
basketData: BasketData,
product: ProductDto,
quantity: number,
billingCycle: BillingCycle,
): CartState => {
const isAlreadyInCart = isItemInCartState(cartState.items, product.id, billingCycle)
): BasketData => {
const isAlreadyInBasket = isItemInBasketData(basketData.items, product.id, billingCycle)
if (!product.isQuantityBased && isAlreadyInCart) {
return cartState
if (!product.isQuantityBased && isAlreadyInBasket) {
return basketData
}
const existingItemIndex = cartState.items.findIndex(
const existingItemIndex = basketData.items.findIndex(
(item) => item.product.id === product.id && item.billingCycle === billingCycle,
)
let newItems
if (existingItemIndex > -1) {
newItems = [...cartState.items]
newItems = [...basketData.items]
newItems[existingItemIndex].quantity += quantity
newItems[existingItemIndex] = withItemVat(
product,
newItems[existingItemIndex].quantity,
billingCycle,
cartState.globalPeriod,
basketData.globalPeriod,
)
} else {
const actualQuantity = !product.isQuantityBased ? 1 : quantity
newItems = [
...cartState.items,
withItemVat(product, actualQuantity, billingCycle, cartState.globalPeriod),
...basketData.items,
withItemVat(product, actualQuantity, billingCycle, basketData.globalPeriod),
]
}
const updatedState = { ...cartState, items: newItems, ...calculateCartTotals(newItems) }
const updatedState = { ...basketData, items: newItems, ...calculateBasketTotals(newItems) }
return updatedState
}
export const removeItemFromCart = (cartState: CartState, id: string): CartState => {
const newItems = cartState.items.filter((item) => item.product.id !== id)
const updatedState = { ...cartState, items: newItems, ...calculateCartTotals(newItems) }
export const removeItemFromBasket = (basketData: BasketData, id: string): BasketData => {
const newItems = basketData.items.filter((item) => item.product.id !== id)
const updatedState = { ...basketData, items: newItems, ...calculateBasketTotals(newItems) }
return updatedState
}
export const updateCartItemQuantity = (
cartState: CartState,
export const updateBasketItemQuantity = (
basketData: BasketData,
id: string,
quantity: number,
): CartState => {
const newItems = cartState.items
): BasketData => {
const newItems = basketData.items
.map((item) => {
if (item.product.id === id) {
if (quantity <= 0) return null
if (!item.product.isQuantityBased) return item
return withItemVat(item.product, quantity, item.billingCycle, cartState.globalPeriod)
return withItemVat(item.product, quantity, item.billingCycle, basketData.globalPeriod)
}
return item
})
.filter(Boolean) as BasketItem[]
const updatedState = { ...cartState, items: newItems, ...calculateCartTotals(newItems) }
const updatedState = { ...basketData, items: newItems, ...calculateBasketTotals(newItems) }
return updatedState
}
export const clearCart = (): CartState => {
return initialCartState
export const clearBasket = (): BasketData => {
return initialBasketData
}
export const setCartGlobalBillingCycle = (cartState: CartState, cycle: BillingCycle): CartState => {
const newItems = cartState.items.map((item) =>
withItemVat(item.product, item.quantity, cycle, cartState.globalPeriod),
export const setBasketGlobalBillingCycle = (basketData: BasketData, cycle: BillingCycle): BasketData => {
const newItems = basketData.items.map((item) =>
withItemVat(item.product, item.quantity, cycle, basketData.globalPeriod),
)
const updatedState = {
...cartState,
...basketData,
globalBillingCycle: cycle,
items: newItems,
...calculateCartTotals(newItems),
...calculateBasketTotals(newItems),
}
return updatedState
}
export const setCartGlobalPeriod = (cartState: CartState, period: number): CartState => {
const newItems = cartState.items.map((item) =>
export const setBasketGlobalPeriod = (basketData: BasketData, period: number): BasketData => {
const newItems = basketData.items.map((item) =>
withItemVat(item.product, item.quantity, item.billingCycle, period),
)
const updatedState = {
...cartState,
...basketData,
globalPeriod: period,
items: newItems,
...calculateCartTotals(newItems),
...calculateBasketTotals(newItems),
}
return updatedState
}
export const isItemInCart = (
cartState: CartState,
export const isItemInBasket = (
basketData: BasketData,
productId: string,
billingCycle: BillingCycle,
): boolean => {
return cartState.items.some(
return basketData.items.some(
(item) => item.product.id === productId && item.billingCycle === billingCycle,
)
}
export const isItemInCartState = (
export const isItemInBasketData = (
items: BasketItem[],
productId: string,
billingCycle: BillingCycle,

View file

@ -154,7 +154,7 @@ function TablePickerModal({
<div className="flex flex-col gap-3 p-4">
{isLoadingColumns ? (
<div className="text-xs text-gray-400 text-center py-6">
{translate('::Loading') || 'Yükleniyor...'}
{translate('::App.Loading')}
</div>
) : (
<>

View file

@ -26,8 +26,21 @@ import {
GridColumnJoinTypeListEnum,
} from '../../../../proxy/admin/list-form-field/models'
import { enumToList } from '../../../../utils/enumUtils'
import { colSpan, iconList, WidgetColorEnum } from '@/components/ui/Widget/iconList'
import { PREFIX } from '@/constants/theme.constant'
import { iconList } from '@/utils/iconList'
export enum WidgetColorEnum {
'Blue' = 'blue',
'Green' = 'green',
'Purple' = 'purple',
'Gray' = 'gray',
'Red' = 'red',
'Yellow' = 'yellow',
'Pink' = 'pink',
'Indigo' = 'indigo',
'Teal' = 'teal',
'Orange' = 'orange',
}
export const overflowWrapOptions = [
{ value: 'normal', label: 'Normal' },
@ -408,6 +421,8 @@ export const chartBreakStyleLineListOptions = [
{ value: 'waved', label: 'Waved' },
]
export const colSpan = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
export const colSpanOptions = colSpan.map((span) => ({
value: span,
label: span,

View file

@ -786,7 +786,7 @@ const Wizard = () => {
{isLoadingEditData && (
<p className="text-xs text-gray-400 text-center py-4 animate-pulse">
{translate('::App.Platform.Loading') || 'Loading...'}
{translate('::App.Loading') || 'Loading...'}
</p>
)}

View file

@ -173,7 +173,7 @@ const WizardFileManager = () => {
{loading && (
<p className="text-xs text-gray-400 text-center py-4 animate-pulse">
{translate('::App.Platform.Loading') || 'Loading...'}
{translate('::App.Loading')}
</p>
)}

View file

@ -272,7 +272,7 @@ const WizardStep2 = ({
options={grouped}
placeholder={
isLoadingDbObjects
? translate('::ListForms.Wizard.Step2.Loading') || 'Loading…'
? translate('::App.Loading')
: translate('::ListForms.Wizard.Step2.SelectCommand') ||
'Tablo/View/SP seç veya SQL yaz…'
}

View file

@ -484,7 +484,7 @@ function SortableItem({
<div className="flex flex-col gap-3 p-4">
{isLoadingPickerColumns ? (
<div className="text-xs text-gray-400 text-center py-6">
{translate('::Loading') || 'Yükleniyor...'}
{translate('::App.Loading')}
</div>
) : (
<>

View file

@ -379,7 +379,7 @@ const CrudEndpointManager: React.FC = () => {
</option>
))}
{dataSources.length === 0 && (
<option value="">{translate('::App.DeveloperKit.CrudEndpoints.Loading')}</option>
<option value="">{translate('::App.Loading')}</option>
)}
</select>
</div>
@ -434,7 +434,7 @@ const CrudEndpointManager: React.FC = () => {
<div className="flex items-center justify-center p-8 text-slate-400">
<FaSyncAlt className="animate-spin mr-2" />
<span className="text-sm">
{translate('::App.DeveloperKit.CrudEndpoints.Loading')}
{translate('::App.Loading')}
</span>
</div>
) : filteredTables.length === 0 ? (

View file

@ -443,7 +443,7 @@ const SqlObjectExplorer = ({
<div className="flex-1 overflow-auto">
{loading && (
<div className="text-center py-8 text-gray-500 text-sm">
{translate('::App.Platform.Loading')}
{translate('::App.Loading')}
</div>
)}
{!loading && treeData.length === 0 && (

View file

@ -1413,7 +1413,7 @@ GO`,
{isLoadingSqlDataFiles ? (
<p className="mb-4 text-gray-600 dark:text-gray-400">
{translate('::App.Platform.Loading') || 'Loading...'}
{translate('::App.Loading')}
</p>
) : (
<div className="flex min-h-0 flex-1 flex-col gap-3 lg:flex-row">

View file

@ -2272,7 +2272,7 @@ const SqlTableDesignerDialog = ({
<div>
<label className="block text-xs font-semibold text-gray-700 dark:text-gray-300 mb-1.5">
{translate('::App.SqlQueryManager.TargetColumn')}
{targetColsLoading ? `${translate('::App.SqlQueryManager.Loading')}` : ''}
{targetColsLoading ? `${translate('::App.Loading')}` : ''}
</label>
<select
value={fkForm.referencedColumn}
@ -2437,7 +2437,7 @@ const SqlTableDesignerDialog = ({
<div className="space-y-3">
{indexesLoading && (
<div className="flex items-center justify-center py-10 text-gray-500 text-sm gap-2">
<span className="animate-spin">&#9696;</span> {translate('::App.SqlQueryManager.Loading')}
<span className="animate-spin">&#9696;</span> {translate('::App.Loading')}
</div>
)}
{!indexesLoading && (

View file

@ -34,7 +34,7 @@ const FormButtons = (props: {
permissions: PermissionResults
handleSubmit: (e: any) => void
refreshData: () => void
getSelectedRowKeys: () => void
getSelectedRowKeys: () => any[] | Promise<any[]>
getSelectedRowsData: () => any[]
getFilter: () => void
onActionEdit?: () => void

View file

@ -69,11 +69,6 @@ const GridBoxEditorComponent = ({
e.component.close()
}
}}
// selectedRowKeys={[{
// key: 'en',
// name: 'English'
// }]}
//TODO:Bu kısım tekrar değerlendirilmeli
onEditorPrepared={(event) => {
const getListValues = async () => {
const data = await editorOptions?.dataSource?.load()

View file

@ -165,8 +165,7 @@ const List: React.FC = () => {
variant={viewMode === 'scheduler' ? 'solid' : 'default'}
onClick={() => setLayout('scheduler')}
onMouseEnter={() => preload.scheduler()}
>
</Button>
></Button>
)}
{gridDto?.gridOptions?.layoutDto.gantt &&
@ -178,8 +177,7 @@ const List: React.FC = () => {
variant={viewMode === 'gantt' ? 'solid' : 'default'}
onClick={() => setLayout('gantt')}
onMouseEnter={() => preload.gantt()}
>
</Button>
></Button>
)}
{gridDto?.gridOptions?.layoutDto.tree &&
@ -190,8 +188,7 @@ const List: React.FC = () => {
variant={viewMode === 'tree' ? 'solid' : 'default'}
onClick={() => setLayout('tree')}
onMouseEnter={() => preload.tree()}
>
</Button>
></Button>
)}
<Button
@ -200,8 +197,7 @@ const List: React.FC = () => {
variant={viewMode === 'grid' ? 'solid' : 'default'}
onClick={() => setLayout('grid')}
onMouseEnter={() => preload.grid()}
>
</Button>
></Button>
{gridDto.gridOptions.layoutDto.pivot && (
<Button
@ -210,8 +206,7 @@ const List: React.FC = () => {
variant={viewMode === 'pivot' ? 'solid' : 'default'}
onClick={() => setLayout('pivot')}
onMouseEnter={() => preload.pivot()}
>
</Button>
></Button>
)}
{gridDto.gridOptions.layoutDto.chart && (
@ -221,8 +216,7 @@ const List: React.FC = () => {
variant={viewMode === 'chart' ? 'solid' : 'default'}
onClick={() => setLayout('chart')}
onMouseEnter={() => preload.chart()}
>
</Button>
></Button>
)}
</div>
</div>
@ -230,7 +224,7 @@ const List: React.FC = () => {
{/* =======================
VIEW RENDER
======================= */}
<Suspense fallback={<div className="p-4 text-sm">Yükleniyor...</div>}>
<Suspense fallback={<div className="p-4 text-sm">{translate('::App.Loading')}</div>}>
{viewMode === 'grid' && (
<Grid
listFormCode={listFormCode}

View file

@ -57,7 +57,7 @@ const useToolbar = ({
}: {
gridDto?: GridDto
listFormCode: string
getSelectedRowKeys: () => unknown[] | Promise<unknown[]>
getSelectedRowKeys: () => any[] | Promise<any[]>
getSelectedRowsData: () => any
refreshData: () => void
getFilter: () => void

View file

@ -1,15 +1,15 @@
import { Cart } from '@/components/orders/Cart'
import { Basket } from '@/components/orders/Basket'
import { TenantForm } from '@/components/orders/TenantForm'
import { APP_NAME } from '@/constants/app.constant'
import { CustomTenantDto } from '@/proxy/config/models'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useStoreActions, useStoreState } from '@/store/store'
import {
CartState,
clearCart,
removeItemFromCart,
updateCartItemQuantity,
} from '@/utils/cartUtils'
BasketData,
clearBasket,
removeItemFromBasket,
updateBasketItemQuantity,
} from '@/utils/basketUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
import React, { useState, useEffect } from 'react'
import { Helmet } from 'react-helmet'
@ -17,17 +17,17 @@ import { useNavigate } from 'react-router-dom'
const Checkout: React.FC = () => {
const navigate = useNavigate()
const [isCartOpen, setIsCartOpen] = useState(false)
const [isBasketOpen, setIsBasketOpen] = useState(false)
const { translate } = useLocalization()
const storedCartState = useStoreState((state) => state.client.cartState)
const { setCartState: persistCartState } = useStoreActions((actions) => actions.client)
const storedBasketData = useStoreState((state) => state.client.basketData)
const { setBasketData } = useStoreActions((actions) => actions.client)
const { setTenantData } = useStoreActions((actions) => actions.client.order)
const [cartState, setCartState] = useState<CartState>(storedCartState)
const [basketData, setLocalBasketData] = useState<BasketData>(storedBasketData)
useEffect(() => {
persistCartState(cartState)
}, [cartState, persistCartState])
setBasketData(basketData)
}, [basketData, setBasketData])
const handleTenantSubmit = (tenantData: CustomTenantDto) => {
setTenantData(tenantData)
@ -39,20 +39,20 @@ const Checkout: React.FC = () => {
}
const handleCheckout = () => {
setIsCartOpen(false)
setIsBasketOpen(false)
navigate(ROUTES_ENUM.public.checkout)
}
const handleUpdateQuantity = (id: string, quantity: number) => {
setCartState((currentState) => updateCartItemQuantity(currentState, id, quantity))
setLocalBasketData((currentState) => updateBasketItemQuantity(currentState, id, quantity))
}
const handleRemoveItem = (id: string) => {
setCartState((currentState) => removeItemFromCart(currentState, id))
setLocalBasketData((currentState) => removeItemFromBasket(currentState, id))
}
const handleClearCart = () => {
setCartState(clearCart())
const handleClearBasket = () => {
setLocalBasketData(clearBasket())
}
return (
@ -77,14 +77,14 @@ const Checkout: React.FC = () => {
<div className="container mx-auto px-4 pt-12">
<TenantForm onSubmit={handleTenantSubmit} onBack={handleBackToCatalog} />
<Cart
isOpen={isCartOpen}
onClose={() => setIsCartOpen(false)}
<Basket
isOpen={isBasketOpen}
onClose={() => setIsBasketOpen(false)}
onCheckout={handleCheckout}
cartState={cartState}
basketData={basketData}
updateQuantity={handleUpdateQuantity}
removeItem={handleRemoveItem}
clearCart={handleClearCart}
clearBasket={handleClearBasket}
/>
</div>
</div>

View file

@ -1,4 +1,4 @@
import { Cart } from '@/components/orders/Cart'
import { Basket } from '@/components/orders/Basket'
import { PaymentForm } from '@/components/orders/PaymentForm'
import { Loading } from '@/components/shared'
import { APP_NAME } from '@/constants/app.constant'
@ -8,11 +8,11 @@ import { ROUTES_ENUM } from '@/routes/route.constant'
import { OrderService } from '@/services/order.service'
import { useStoreActions, useStoreState } from '@/store/store'
import {
CartState,
clearCart,
removeItemFromCart,
updateCartItemQuantity,
} from '@/utils/cartUtils'
BasketData,
clearBasket,
removeItemFromBasket,
updateBasketItemQuantity,
} from '@/utils/basketUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
import React, { useState, useEffect } from 'react'
import { Helmet } from 'react-helmet'
@ -20,13 +20,13 @@ import { useNavigate } from 'react-router-dom'
const Payment: React.FC = () => {
const navigate = useNavigate()
const storedCartState = useStoreState((state) => state.client.cartState)
const storedBasketData = useStoreState((state) => state.client.basketData)
const storedTenantData = useStoreState((state) => state.client.order.tenantData)
const { setCartState: persistCartState } = useStoreActions((actions) => actions.client)
const { setBasketData } = useStoreActions((actions) => actions.client)
const { setOrderResult } = useStoreActions((actions) => actions.client.order)
const [tenant, setTenant] = useState<CustomTenantDto | null>(storedTenantData)
const [isCartOpen, setIsCartOpen] = useState(false)
const [cartState, setCartState] = useState<CartState>(storedCartState)
const [isBasketOpen, setIsBasketOpen] = useState(false)
const [basketData, setLocalBasketData] = useState<BasketData>(storedBasketData)
const { translate } = useLocalization()
useEffect(() => {
@ -39,45 +39,45 @@ const Payment: React.FC = () => {
}, [navigate, storedTenantData])
useEffect(() => {
persistCartState(cartState)
}, [cartState, persistCartState])
setBasketData(basketData)
}, [basketData, setBasketData])
const handleCheckout = () => {
setIsCartOpen(false)
setIsBasketOpen(false)
navigate(ROUTES_ENUM.public.checkout)
}
const handleUpdateQuantity = (id: string, quantity: number) => {
setCartState((currentState) => updateCartItemQuantity(currentState, id, quantity))
setLocalBasketData((currentState) => updateBasketItemQuantity(currentState, id, quantity))
}
const handleRemoveItem = (id: string) => {
setCartState((currentState) => removeItemFromCart(currentState, id))
setLocalBasketData((currentState) => removeItemFromBasket(currentState, id))
}
const handleClearCart = () => {
setCartState(clearCart())
const handleClearBasket = () => {
setLocalBasketData(clearBasket())
}
const handlePaymentComplete = async (paymentData: Record<string, unknown>) => {
if (!tenant) return
try {
const billingCycle = cartState.globalBillingCycle || 'yearly'
const period = cartState.globalPeriod > 0 ? cartState.globalPeriod : 1
const billingCycle = basketData.globalBillingCycle || 'yearly'
const period = basketData.globalPeriod > 0 ? basketData.globalPeriod : 1
const licenseStartTime = new Date(paymentData.licenseStartTime as string)
const licenseEndTime = new Date(paymentData.licenseEndTime as string)
const orderData = {
tenant,
items: cartState.items,
items: basketData.items,
isExisting: paymentData.isExisting,
billingCycle,
period,
licenseStartTime: licenseStartTime.toISOString(),
licenseEndTime: licenseEndTime.toISOString(),
subtotal: cartState.subtotal,
vatTotal: cartState.vatTotal,
subtotal: basketData.subtotal,
vatTotal: basketData.vatTotal,
commission: paymentData.commission,
total: paymentData.total,
paymentMethodId: paymentData.paymentMethodId,
@ -99,7 +99,7 @@ const Payment: React.FC = () => {
orderId: result.orderId,
...orderData,
})
setCartState(clearCart())
setLocalBasketData(clearBasket())
navigate(ROUTES_ENUM.public.success)
} else {
alert('Sipariş oluşturulurken hata oluştu: ' + result.error)
@ -145,19 +145,19 @@ const Payment: React.FC = () => {
<div className="container mx-auto px-4 pt-4">
<PaymentForm
cartState={cartState}
basketData={basketData}
tenant={tenant}
onBack={handleBackToTenant}
onComplete={handlePaymentComplete}
/>
<Cart
cartState={cartState}
isOpen={isCartOpen}
clearCart={handleClearCart}
<Basket
basketData={basketData}
isOpen={isBasketOpen}
clearBasket={handleClearBasket}
removeItem={handleRemoveItem}
updateQuantity={handleUpdateQuantity}
onClose={() => setIsCartOpen(false)}
onClose={() => setIsBasketOpen(false)}
onCheckout={handleCheckout}
/>
</div>

View file

@ -1,18 +1,18 @@
import { BillingControls } from '@/components/orders/BillingControls'
import { Cart } from '@/components/orders/Cart'
import { Basket } from '@/components/orders/Basket'
import { ProductCatalog } from '@/components/orders/ProductCatalog'
import { APP_NAME } from '@/constants/app.constant'
import { BillingCycle } from '@/proxy/order/models'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { useStoreActions, useStoreState } from '@/store/store'
import {
CartState,
clearCart,
removeItemFromCart,
setCartGlobalBillingCycle,
setCartGlobalPeriod,
updateCartItemQuantity,
} from '@/utils/cartUtils'
BasketData,
clearBasket,
removeItemFromBasket,
setBasketGlobalBillingCycle,
setBasketGlobalPeriod,
updateBasketItemQuantity,
} from '@/utils/basketUtils'
import { useLocalization } from '@/utils/hooks/useLocalization'
import React, { useState, useEffect } from 'react'
import { Helmet } from 'react-helmet'
@ -20,20 +20,20 @@ import { useNavigate } from 'react-router-dom'
const Products: React.FC = () => {
const [searchQuery, setSearchQuery] = useState('')
const [isCartOpen, setIsCartOpen] = useState(false)
const [isBasketOpen, setIsBasketOpen] = useState(false)
const { translate } = useLocalization()
const storedCartState = useStoreState((state) => state.client.cartState)
const { setCartState: persistCartState } = useStoreActions((actions) => actions.client)
const [cartState, setCartState] = useState<CartState>(storedCartState)
const storedBasketData = useStoreState((state) => state.client.basketData)
const { setBasketData } = useStoreActions((actions) => actions.client)
const [basketData, setLocalBasketData] = useState<BasketData>(storedBasketData)
const navigate = useNavigate()
useEffect(() => {
persistCartState(cartState)
}, [cartState, persistCartState])
setBasketData(basketData)
}, [basketData, setBasketData])
const handleCartClick = () => {
setIsCartOpen(true)
const handleBasketClick = () => {
setIsBasketOpen(true)
}
const handleNavigate = (section: string) => {
@ -47,28 +47,28 @@ const Products: React.FC = () => {
}
const handleCheckout = () => {
setIsCartOpen(false)
setIsBasketOpen(false)
navigate(ROUTES_ENUM.public.checkout)
}
const handleUpdateQuantity = (id: string, quantity: number) => {
setCartState((currentState) => updateCartItemQuantity(currentState, id, quantity))
setLocalBasketData((currentState) => updateBasketItemQuantity(currentState, id, quantity))
}
const handleRemoveItem = (id: string) => {
setCartState((currentState) => removeItemFromCart(currentState, id))
setLocalBasketData((currentState) => removeItemFromBasket(currentState, id))
}
const handleSetGlobalBillingCycle = (cycle: BillingCycle) => {
setCartState((currentState) => setCartGlobalBillingCycle(currentState, cycle))
setLocalBasketData((currentState) => setBasketGlobalBillingCycle(currentState, cycle))
}
const handleSetGlobalPeriod = (period: number) => {
setCartState((currentState) => setCartGlobalPeriod(currentState, period))
setLocalBasketData((currentState) => setBasketGlobalPeriod(currentState, period))
}
const handleClearCart = () => {
setCartState(clearCart())
const handleClearBasket = () => {
setLocalBasketData(clearBasket())
}
return (
@ -84,31 +84,31 @@ const Products: React.FC = () => {
<div className="container mx-auto px-4 pt-4">
<BillingControls
globalBillingCycle={cartState.globalBillingCycle}
globalPeriod={cartState.globalPeriod}
globalBillingCycle={basketData.globalBillingCycle}
globalPeriod={basketData.globalPeriod}
setGlobalBillingCycle={handleSetGlobalBillingCycle}
setGlobalPeriod={handleSetGlobalPeriod}
onCartClick={handleCartClick}
onBasketClick={handleBasketClick}
onNavigate={handleNavigate}
cartItemsCount={cartState.items.length}
cartState={cartState}
basketItemsCount={basketData.items.length}
basketData={basketData}
/>
<ProductCatalog
searchQuery={searchQuery}
onSearchChange={setSearchQuery}
cartState={cartState}
setCartState={setCartState}
basketData={basketData}
setBasketData={setLocalBasketData}
/>
<Cart
isOpen={isCartOpen}
onClose={() => setIsCartOpen(false)}
<Basket
isOpen={isBasketOpen}
onClose={() => setIsBasketOpen(false)}
onCheckout={handleCheckout}
cartState={cartState}
basketData={basketData}
updateQuantity={handleUpdateQuantity}
removeItem={handleRemoveItem}
clearCart={handleClearCart}
clearBasket={handleClearBasket}
/>
</div>
</div>

View file

@ -9,9 +9,7 @@ import { createReportUrl } from './reportRouteParams'
import { MODE_DARK } from '@/constants/theme.constant'
import { useStoreState } from '@/store/store'
const ReportDesigner = lazy(() =>
import('devexpress-reporting-react/dx-report-designer')
)
const ReportDesigner = lazy(() => import('devexpress-reporting-react/dx-report-designer'))
const VIEWER_THEME_LINK_ID = 'devexpress-report-viewer-theme'
const REPORT_DESIGNER_CSS_ID = 'devexpress-report-designer-css'
@ -81,7 +79,11 @@ const DevexpressReportDesigner: React.FC = () => {
const themeMode = useStoreState((state) => state.theme.mode)
const isDarkMode = themeMode === MODE_DARK
const location = useLocation()
const reportUrlWithParams = createReportUrl({ report, id, listFormCode }, location.search, 'design')
const reportUrlWithParams = createReportUrl(
{ report, id, listFormCode },
location.search,
'design',
)
useEffect(() => {
loadViewerCss(isDarkMode)
}, [isDarkMode])
@ -96,7 +98,7 @@ const DevexpressReportDesigner: React.FC = () => {
defaultTitle={APP_NAME}
/>
<Suspense fallback={<div>Rapor tasarımcısı yükleniyor...</div>}>
<Suspense fallback={<div>{translate('::App.Loading')}</div>}>
<ReportDesigner reportUrl={reportUrlWithParams}>
<RequestOptions
host={`${import.meta.env.VITE_API_URL}/`}

View file

@ -5,13 +5,12 @@
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"ignoreDeprecations": "6.0",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": false,
"module": "ESNext",
"moduleResolution": "Bundler",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,

View file

@ -7,5 +7,5 @@
"ignoreDeprecations": "6.0",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts", "./src/services/tenants.ts"]
"include": ["vite.config.ts"]
}

View file

@ -8,9 +8,6 @@ export default defineConfig(async ({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
const apiUrl = env.VITE_API_URL
const baseDomains = ['sozsoft.com', 'dev.sozsoft.com', '.sozsoft.com']
// const tenantNames = (await fetchTenantNames(apiUrl)).map((n) => n.trim().toLowerCase())
// const tenantHosts = tenantNames.map((t) => `${t}.sozsoft.com`)
const tenantHosts: string[] = []
const allowedHosts = Array.from(new Set(['localhost', ...baseDomains, ...tenantHosts]))