Tailwind 4 geçişi
This commit is contained in:
parent
48e7d34026
commit
a56bdc3e79
227 changed files with 3511 additions and 11204 deletions
43
README.md
43
README.md
|
|
@ -128,18 +128,18 @@ DevExtreme bileşenleri bu metadata'ya göre kendini kurar.
|
||||||
|
|
||||||
| Bileşen | Sürüm / Notlar |
|
| Bileşen | Sürüm / Notlar |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| React | 19.2 |
|
| React | 19.3 |
|
||||||
| Build | Vite 8 + TypeScript 5.9 |
|
| Build | Vite 8 + TypeScript 7.0 (native `tsc`), lint: oxlint |
|
||||||
| UI kütüphaneleri | DevExtreme 26.1 (React), Tailwind CSS 3.4, kendi `components/ui` tasarım sistemi |
|
| UI kütüphaneleri | DevExtreme 26.1 (React), Tailwind CSS 4.3 (`@tailwindcss/vite`, CSS-first yapılandırma), kendi `components/ui` tasarım sistemi |
|
||||||
| Routing | react-router-dom 7 (dinamik route üretimi) |
|
| Routing | react-router-dom 7 (dinamik route üretimi) |
|
||||||
| State | easy-peasy (global store) + @tanstack/react-query |
|
| State | easy-peasy (global store) |
|
||||||
| Form | Formik + Yup, DevExtreme Form |
|
| Form | Formik + Yup, DevExtreme Form |
|
||||||
| Kod editörü | Monaco Editor |
|
| Kod editörü | Monaco Editor |
|
||||||
| Runtime derleme | @babel/standalone (Custom Component) |
|
| Runtime derleme | @babel/standalone 8 (Custom Component; JSX `classic` runtime) |
|
||||||
| Takvim/Gantt | DevExtreme Scheduler/Gantt |
|
| Takvim/Gantt | DevExtreme Scheduler/Gantt |
|
||||||
| Gerçek zamanlı | @microsoft/signalr |
|
| Gerçek zamanlı | @microsoft/signalr |
|
||||||
| PWA | vite-plugin-pwa (Workbox) |
|
| PWA | vite-plugin-pwa 2 (Workbox 7) |
|
||||||
| Node | 24.13 / npm 11 (`volta` ile sabitlenmiş) |
|
| Node | 24.22 / npm 12 (`volta` ile sabitlenmiş; kurulum betikleri `allowScripts` ile yönetilir) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -1140,12 +1140,25 @@ kaynak seed dosyalarıdır (`configs/seeds/*/data/App.DeveloperKit.CustomCompone
|
||||||
depo kökünde, `ui/` dışındadır — derleme bağlamı yalnızca `ui/` klasörü olduğunda (docker, ayrı
|
depo kökünde, `ui/` dışındadır — derleme bağlamı yalnızca `ui/` klasörü olduğunda (docker, ayrı
|
||||||
checkout) glob boş döner ve seed'e özgü sınıflar (`md:col-span-4`, `bg-gray-950/80`, `opacity-20`)
|
checkout) glob boş döner ve seed'e özgü sınıflar (`md:col-span-4`, `bg-gray-950/80`, `opacity-20`)
|
||||||
CSS'e hiç girmez: uygulama yerelde doğru, sunucuda stilsiz görünür. Bu yüzden aynı sınıflar var
|
CSS'e hiç girmez: uygulama yerelde doğru, sunucuda stilsiz görünür. Bu yüzden aynı sınıflar var
|
||||||
olan `ui/safelist.txt` dosyasına da yazılır. Dosyayı zaten `twSafelistGenerator` eklentisi üretiyor
|
olan `ui/safelist.txt` dosyasına da yazılır. Dosyayı `ui/twSafelistGenerator.ts` Vite eklentisi
|
||||||
(renk/ölçü listesi); eklenti artık seed dosyalarındaki `className` değerlerini de toplayıp
|
üretir: seed dosyalarındaki `className` değerlerini toplar, derleme başında yazar ve geliştirmede seed
|
||||||
`# --- custom component classes ---` işaretinin altına ekliyor. `safelist.txt` `ui/` içinde ve
|
klasörünü izler. `safelist.txt` `ui/` içinde ve depoda olduğu için her ortamda taranır
|
||||||
depoda olduğu için her ortamda taranır. Seed kökü görünmüyorsa işaretin altındaki liste olduğu gibi
|
(`src/assets/styles/tailwind/index.css` → `@source`). Seed kökü görünmüyorsa liste olduğu gibi
|
||||||
korunur — eksik bir bağlam listeyi silip sorunu büyütmez. Ayrı bir betik ya da ikinci bir safelist
|
korunur — eksik bir bağlam listeyi silip sorunu büyütmez. Çalışma anında veriden gelen renk/ölçü
|
||||||
dosyası yoktur; liste her `npm run build` / `npm start` ile tazelenir.
|
sınıfları (`bg-{renk}-{ton}`, `w-1/2` …) dosyaya değil aynı CSS'teki `@source inline(...)` satırlarına
|
||||||
|
yazılır. Ayrı bir betik ya da ikinci bir safelist dosyası yoktur; liste her `npm run build` /
|
||||||
|
`npm start` ile tazelenir.
|
||||||
|
|
||||||
|
**Tailwind 4 yapılandırması.** `tailwind.config.ts` ve PostCSS zinciri yoktur; tema (`gray` paleti,
|
||||||
|
`sozsoft-*` renkleri, `1.2`–`1.4` aralıkları, font) `src/assets/styles/tailwind/index.css` içindeki
|
||||||
|
`@theme` bloğundadır. Aynı dosya v3 davranışını koruyan uyumluluk kurallarını taşır: `dark` sınıf
|
||||||
|
varyantı, dokunmatikte de çalışan `hover`, gri-200 kenarlık, gri-400 placeholder, butonda `pointer`
|
||||||
|
imleci, varsayılan 3px mavi `ring`, veritabanındaki eski Custom Component kodu için `flex-shrink-*` /
|
||||||
|
`flex-grow-*`. Kademelenme v3 ile aynıdır (`app.css`): yalnızca tema ve preflight katmandadır
|
||||||
|
(en zayıf); `components/` + `template/` stilleri ve en sonda utility'ler katmansızdır. Bileşen
|
||||||
|
stilleri katmana alınmaz — katmansız CSS her katmanı yendiği için stilini katmansız basan
|
||||||
|
kütüphanelere (react-select, DevExtreme) yenilirdi. JS'te renk gerektiğinde değer kopyalanmaz,
|
||||||
|
`themeColor()` (`src/utils/tailwind.ts`) temanın `var(--color-*)` değişkenini döndürür.
|
||||||
|
|
||||||
**Katalog düğümleri.** Kanvasın doğrudan çizdiği, derlenen bileşen listesinde yer almayan
|
**Katalog düğümleri.** Kanvasın doğrudan çizdiği, derlenen bileşen listesinde yer almayan
|
||||||
bileşenler tek bir sözlükte durur (`RUNTIME_NODE_COMPONENTS`): kanvas onu `VisualCanvas` içinde,
|
bileşenler tek bir sözlükte durur (`RUNTIME_NODE_COMPONENTS`): kanvas onu `VisualCanvas` içinde,
|
||||||
|
|
@ -2104,8 +2117,8 @@ Ayrıntılı kurulum notları: [`configs/deployment/README.md`](configs/deployme
|
||||||
cd ui
|
cd ui
|
||||||
npm start # geliştirme sunucusu
|
npm start # geliştirme sunucusu
|
||||||
npm run build # üretim derlemesi (metadata + version + vite build)
|
npm run build # üretim derlemesi (metadata + version + vite build)
|
||||||
npm run lint # ESLint
|
npm run lint # oxlint (.oxlintrc.json)
|
||||||
npm run format # prettier --write + eslint --fix
|
npm run format # prettier --write + oxlint --fix
|
||||||
```
|
```
|
||||||
|
|
||||||
### 21.3. Backend
|
### 21.3. Backend
|
||||||
|
|
|
||||||
|
|
@ -519,8 +519,11 @@ Bir çelişki varsa sıra: `ai.instructions.md` → `dotnet.instructions.md` →
|
||||||
olmadığını kontrol et.
|
olmadığını kontrol et.
|
||||||
- **Custom component sınıfları** → bileşen kodu veritabanında yaşar, Tailwind derlemede yalnızca
|
- **Custom component sınıfları** → bileşen kodu veritabanında yaşar, Tailwind derlemede yalnızca
|
||||||
seed dosyasını görür. Seed dosyası `ui/` dışında olduğu için aynı sınıflar `ui/safelist.txt`
|
seed dosyasını görür. Seed dosyası `ui/` dışında olduğu için aynı sınıflar `ui/safelist.txt`
|
||||||
sonuna da yazılır (`twSafelistGenerator`, derlemede otomatik); yoksa uygulama sunucuda stilsiz
|
dosyasına da yazılır (`ui/twSafelistGenerator.ts` Vite eklentisi, derlemede otomatik); yoksa
|
||||||
kalır. İkinci bir safelist dosyası açma.
|
uygulama sunucuda stilsiz kalır. İkinci bir safelist dosyası açma. Çalışma anında veriden üretilen
|
||||||
|
sınıf (`bg-${renk}-500`) dosyaya değil `src/assets/styles/tailwind/index.css`'teki `@source inline`
|
||||||
|
satırına eklenir. Sınıf adları Tailwind 4'tür (`shadow-xs`, `rounded-sm`, `bg-black/50`,
|
||||||
|
`shrink-0`, `x!`); tema `tailwind.config.ts`'te değil aynı dosyanın `@theme` bloğundadır.
|
||||||
- **Custom component kaydı/silinmesi** → `data/App.DeveloperKit.CustomComponents/{Id}.json`
|
- **Custom component kaydı/silinmesi** → `data/App.DeveloperKit.CustomComponents/{Id}.json`
|
||||||
(Custom Components ekranının seed verisi); ekran klasör modundadır, her bileşen kendi satır
|
(Custom Components ekranının seed verisi); ekran klasör modundadır, her bileşen kendi satır
|
||||||
dosyasındadır. Hem listeden hem Visual Designer'dan (`CustomComponentAppService`) yapılan kayıt
|
dosyasındadır. Hem listeden hem Visual Designer'dan (`CustomComponentAppService`) yapılan kayıt
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -11,7 +11,7 @@
|
||||||
"Description": null,
|
"Description": null,
|
||||||
"IsActive": true,
|
"IsActive": true,
|
||||||
"Dependencies": "",
|
"Dependencies": "",
|
||||||
"Code": "import React, { useEffect, useState } from \"react\";\nimport axios from \"axios\";\n\ninterface DynamicEntityComponentProps {\n title: string;\n}\n\nconst api = axios.create({\n baseURL: \"https://localhost:44344/\",\n});\n\nconst DynamicEntityComponent: React.FC<DynamicEntityComponentProps> = ({ title }) => {\n const [data, setData] = useState<Array<{ id: string; name: string }>>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const res = await api.get(`/api/app/crudendpoint/${title}`);\n const raw = Array.isArray(res.data) ? res.data : res.data?.items ?? [];\n\n const filtered = raw.map((item: any) => ({\n id: item.Id ?? item.id,\n name: item.Name ?? item.name,\n }));\n\n setData(filtered);\n } catch (err: any) {\n setError(err.message || \"Failed to fetch data\");\n } finally {\n setLoading(false);\n }\n };\n\n if (title) fetchData();\n }, [title]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div className=\"text-red-600 dark:text-red-400\">Error: {error}</div>;\n if (!data.length) return <div>No records found</div>;\n\n const headers = [\"id\", \"name\", \"actions\"];\n\n return (\n <div className=\"overflow-auto\">\n <table className=\"min-w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 shadow-sm rounded-lg\">\n <thead className=\"bg-slate-100 dark:bg-slate-800\">\n <tr>\n {headers.map((key) => (\n <th\n key={key}\n className=\"text-left px-4 py-2 border-b border-slate-200 dark:border-slate-700 text-sm font-medium text-slate-700 dark:text-slate-200\"\n >\n {key === \"actions\" ? \"Actions\" : key}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((item, rowIndex) => (\n <tr key={item.id ?? rowIndex} className=\"hover:bg-slate-50 dark:hover:bg-slate-800\">\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.id}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.name}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800\">\n <Button\n type=\"button\"\n color=\"blue-500\"\n onClick={() => alert(item.name)}\n shape=\"round\"\n size=\"xs\"\n variant=\"solid\"\n id=\"c_mrix4c1a_qrybhk\"\n >\n Show Name\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default DynamicEntityComponent;",
|
"Code": "import React, { useEffect, useState } from \"react\";\nimport axios from \"axios\";\n\ninterface DynamicEntityComponentProps {\n title: string;\n}\n\nconst api = axios.create({\n baseURL: \"https://localhost:44344/\",\n});\n\nconst DynamicEntityComponent: React.FC<DynamicEntityComponentProps> = ({ title }) => {\n const [data, setData] = useState<Array<{ id: string; name: string }>>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const res = await api.get(`/api/app/crudendpoint/${title}`);\n const raw = Array.isArray(res.data) ? res.data : res.data?.items ?? [];\n\n const filtered = raw.map((item: any) => ({\n id: item.Id ?? item.id,\n name: item.Name ?? item.name,\n }));\n\n setData(filtered);\n } catch (err: any) {\n setError(err.message || \"Failed to fetch data\");\n } finally {\n setLoading(false);\n }\n };\n\n if (title) fetchData();\n }, [title]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div className=\"text-red-600 dark:text-red-400\">Error: {error}</div>;\n if (!data.length) return <div>No records found</div>;\n\n const headers = [\"id\", \"name\", \"actions\"];\n\n return (\n <div className=\"overflow-auto\">\n <table className=\"min-w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 shadow-xs rounded-lg\">\n <thead className=\"bg-slate-100 dark:bg-slate-800\">\n <tr>\n {headers.map((key) => (\n <th\n key={key}\n className=\"text-left px-4 py-2 border-b border-slate-200 dark:border-slate-700 text-sm font-medium text-slate-700 dark:text-slate-200\"\n >\n {key === \"actions\" ? \"Actions\" : key}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((item, rowIndex) => (\n <tr key={item.id ?? rowIndex} className=\"hover:bg-slate-50 dark:hover:bg-slate-800\">\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.id}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.name}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800\">\n <Button\n type=\"button\"\n color=\"blue-500\"\n onClick={() => alert(item.name)}\n shape=\"round\"\n size=\"xs\"\n variant=\"solid\"\n id=\"c_mrix4c1a_qrybhk\"\n >\n Show Name\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default DynamicEntityComponent;",
|
||||||
"Props": null,
|
"Props": null,
|
||||||
"DataSources": "",
|
"DataSources": "",
|
||||||
"LastModificationTime": null,
|
"LastModificationTime": null,
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
44
ui/.oxlintrc.json
Normal file
44
ui/.oxlintrc.json
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||||
|
"plugins": ["typescript", "react", "import", "oxc"],
|
||||||
|
"categories": {
|
||||||
|
"correctness": "error"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2024": true
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"react": { "version": "19" }
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"react/rules-of-hooks": "error",
|
||||||
|
"react/exhaustive-deps": "warn",
|
||||||
|
"react/only-export-components": ["warn", { "allowConstantExport": true }],
|
||||||
|
"react/react-in-jsx-scope": "off",
|
||||||
|
"react/set-state-in-effect": "off",
|
||||||
|
"react/refs": "off",
|
||||||
|
"react/immutability": "off",
|
||||||
|
"react/static-components": "off",
|
||||||
|
"react/preserve-manual-memoization": "off",
|
||||||
|
"react/purity": "off",
|
||||||
|
"react/use-memo": "off",
|
||||||
|
"react/no-did-update-set-state": "off",
|
||||||
|
"no-eval": "off",
|
||||||
|
"import/first": "warn",
|
||||||
|
"import/newline-after-import": "warn",
|
||||||
|
"import/no-duplicates": "error",
|
||||||
|
"import/default": "off",
|
||||||
|
"import/no-named-as-default": "off",
|
||||||
|
"import/no-named-as-default-member": "off",
|
||||||
|
"typescript/no-explicit-any": "off",
|
||||||
|
"no-unused-vars": "off"
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["vite.config.ts", "twSafelistGenerator.ts"],
|
||||||
|
"env": { "browser": false, "node": true }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ignorePatterns": ["dist/**", "dev-dist/**", "public/**", "env.d.ts"]
|
||||||
|
}
|
||||||
2
ui/.vscode/extensions.json
vendored
2
ui/.vscode/extensions.json
vendored
|
|
@ -3,7 +3,7 @@
|
||||||
"vscode.typescript-language-features",
|
"vscode.typescript-language-features",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"bradlc.vscode-tailwindcss",
|
"bradlc.vscode-tailwindcss",
|
||||||
"dbaemuer.vscode-eslint",
|
"oxc.oxc-vscode",
|
||||||
"vscode.npm"
|
"vscode.npm"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
ARG ENV="dev"
|
ARG ENV="dev"
|
||||||
|
|
||||||
FROM node:24-alpine
|
FROM node:24.22-alpine
|
||||||
ARG ENV=$ENV
|
ARG ENV=$ENV
|
||||||
RUN apk add --no-cache ca-certificates && update-ca-certificates
|
# Node/npm sürümü package.json `volta` alanıyla aynıdır.
|
||||||
|
RUN apk add --no-cache ca-certificates && update-ca-certificates && \
|
||||||
|
npm install -g npm@12.2.0
|
||||||
|
|
||||||
ENV GENERATE_SOURCEMAP=false
|
ENV GENERATE_SOURCEMAP=false
|
||||||
ENV NODE_OPTIONS=--max-old-space-size=16384
|
ENV NODE_OPTIONS=--max-old-space-size=16384
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
import js from '@eslint/js'
|
|
||||||
import tsParser from '@typescript-eslint/parser'
|
|
||||||
import tsPlugin from '@typescript-eslint/eslint-plugin'
|
|
||||||
import importPlugin from 'eslint-plugin-import'
|
|
||||||
import reactPlugin from 'eslint-plugin-react'
|
|
||||||
import reactHooks from 'eslint-plugin-react-hooks'
|
|
||||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
||||||
import prettier from 'eslint-config-prettier'
|
|
||||||
import globals from 'globals'
|
|
||||||
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
ignores: [
|
|
||||||
'node_modules/**',
|
|
||||||
'dist/**',
|
|
||||||
'dev-dist/**',
|
|
||||||
'public/**',
|
|
||||||
'env.d.ts',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
js.configs.recommended,
|
|
||||||
{
|
|
||||||
files: ['**/*.{js,jsx,ts,tsx}'],
|
|
||||||
languageOptions: {
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
sourceType: 'module',
|
|
||||||
globals: globals.browser,
|
|
||||||
parserOptions: { ecmaFeatures: { jsx: true } },
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
import: importPlugin,
|
|
||||||
react: reactPlugin,
|
|
||||||
'react-hooks': reactHooks,
|
|
||||||
'react-refresh': reactRefresh,
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
react: { version: 'detect' },
|
|
||||||
'import/parsers': { '@typescript-eslint/parser': ['.ts', '.tsx'] },
|
|
||||||
'import/resolver': {
|
|
||||||
typescript: { project: './tsconfig.eslint.json', alwaysTryTypes: true },
|
|
||||||
},
|
|
||||||
// Vite'in sanal modulleri diskte yoktur; cozucu onlari bulamaz, tipleri
|
|
||||||
// `vite-env.d.ts` uzerinden gelir.
|
|
||||||
'import/core-modules': ['virtual:pwa-register'],
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
...reactPlugin.configs.recommended.rules,
|
|
||||||
...reactPlugin.configs['jsx-runtime'].rules,
|
|
||||||
'react-hooks/rules-of-hooks': 'error',
|
|
||||||
'react-hooks/exhaustive-deps': 'warn',
|
|
||||||
...importPlugin.configs.recommended.rules,
|
|
||||||
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
|
||||||
'react/react-in-jsx-scope': 'off',
|
|
||||||
'import/first': 'warn',
|
|
||||||
'import/default': 'off',
|
|
||||||
'import/newline-after-import': 'warn',
|
|
||||||
'import/no-named-as-default-member': 'off',
|
|
||||||
'import/no-duplicates': 'error',
|
|
||||||
'import/no-named-as-default': 'off',
|
|
||||||
'react/prop-types': 'off',
|
|
||||||
'react/jsx-sort-props': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
callbacksLast: true,
|
|
||||||
shorthandFirst: true,
|
|
||||||
ignoreCase: true,
|
|
||||||
reservedFirst: true,
|
|
||||||
noSortAlphabetically: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/*.{ts,tsx}'],
|
|
||||||
languageOptions: { parser: tsParser },
|
|
||||||
plugins: { '@typescript-eslint': tsPlugin },
|
|
||||||
rules: {
|
|
||||||
...tsPlugin.configs.recommended.rules,
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-unused-vars': 'off',
|
|
||||||
// TypeScript zaten tanimsiz tanimlayicilari yakalar; ESLint'in kapsam
|
|
||||||
// analizi ise `EventListener` / `NotificationOptions` gibi yalnizca tip
|
|
||||||
// olarak var olan DOM global'lerini bilmedigi icin yanlis alarm veriyor.
|
|
||||||
// typescript-eslint'in de onerdigi ayar.
|
|
||||||
'no-undef': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
prettier,
|
|
||||||
// Derleme araclari Node'da CommonJS olarak calisir: tarayici globalleri yerine Node
|
|
||||||
// globalleri gecerlidir ve Tailwind eklentisi `require` ile yuklenir (tailwind.config.ts
|
|
||||||
// Node tarafindan okunur, bundle'a girmez).
|
|
||||||
{
|
|
||||||
files: ['tailwind.config.ts', 'postcss.config.cjs', 'twSafelistGenerator/**/*.js'],
|
|
||||||
languageOptions: {
|
|
||||||
globals: globals.node,
|
|
||||||
sourceType: 'commonjs',
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-require-imports': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
6513
ui/package-lock.json
generated
6513
ui/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -3,8 +3,8 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"elstarVersion": "2.1.6",
|
"elstarVersion": "2.1.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=24.19.0",
|
"node": ">=24.22.0",
|
||||||
"npm": ">=11.19.0"
|
"npm": ">=12.2.0"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
@ -17,82 +17,67 @@
|
||||||
"build:production": "vite build",
|
"build:production": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint": "eslint .",
|
"lint": "oxlint",
|
||||||
"lint:fix": "npm run lint -- --fix",
|
"lint:fix": "oxlint --fix",
|
||||||
"prettier": "prettier --ignore-path .gitignore src --check",
|
"prettier": "prettier --ignore-path .gitignore src --check",
|
||||||
"prettier:fix": "npm run prettier -- --write",
|
"prettier:fix": "npm run prettier -- --write",
|
||||||
"format": "npm run prettier:fix && npm run lint:fix"
|
"format": "npm run prettier:fix && npm run lint:fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/standalone": "^7.29.8",
|
"@babel/standalone": "^8.0.7",
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@floating-ui/react": "^0.27.20",
|
"@floating-ui/react": "^0.27.20",
|
||||||
"@marsidev/react-turnstile": "^1.6.0",
|
"@marsidev/react-turnstile": "^1.6.2",
|
||||||
"@microsoft/signalr": "^10.0.11",
|
"@microsoft/signalr": "^10.0.11",
|
||||||
"@monaco-editor/react": "^4.7.0",
|
"@monaco-editor/react": "^4.7.0",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"axios": "^1.20.0",
|
||||||
"axios": "^1.19.0",
|
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"dayjs": "^1.11.21",
|
"dayjs": "^1.11.23",
|
||||||
"devexpress-reporting-react": "26.1.4",
|
"devexpress-reporting-react": "26.1.5",
|
||||||
"devextreme": "26.1.4",
|
"devextreme": "26.1.5",
|
||||||
"devextreme-exceljs-fork": "^4.4.13",
|
"devextreme-exceljs-fork": "^4.5.0",
|
||||||
"devextreme-react": "26.1.4",
|
"devextreme-react": "26.1.5",
|
||||||
"dompurify": "3.4.13",
|
"dompurify": "3.4.17",
|
||||||
"easy-peasy": "^6.1.1",
|
"easy-peasy": "^6.1.1",
|
||||||
"emoji-picker-react": "^4.19.1",
|
"emoji-picker-react": "^5.0.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"formik": "^2.4.9",
|
"formik": "^2.4.9",
|
||||||
"framer-motion": "^13.1.0",
|
"framer-motion": "^14.3.0",
|
||||||
"jspdf": "^4.2.1",
|
"jspdf": "^4.2.1",
|
||||||
"react": "^19.2.8",
|
"react": "^19.3.1",
|
||||||
"react-advanced-cropper": "^0.20.1",
|
"react-advanced-cropper": "^0.20.1",
|
||||||
"react-arborist": "^3.16.0",
|
"react-dom": "^19.3.1",
|
||||||
"react-dom": "^19.2.8",
|
|
||||||
"react-icons": "^5.7.0",
|
"react-icons": "^5.7.0",
|
||||||
"react-modal": "^3.16.3",
|
"react-modal": "^3.16.3",
|
||||||
"react-router-dom": "^7.18.2",
|
"react-router-dom": "^7.18.4",
|
||||||
"react-select": "^5.10.2",
|
"react-select": "^5.10.2",
|
||||||
"yup": "^1.7.1",
|
"yup": "^1.7.1",
|
||||||
"zxing-wasm": "^3.1.4"
|
"zxing-wasm": "^3.1.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.39.5",
|
|
||||||
"@tailwindcss/typography": "^0.5.20",
|
"@tailwindcss/typography": "^0.5.20",
|
||||||
|
"@tailwindcss/vite": "^4.3.3",
|
||||||
"@types/file-saver": "^2.0.7",
|
"@types/file-saver": "^2.0.7",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.19.2",
|
||||||
"@types/react": "^19.2.18",
|
"@types/react": "^19.3.0",
|
||||||
"@types/react-dom": "^19.2.4",
|
"@types/react-dom": "^19.3.0",
|
||||||
"@types/react-modal": "^3.16.3",
|
"@types/react-modal": "^3.16.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.67.0",
|
"@vitejs/plugin-react": "^6.1.2",
|
||||||
"@typescript-eslint/parser": "^8.67.0",
|
"oxlint": "^1.88.0",
|
||||||
"@vitejs/plugin-react": "^6.0.5",
|
"prettier": "^3.9.10",
|
||||||
"autoprefixer": "^10.5.4",
|
"tailwindcss": "^4.3.3",
|
||||||
"cssnano": "^8.0.5",
|
"typescript": "^7.0.2",
|
||||||
"eslint": "^9.39.5",
|
"vite": "^8.3.4",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"vite-plugin-pwa": "^2.0.0",
|
||||||
"eslint-import-resolver-typescript": "^4.4.5",
|
"workbox-build": "^7.4.1",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"workbox-window": "^7.4.1"
|
||||||
"eslint-plugin-react": "^7.37.5",
|
|
||||||
"eslint-plugin-react-hooks": "^7.1.1",
|
|
||||||
"eslint-plugin-react-refresh": "^0.5.4",
|
|
||||||
"globals": "^17.11.0",
|
|
||||||
"postcss": "^8.5.26",
|
|
||||||
"prettier": "^3.9.6",
|
|
||||||
"tailwindcss": "^3.4.19",
|
|
||||||
"typescript": "5.9",
|
|
||||||
"vite": "^8.2.1",
|
|
||||||
"vite-plugin-pwa": "^1.3.0"
|
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"dompurify": "3.4.13",
|
|
||||||
"glob": "13.0.6",
|
"glob": "13.0.6",
|
||||||
"brace-expansion@1": "1.1.18",
|
"dompurify": "3.4.17",
|
||||||
"brace-expansion@2": "2.1.4",
|
"postcss-selector-parser": "7.1.6",
|
||||||
"brace-expansion@5": "5.0.9",
|
|
||||||
"fast-uri": "3.1.5",
|
|
||||||
"workbox-build": {
|
"workbox-build": {
|
||||||
"source-map": "0.8.0"
|
"source-map": "0.8.0"
|
||||||
},
|
},
|
||||||
|
|
@ -101,7 +86,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "24.19.0",
|
"node": "24.22.0",
|
||||||
"npm": "11.19.0"
|
"npm": "12.2.0"
|
||||||
|
},
|
||||||
|
"allowScripts": {
|
||||||
|
"core-js": false,
|
||||||
|
"unrs-resolver": false,
|
||||||
|
"inferno": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
plugins: {
|
|
||||||
'tailwindcss/nesting': {},
|
|
||||||
tailwindcss: {},
|
|
||||||
autoprefixer: {},
|
|
||||||
cssnano: {},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
4516
ui/safelist.txt
4516
ui/safelist.txt
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,8 @@
|
||||||
|
/* v3 kademelenmesi: preflight ve tema katmanda (en zayif), bilesen stilleri ve utility'ler
|
||||||
|
katmansiz. Katmansiz CSS her katmani yendigi icin bilesen stilleri katmana alinsaydi
|
||||||
|
react-select/DevExtreme gibi stilini katmansiz basan kutuphanelere yenilirdi; utility'ler
|
||||||
|
en sonda oldugu icin esit ozgullukte bilesen stilini ezer. */
|
||||||
|
@import './tailwind/index.css';
|
||||||
@import './components/index.css';
|
@import './components/index.css';
|
||||||
@import './template/index.css';
|
@import './template/index.css';
|
||||||
@import './tailwind/index.css';
|
@import 'tailwindcss/utilities.css' source(none);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
@apply w-full px-3 rounded-lg border border-gray-300 dark:border-gray-600
|
@apply w-full px-3 rounded-lg border border-gray-300 dark:border-gray-600
|
||||||
bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100
|
bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100
|
||||||
placeholder-gray-400 dark:placeholder-gray-500
|
placeholder-gray-400 dark:placeholder-gray-500
|
||||||
focus:outline-none focus:ring-2 focus:border-transparent
|
focus:outline-hidden focus:ring-2 focus:border-transparent
|
||||||
transition-colors duration-150 text-sm;
|
transition-colors duration-150 text-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
.button {
|
.button {
|
||||||
@apply font-semibold focus:outline-none whitespace-nowrap;
|
@apply font-semibold focus:outline-hidden whitespace-nowrap;
|
||||||
|
|
||||||
&.radius-round {
|
&.radius-round {
|
||||||
@apply rounded-md;
|
@apply rounded-md;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-shadow {
|
.card-shadow {
|
||||||
@apply shadow border-b border-gray-200 dark:border-gray-600 dark:border-none;
|
@apply shadow-sm border-b border-gray-200 dark:border-gray-600 dark:border-none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header-border {
|
.card-header-border {
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@
|
||||||
border
|
border
|
||||||
border-gray-300
|
border-gray-300
|
||||||
dark:border-gray-600
|
dark:border-gray-600
|
||||||
rounded
|
rounded-sm
|
||||||
cursor-pointer
|
cursor-pointer
|
||||||
inline-block
|
inline-block
|
||||||
align-middle
|
align-middle
|
||||||
flex-shrink-0
|
shrink-0
|
||||||
p-0
|
p-0
|
||||||
appearance-none
|
appearance-none
|
||||||
transition-colors
|
transition-colors
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
@apply inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-sm
|
@apply inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-sm
|
||||||
bg-indigo-100 dark:bg-indigo-900/40
|
bg-indigo-100 dark:bg-indigo-900/40
|
||||||
text-indigo-700 dark:text-indigo-300
|
text-indigo-700 dark:text-indigo-300
|
||||||
select-none outline-none
|
select-none outline-hidden
|
||||||
focus-visible:ring-2 focus-visible:ring-indigo-500;
|
focus-visible:ring-2 focus-visible:ring-indigo-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,6 +40,6 @@
|
||||||
|
|
||||||
/* Input */
|
/* Input */
|
||||||
.chips-input {
|
.chips-input {
|
||||||
@apply flex-1 min-w-[80px] outline-none bg-transparent text-sm
|
@apply flex-1 min-w-[80px] outline-hidden bg-transparent text-sm
|
||||||
text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500;
|
text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
.close-btn {
|
.close-btn {
|
||||||
@apply outline-none;
|
@apply outline-hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-btn-default {
|
.close-btn-default {
|
||||||
@apply text-xl rounded p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300;
|
@apply text-xl rounded-sm p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sizes */
|
/* Sizes */
|
||||||
.color-picker-sm .color-picker-swatch { @apply w-6 h-6 rounded; }
|
.color-picker-sm .color-picker-swatch { @apply w-6 h-6 rounded-sm; }
|
||||||
.color-picker-lg .color-picker-swatch { @apply w-10 h-10 rounded-lg; }
|
.color-picker-lg .color-picker-swatch { @apply w-10 h-10 rounded-lg; }
|
||||||
.color-picker-xs .color-picker-swatch { @apply w-5 h-5 rounded; }
|
.color-picker-xs .color-picker-swatch { @apply w-5 h-5 rounded-sm; }
|
||||||
|
|
||||||
/* Native hidden input */
|
/* Native hidden input */
|
||||||
.color-picker-native {
|
.color-picker-native {
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
.color-picker-text-input {
|
.color-picker-text-input {
|
||||||
@apply w-full text-sm px-2 py-1 rounded-md border border-gray-300 dark:border-gray-600
|
@apply w-full text-sm px-2 py-1 rounded-md border border-gray-300 dark:border-gray-600
|
||||||
bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-gray-100
|
bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-gray-100
|
||||||
focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent
|
focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:border-transparent
|
||||||
font-mono;
|
font-mono;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@screen sm {
|
@media (width >= theme(--breakpoint-sm)) {
|
||||||
.dialog {
|
.dialog {
|
||||||
@apply max-w-xl;
|
@apply max-w-xl;
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@screen md {
|
@media (width >= theme(--breakpoint-md)) {
|
||||||
.dialog {
|
.dialog {
|
||||||
@apply max-w-2xl;
|
@apply max-w-2xl;
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@screen lg {
|
@media (width >= theme(--breakpoint-lg)) {
|
||||||
.dialog {
|
.dialog {
|
||||||
@apply max-w-4xl;
|
@apply max-w-4xl;
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@screen xl {
|
@media (width >= theme(--breakpoint-xl)) {
|
||||||
.dialog {
|
.dialog {
|
||||||
@apply max-w-6xl;
|
@apply max-w-6xl;
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
@apply p-6 rounded-lg shadow-xl my-4 relative bg-white dark:bg-gray-800 flex flex-col overflow-hidden;
|
@apply p-6 rounded-lg shadow-xl my-4 relative bg-white dark:bg-gray-800 flex flex-col overflow-hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@screen sm {
|
@media (width >= theme(--breakpoint-sm)) {
|
||||||
.dialog-content {
|
.dialog-content {
|
||||||
max-height: calc(100vh - 8rem);
|
max-height: calc(100vh - 8rem);
|
||||||
@apply my-16;
|
@apply my-16;
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
.dialog-header,
|
.dialog-header,
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
@apply flex-shrink-0;
|
@apply shrink-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-body {
|
.dialog-body {
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
|
|
||||||
.dialog-overlay {
|
.dialog-overlay {
|
||||||
transition: all 0.15s ease-in-out;
|
transition: all 0.15s ease-in-out;
|
||||||
@apply bg-opacity-60 inset-0 fixed z-30 bg-black dark:bg-opacity-80;
|
@apply bg-black/60 dark:bg-black/80 inset-0 fixed z-30;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-overlay-after-open {
|
.dialog-overlay-after-open {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
.drawer-overlay {
|
.drawer-overlay {
|
||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
@apply bg-black bg-opacity-80 inset-0 fixed z-30;
|
@apply bg-black/80 inset-0 fixed z-30;
|
||||||
}
|
}
|
||||||
|
|
||||||
.drawer-overlay-after-open {
|
.drawer-overlay-after-open {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
@apply rounded-md shadow-lg bg-white dark:bg-gray-700 dark:shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none p-1.5 absolute z-30;
|
@apply rounded-md shadow-lg bg-white dark:bg-gray-700 dark:shadow-2xl ring-1 ring-black/5 focus:outline-hidden p-1.5 absolute z-30;
|
||||||
|
|
||||||
&.top-start {
|
&.top-start {
|
||||||
@apply ltr:left-0 rtl:right-0 bottom-full origin-bottom;
|
@apply ltr:left-0 rtl:right-0 bottom-full origin-bottom;
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-viewer-toolbar-actions button {
|
.image-viewer-toolbar-actions button {
|
||||||
@apply p-1.5 rounded text-white/70 hover:text-white hover:bg-white/10
|
@apply p-1.5 rounded-sm text-white/70 hover:text-white hover:bg-white/10
|
||||||
transition-colors duration-150;
|
transition-colors duration-150;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-viewer-close {
|
.image-viewer-close {
|
||||||
@apply ml-2 !text-white/90 hover:!text-red-400;
|
@apply ml-2 text-white/90! hover:!text-red-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stage */
|
/* Stage */
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-viewer-thumb {
|
.image-viewer-thumb {
|
||||||
@apply w-14 h-14 rounded overflow-hidden border-2 border-transparent
|
@apply w-14 h-14 rounded-sm overflow-hidden border-2 border-transparent
|
||||||
opacity-50 hover:opacity-80 transition-all duration-150 shrink-0 p-0;
|
opacity-50 hover:opacity-80 transition-all duration-150 shrink-0 p-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
rounded-md
|
rounded-md
|
||||||
w-full
|
w-full
|
||||||
py-2 px-3
|
py-2 px-3
|
||||||
focus:outline-none
|
focus:outline-hidden
|
||||||
focus:ring-1
|
focus:ring-1
|
||||||
focus-within:ring-1
|
focus-within:ring-1
|
||||||
appearance-none
|
appearance-none
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.knob {
|
.knob {
|
||||||
@apply select-none outline-none;
|
@apply select-none outline-hidden;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.menu-item-themed {
|
&.menu-item-themed {
|
||||||
@apply text-gray-100 text-opacity-80;
|
@apply text-gray-100/80;
|
||||||
|
|
||||||
&.menu-item-hoverable {
|
&.menu-item-hoverable {
|
||||||
@apply hover:text-opacity-100 hover:bg-gray-900 hover:bg-opacity-10;
|
@apply hover:text-gray-100 hover:bg-gray-900/10;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.menu-item-active {
|
&.menu-item-active {
|
||||||
@apply text-gray-100 bg-gray-900 bg-opacity-30 hover:bg-opacity-30;
|
@apply text-gray-100 bg-gray-900/30 hover:bg-gray-900/30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.menu-collapse-item-themed {
|
&.menu-collapse-item-themed {
|
||||||
@apply text-gray-100 text-opacity-80 hover:text-opacity-100 hover:bg-gray-900 hover:bg-opacity-10;
|
@apply text-gray-100/80 hover:text-gray-100 hover:bg-gray-900/10;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.menu-collapse-item-transparent {
|
&.menu-collapse-item-transparent {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.menu-title-themed {
|
&.menu-title-themed {
|
||||||
@apply text-gray-100 text-opacity-50;
|
@apply text-gray-100/50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-pager {
|
.pagination-pager {
|
||||||
@apply cursor-pointer relative mx-1 rounded inline-flex items-center h-8 w-8 justify-center text-sm font-semibold select-none;
|
@apply cursor-pointer relative mx-1 rounded-sm inline-flex items-center h-8 w-8 justify-center text-sm font-semibold select-none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-pager-inactive {
|
.pagination-pager-inactive {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
cursor-pointer
|
cursor-pointer
|
||||||
inline-block
|
inline-block
|
||||||
align-middle
|
align-middle
|
||||||
flex-shrink-0
|
shrink-0
|
||||||
p-0
|
p-0
|
||||||
appearance-none
|
appearance-none
|
||||||
transition-colors
|
transition-colors
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
.rate {
|
.rate {
|
||||||
@apply inline-flex items-center select-none outline-none;
|
@apply inline-flex items-center select-none outline-hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rate-star {
|
.rate-star {
|
||||||
|
|
@ -7,5 +7,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.rate-star:focus-visible {
|
.rate-star:focus-visible {
|
||||||
@apply outline-2 outline-offset-2 outline-indigo-500 rounded;
|
@apply outline-2 outline-offset-2 outline-indigo-500 rounded-sm;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
.segment-item-default {
|
.segment-item-default {
|
||||||
@apply font-semibold
|
@apply font-semibold
|
||||||
focus:outline-none
|
focus:outline-hidden
|
||||||
cursor-pointer
|
cursor-pointer
|
||||||
select-none
|
select-none
|
||||||
rounded-md
|
rounded-md
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.select__multi-value {
|
.select__multi-value {
|
||||||
@apply rounded text-sm;
|
@apply rounded-sm text-sm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.select__multi-value {
|
.select__multi-value {
|
||||||
@apply rounded text-xs;
|
@apply rounded-sm text-xs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
|
|
||||||
&.hide-single-value {
|
&.hide-single-value {
|
||||||
.select__single-value {
|
.select__single-value {
|
||||||
@apply !hidden;
|
@apply hidden!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.skeleton-block {
|
.skeleton-block {
|
||||||
@apply rounded h-2.5 w-full;
|
@apply rounded-sm h-2.5 w-full;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
/* Handle */
|
/* Handle */
|
||||||
.slider-handle {
|
.slider-handle {
|
||||||
@apply absolute rounded-full bg-white border-2 border-indigo-500
|
@apply absolute rounded-full bg-white border-2 border-indigo-500
|
||||||
shadow-md cursor-grab z-10 outline-none
|
shadow-md cursor-grab z-10 outline-hidden
|
||||||
focus:ring-2 focus:ring-offset-1 transition-shadow duration-100
|
focus:ring-2 focus:ring-offset-1 transition-shadow duration-100
|
||||||
hover:shadow-lg;
|
hover:shadow-lg;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
@ -74,18 +74,18 @@
|
||||||
px-1.5 py-0.5 text-xs font-medium
|
px-1.5 py-0.5 text-xs font-medium
|
||||||
bg-gray-800 dark:bg-gray-200
|
bg-gray-800 dark:bg-gray-200
|
||||||
text-white dark:text-gray-900
|
text-white dark:text-gray-900
|
||||||
rounded whitespace-nowrap pointer-events-none z-20;
|
rounded-sm whitespace-nowrap pointer-events-none z-20;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider-tooltip::after {
|
.slider-tooltip::after {
|
||||||
content: '';
|
content: '';
|
||||||
@apply absolute left-1/2 -translate-x-1/2 -bottom-1;
|
@apply absolute left-1/2 -translate-x-1/2 -bottom-1;
|
||||||
border: 4px solid transparent;
|
border: 4px solid transparent;
|
||||||
border-top-color: theme('colors.gray.800');
|
border-top-color: var(--color-gray-800);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .slider-tooltip::after {
|
.dark .slider-tooltip::after {
|
||||||
border-top-color: theme('colors.gray.200');
|
border-top-color: var(--color-gray-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Marks */
|
/* Marks */
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.switcher-checked-loading {
|
.switcher-checked-loading {
|
||||||
@apply !text-white;
|
@apply text-white!;
|
||||||
}
|
}
|
||||||
|
|
||||||
.switcher-uncheck-loading {
|
.switcher-uncheck-loading {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
.time-input-field {
|
.time-input-field {
|
||||||
@apply ring-0 w-6 text-center outline-none bg-transparent;
|
@apply ring-0 w-6 text-center outline-hidden bg-transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-input-wrapper {
|
.time-input-wrapper {
|
||||||
|
|
|
||||||
|
|
@ -35,5 +35,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-connect {
|
.timeline-connect {
|
||||||
@apply h-full w-[2px] bg-gray-200 dark:bg-gray-600 flex-grow;
|
@apply h-full w-[2px] bg-gray-200 dark:bg-gray-600 grow;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,103 @@
|
||||||
@tailwind base;
|
@layer theme, base;
|
||||||
@tailwind components;
|
@import 'tailwindcss/theme.css' layer(theme);
|
||||||
@tailwind utilities;
|
@import 'tailwindcss/preflight.css' layer(base);
|
||||||
|
@plugin '@tailwindcss/typography';
|
||||||
|
|
||||||
|
@source '../../../../index.html';
|
||||||
|
@source '../../..';
|
||||||
|
/* Custom Component siniflari: seed dosyasi `ui/` disinda oldugu icin twSafelistGenerator derlemede
|
||||||
|
buraya yazar (vite.config.ts). */
|
||||||
|
@source '../../../../safelist.txt';
|
||||||
|
|
||||||
|
/* Calisma aninda veriden gelen siniflar (renk, olcu); kaynakta gecmedikleri icin derlemeye elle
|
||||||
|
alinir. Renk listesi temanin paletidir (`--color-*`). */
|
||||||
|
@source inline('{,hover:,dark:,dark:hover:}text-{inherit,current,transparent,black,white,{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-{50,{100..900..100},950},sozsoft-{main,secondary,active,x,y}}');
|
||||||
|
@source inline('{,hover:,active:,dark:,dark:hover:,dark:active:}bg-{inherit,current,transparent,black,white,{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-{50,{100..900..100},950},sozsoft-{main,secondary,active,x,y}}');
|
||||||
|
@source inline('{,hover:,focus:,focus-within:}ring-{inherit,current,transparent,black,white,{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-{50,{100..900..100},950},sozsoft-{main,secondary,active,x,y}}');
|
||||||
|
@source inline('{,focus:,focus-within:}border-{inherit,current,transparent,black,white,{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-{50,{100..900..100},950},sozsoft-{main,secondary,active,x,y}}');
|
||||||
|
/* Button iki tonlu koyu tema: renk adi calisma aninda gelir. */
|
||||||
|
@source inline('dark:bg-{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-500/20');
|
||||||
|
@source inline('dark:hover:bg-{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-500/30');
|
||||||
|
@source inline('dark:active:bg-{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}-500/40');
|
||||||
|
@source inline('{h,w,ml,mr}-{0,px,0.5,1,1.2,1.3,1.4,1.5,2,2.5,3,3.5,4,5,6,7,8,9,10,11,12,14,16,20,24,28,32,36,40,44,48,52,56,60,64,72,80,96,auto}');
|
||||||
|
@source inline('{h,w}-{1/2,1/3,2/3,1/4,2/4,3/4,1/5,2/5,3/5,4/5,1/6,2/6,3/6,4/6,5/6,full,screen,min,max,fit}');
|
||||||
|
@source inline('h-{svh,lvh,dvh}');
|
||||||
|
@source inline('w-{1/12,2/12,3/12,4/12,5/12,6/12,7/12,8/12,9/12,10/12,11/12,svw,lvw,dvw}');
|
||||||
|
@source inline('{,hover:,focus:,active:,dark:,sm:,md:,lg:,xl:,2xl:}{container,block,inline-block,inline-flex,hidden,absolute,relative,fixed,sticky,grid,flex,flex-col,flex-row,flex-wrap,truncate,rounded,border,shadow,uppercase,lowercase,capitalize,backdrop-blur,transition,transform}');
|
||||||
|
@source inline('{,sm:,md:,lg:,xl:,2xl:}prose{,-sm,-base,-lg,-xl,-2xl}');
|
||||||
|
@source inline('{,dark:}prose-invert');
|
||||||
|
@source inline('prose-{slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose}');
|
||||||
|
|
||||||
|
/* v4'te kaldirilan adlar: veritabanina daha once kurulmus Custom Component kodu bunlari tasiyabilir
|
||||||
|
(migrate var olan kaydi ezmez). */
|
||||||
|
@utility flex-shrink-0 {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
@utility flex-shrink {
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
@utility flex-grow-0 {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
@utility flex-grow {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
@source inline('{,sm:,md:,lg:,xl:,2xl:}{flex-shrink-0,flex-shrink,flex-grow-0,flex-grow}');
|
||||||
|
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
/* v3 davranisi: hover dokunmatik cihazlarda da calisir. */
|
||||||
|
@custom-variant hover (&:hover);
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-sans: 'Helvetica Neue', 'Segoe UI', helvetica, verdana, sans-serif;
|
||||||
|
|
||||||
|
--color-gray-50: #f8f8f8;
|
||||||
|
--color-gray-100: #eeeeee;
|
||||||
|
--color-gray-200: #d6d6d6;
|
||||||
|
--color-gray-300: #b8b8b8;
|
||||||
|
--color-gray-400: #929292;
|
||||||
|
--color-gray-500: #747474;
|
||||||
|
--color-gray-600: #575757;
|
||||||
|
--color-gray-700: #3f3f3f;
|
||||||
|
--color-gray-800: #303030;
|
||||||
|
--color-gray-900: #252525;
|
||||||
|
--color-gray-950: #1f1f1f;
|
||||||
|
|
||||||
|
--color-sozsoft-main: #ff99c8;
|
||||||
|
--color-sozsoft-secondary: #fcf6bd;
|
||||||
|
--color-sozsoft-active: #d0f4de;
|
||||||
|
--color-sozsoft-x: #a9def9;
|
||||||
|
--color-sozsoft-y: #e4c1f9;
|
||||||
|
|
||||||
|
--spacing-1_2: 0.35rem;
|
||||||
|
--spacing-1_3: 0.4rem;
|
||||||
|
--spacing-1_4: 0.45rem;
|
||||||
|
|
||||||
|
/* v3 varsayilani: renksiz `ring` 3px yari saydam mavi. */
|
||||||
|
--default-ring-width: 3px;
|
||||||
|
--default-ring-color: color-mix(in oklab, var(--color-blue-500) 50%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* v4 onyuklemesinin v3'ten farklari: kenarlik rengi, placeholder rengi, buton imleci. */
|
||||||
|
@layer base {
|
||||||
|
*,
|
||||||
|
::after,
|
||||||
|
::before,
|
||||||
|
::backdrop,
|
||||||
|
::file-selector-button {
|
||||||
|
border-color: var(--color-gray-200, currentcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
input::placeholder,
|
||||||
|
textarea::placeholder {
|
||||||
|
color: var(--color-gray-400);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(:disabled),
|
||||||
|
[role='button']:not(:disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root,
|
:root,
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-action-item-hoverable {
|
.header-action-item-hoverable {
|
||||||
@apply hover:bg-black
|
@apply hover:bg-black/5
|
||||||
hover:bg-opacity-5
|
|
||||||
hover:text-gray-900
|
hover:text-gray-900
|
||||||
dark:hover:bg-black
|
dark:hover:bg-black/40
|
||||||
dark:hover:text-gray-100
|
dark:hover:text-gray-100
|
||||||
dark:hover:bg-opacity-40
|
|
||||||
transition-colors
|
transition-colors
|
||||||
duration-300
|
duration-300
|
||||||
ease-in-out;
|
ease-in-out;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.horizontal-menu-themed .menu-item.horizontal-menu-tab-active {
|
.horizontal-menu-themed .menu-item.horizontal-menu-tab-active {
|
||||||
@apply text-opacity-100;
|
@apply text-gray-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Açılır menü: genel Dropdown'a dokunmadan yalnızca üst menünün panelleri kapsanır. */
|
/* Açılır menü: genel Dropdown'a dokunmadan yalnızca üst menünün panelleri kapsanır. */
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
.side-nav {
|
.side-nav {
|
||||||
@apply flex-col flex-auto flex-shrink-0 z-20 transition-all ease-in-out duration-200 print:hidden;
|
@apply flex-col flex-auto shrink-0 z-20 transition-all ease-in-out duration-200 print:hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-nav-expand {
|
.side-nav-expand {
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-nav-content {
|
.side-nav-content {
|
||||||
height: calc(100vh - theme('spacing.24'));
|
height: calc(100vh - --spacing(24));
|
||||||
@apply overflow-y-auto;
|
@apply overflow-y-auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
.stacked-side-nav {
|
.stacked-side-nav {
|
||||||
@apply flex flex-auto sticky top-0 h-screen flex-shrink-0 z-20 transition-all ease-in-out duration-200 overflow-y-hidden print:hidden;
|
@apply flex flex-auto sticky top-0 h-screen shrink-0 z-20 transition-all ease-in-out duration-200 overflow-y-hidden print:hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stacked-side-nav-content {
|
.stacked-side-nav-content {
|
||||||
height: calc(100vh - theme("spacing.16"));
|
height: calc(100vh - --spacing(16));
|
||||||
@apply overflow-y-auto;
|
@apply overflow-y-auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ export const Splitter: React.FC<SplitterProps> = ({
|
||||||
ref={splitterRef}
|
ref={splitterRef}
|
||||||
className={`
|
className={`
|
||||||
${isHorizontal ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'}
|
${isHorizontal ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'}
|
||||||
bg-gray-300 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 transition-colors duration-200 flex-shrink-0
|
bg-gray-300 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 transition-colors duration-200 shrink-0
|
||||||
${isDragging ? 'bg-blue-500 dark:bg-blue-600' : ''}
|
${isDragging ? 'bg-blue-500 dark:bg-blue-600' : ''}
|
||||||
`}
|
`}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
|
|
@ -120,7 +120,7 @@ export const Splitter: React.FC<SplitterProps> = ({
|
||||||
ref={splitterRef}
|
ref={splitterRef}
|
||||||
className={`
|
className={`
|
||||||
${isHorizontal ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'}
|
${isHorizontal ? 'w-1 cursor-col-resize' : 'h-1 cursor-row-resize'}
|
||||||
bg-gray-300 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 transition-colors duration-200 flex-shrink-0
|
bg-gray-300 dark:bg-gray-700 hover:bg-blue-500 dark:hover:bg-blue-600 transition-colors duration-200 shrink-0
|
||||||
${isDragging ? 'bg-blue-500 dark:bg-blue-600' : ''}
|
${isDragging ? 'bg-blue-500 dark:bg-blue-600' : ''}
|
||||||
`}
|
`}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ const STYLE_GROUPS = {
|
||||||
'truncate',
|
'truncate',
|
||||||
'whitespace-normal',
|
'whitespace-normal',
|
||||||
'whitespace-nowrap',
|
'whitespace-nowrap',
|
||||||
'break-words',
|
'wrap-break-word',
|
||||||
'leading-none',
|
'leading-none',
|
||||||
'leading-tight',
|
'leading-tight',
|
||||||
'leading-normal',
|
'leading-normal',
|
||||||
|
|
@ -263,8 +263,8 @@ const STYLE_GROUPS = {
|
||||||
'border-slate-700',
|
'border-slate-700',
|
||||||
'border-sky-500',
|
'border-sky-500',
|
||||||
'rounded-none',
|
'rounded-none',
|
||||||
|
'rounded-xs',
|
||||||
'rounded-sm',
|
'rounded-sm',
|
||||||
'rounded',
|
|
||||||
'rounded-md',
|
'rounded-md',
|
||||||
'rounded-lg',
|
'rounded-lg',
|
||||||
'rounded-xl',
|
'rounded-xl',
|
||||||
|
|
@ -275,8 +275,8 @@ const STYLE_GROUPS = {
|
||||||
],
|
],
|
||||||
Effects: [
|
Effects: [
|
||||||
'shadow-none',
|
'shadow-none',
|
||||||
|
'shadow-xs',
|
||||||
'shadow-sm',
|
'shadow-sm',
|
||||||
'shadow',
|
|
||||||
'shadow-md',
|
'shadow-md',
|
||||||
'shadow-lg',
|
'shadow-lg',
|
||||||
'shadow-xl',
|
'shadow-xl',
|
||||||
|
|
@ -284,10 +284,10 @@ const STYLE_GROUPS = {
|
||||||
'opacity-50',
|
'opacity-50',
|
||||||
'opacity-75',
|
'opacity-75',
|
||||||
'opacity-100',
|
'opacity-100',
|
||||||
|
'blur-xs',
|
||||||
'blur-sm',
|
'blur-sm',
|
||||||
'blur',
|
'backdrop-blur-xs',
|
||||||
'backdrop-blur-sm',
|
'backdrop-blur-sm',
|
||||||
'backdrop-blur',
|
|
||||||
'transition',
|
'transition',
|
||||||
'transition-all',
|
'transition-all',
|
||||||
'duration-150',
|
'duration-150',
|
||||||
|
|
@ -307,8 +307,8 @@ const STYLE_GROUPS = {
|
||||||
'pointer-events-auto',
|
'pointer-events-auto',
|
||||||
'resize',
|
'resize',
|
||||||
'resize-none',
|
'resize-none',
|
||||||
'outline-none',
|
'outline-hidden',
|
||||||
'focus:outline-none',
|
'focus:outline-hidden',
|
||||||
'hover:opacity-80',
|
'hover:opacity-80',
|
||||||
'hover:bg-slate-100',
|
'hover:bg-slate-100',
|
||||||
'focus:ring-2',
|
'focus:ring-2',
|
||||||
|
|
@ -382,7 +382,7 @@ const StyleModal = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/60 p-4"
|
className="fixed inset-0 z-100 flex items-center justify-center bg-black/60 p-4"
|
||||||
onMouseDown={onClose}
|
onMouseDown={onClose}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
@ -447,7 +447,7 @@ const StyleModal = ({
|
||||||
{translate('::App.StyleModal.EditValueManually', { property: propertyName })}
|
{translate('::App.StyleModal.EditValueManually', { property: propertyName })}
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
className={`w-full rounded-md border border-slate-300 bg-white p-3 font-mono text-xs text-slate-800 outline-none focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-white ${mode === 'css' ? 'min-h-48' : 'min-h-20'}`}
|
className={`w-full rounded-md border border-slate-300 bg-white p-3 font-mono text-xs text-slate-800 outline-hidden focus:border-sky-500 dark:border-slate-700 dark:bg-slate-900 dark:text-white ${mode === 'css' ? 'min-h-48' : 'min-h-20'}`}
|
||||||
placeholder={
|
placeholder={
|
||||||
mode === 'css' ? '.my-class { color: red; }' : 'my-card selected-state md:wide-card'
|
mode === 'css' ? '.my-class { color: red; }' : 'my-card selected-state md:wide-card'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1658,7 +1658,7 @@ export const CUSTOM_COMPONENTS: ComponentDefinition[] = [
|
||||||
rowSpan: 1,
|
rowSpan: 1,
|
||||||
colStart: 1,
|
colStart: 1,
|
||||||
rowStart: 1,
|
rowStart: 1,
|
||||||
className: 'bg-blue-100 p-4 border rounded',
|
className: 'bg-blue-100 p-4 border rounded-sm',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'grid-item-2',
|
id: 'grid-item-2',
|
||||||
|
|
@ -1667,7 +1667,7 @@ export const CUSTOM_COMPONENTS: ComponentDefinition[] = [
|
||||||
rowSpan: 1,
|
rowSpan: 1,
|
||||||
colStart: 2,
|
colStart: 2,
|
||||||
rowStart: 1,
|
rowStart: 1,
|
||||||
className: 'bg-green-100 p-4 border rounded',
|
className: 'bg-green-100 p-4 border rounded-sm',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'grid-item-3',
|
id: 'grid-item-3',
|
||||||
|
|
@ -1676,7 +1676,7 @@ export const CUSTOM_COMPONENTS: ComponentDefinition[] = [
|
||||||
rowSpan: 1,
|
rowSpan: 1,
|
||||||
colStart: 3,
|
colStart: 3,
|
||||||
rowStart: 1,
|
rowStart: 1,
|
||||||
className: 'bg-yellow-100 p-4 border rounded',
|
className: 'bg-yellow-100 p-4 border rounded-sm',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'grid-item-4',
|
id: 'grid-item-4',
|
||||||
|
|
@ -1685,7 +1685,7 @@ export const CUSTOM_COMPONENTS: ComponentDefinition[] = [
|
||||||
rowSpan: 1,
|
rowSpan: 1,
|
||||||
colStart: 1,
|
colStart: 1,
|
||||||
rowStart: 2,
|
rowStart: 2,
|
||||||
className: 'bg-purple-100 p-4 border rounded',
|
className: 'bg-purple-100 p-4 border rounded-sm',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'grid-item-5',
|
id: 'grid-item-5',
|
||||||
|
|
@ -1694,7 +1694,7 @@ export const CUSTOM_COMPONENTS: ComponentDefinition[] = [
|
||||||
rowSpan: 1,
|
rowSpan: 1,
|
||||||
colStart: 3,
|
colStart: 3,
|
||||||
rowStart: 2,
|
rowStart: 2,
|
||||||
className: 'bg-red-100 p-4 border rounded',
|
className: 'bg-red-100 p-4 border rounded-sm',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
category: 'properties',
|
category: 'properties',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
declare module '@babel/standalone' {
|
|
||||||
export function transform(code: string, options?: any): { code: string; map?: any };
|
|
||||||
export function transformSync(code: string, options?: any): { code: string; map?: any };
|
|
||||||
}
|
|
||||||
|
|
@ -70,7 +70,7 @@ export default function Widget({
|
||||||
<div
|
<div
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 flex flex-col justify-between',
|
'bg-white dark:bg-gray-900 rounded-lg shadow-xs border border-gray-200 dark:border-gray-700 p-4 flex flex-col justify-between',
|
||||||
onClick && 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800',
|
onClick && 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
|
|
@ -89,7 +89,7 @@ export default function Widget({
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-12 h-12 bg-gradient-to-br rounded-xl flex items-center justify-center shadow-sm',
|
'w-12 h-12 bg-linear-to-br rounded-xl flex items-center justify-center shadow-xs',
|
||||||
colorMap[safeColor].bg,
|
colorMap[safeColor].bg,
|
||||||
'dark:' + colorMap[safeColor].darkBg
|
'dark:' + colorMap[safeColor].darkBg
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const DevExtremeBoundary = ({ children }: DevExtremeBoundaryProps) => {
|
||||||
|
|
||||||
if (configuredCulture !== cultureName) {
|
if (configuredCulture !== cultureName) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-auto flex-col h-[100vh]">
|
<div className="flex flex-auto flex-col h-screen">
|
||||||
<Loading loading />
|
<Loading loading />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ export const FileUploadArea: React.FC<FileUploadAreaProps> = ({
|
||||||
<div className="border border-gray-200 dark:border-gray-700 rounded-lg p-4 dark:bg-gray-900/40">
|
<div className="border border-gray-200 dark:border-gray-700 rounded-lg p-4 dark:bg-gray-900/40">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center space-x-3 min-w-0 flex-1">
|
<div className="flex items-center space-x-3 min-w-0 flex-1">
|
||||||
<FaFile className="w-8 h-8 text-blue-500 flex-shrink-0" />
|
<FaFile className="w-8 h-8 text-blue-500 shrink-0" />
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="font-medium text-gray-800 dark:text-gray-100 truncate">
|
<div className="font-medium text-gray-800 dark:text-gray-100 truncate">
|
||||||
{selectedFile.name}
|
{selectedFile.name}
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full mt-4">
|
<div className="flex flex-col w-full mt-4">
|
||||||
{/* Navigation Tabs */}
|
{/* Navigation Tabs */}
|
||||||
<div className="flex space-x-1 mb-4 bg-white dark:bg-gray-800 dark:border-gray-800 rounded-lg p-1 shadow-sm border border-gray-200 flex-shrink-0">
|
<div className="flex space-x-1 mb-4 bg-white dark:bg-gray-800 dark:border-gray-800 rounded-lg p-1 shadow-xs border border-gray-200 shrink-0">
|
||||||
{['import', 'preview', 'history'].map((tab) => (
|
{['import', 'preview', 'history'].map((tab) => (
|
||||||
<Button
|
<Button
|
||||||
key={tab}
|
key={tab}
|
||||||
|
|
@ -360,7 +360,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
{/* Template Generator - 2/3 width on large screens, full width on mobile */}
|
{/* Template Generator - 2/3 width on large screens, full width on mobile */}
|
||||||
<div className="lg:col-span-2">
|
<div className="lg:col-span-2">
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700">
|
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-xs border border-gray-200 dark:border-gray-700">
|
||||||
<div className="px-3 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
<div className="px-3 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
|
||||||
<h3 className="text-xl font-semibold text-gray-800 dark:text-gray-100 flex items-center">
|
<h3 className="text-xl font-semibold text-gray-800 dark:text-gray-100 flex items-center">
|
||||||
<FaDownload className="w-4 h-4 mr-2" />
|
<FaDownload className="w-4 h-4 mr-2" />
|
||||||
|
|
@ -471,7 +471,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
|
|
||||||
{/* File Upload - 1/3 width on large screens, full width on mobile */}
|
{/* File Upload - 1/3 width on large screens, full width on mobile */}
|
||||||
<div className="lg:col-span-1">
|
<div className="lg:col-span-1">
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-4 h-full">
|
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-xs border border-gray-200 dark:border-gray-700 p-4 h-full">
|
||||||
<h2 className="text-xl font-semibold text-gray-800 dark:text-gray-100 mb-4 flex items-center">
|
<h2 className="text-xl font-semibold text-gray-800 dark:text-gray-100 mb-4 flex items-center">
|
||||||
<FaUpload className="w-5 h-5 mr-2 text-green-500" />
|
<FaUpload className="w-5 h-5 mr-2 text-green-500" />
|
||||||
{translate('::App.ListFormImportManager.UploadData')}
|
{translate('::App.ListFormImportManager.UploadData')}
|
||||||
|
|
@ -509,7 +509,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-12">
|
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-xs border border-gray-200 dark:border-gray-700 p-12">
|
||||||
<div className="text-center text-gray-500 dark:text-gray-400">
|
<div className="text-center text-gray-500 dark:text-gray-400">
|
||||||
<FaEye className="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-600" />
|
<FaEye className="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-600" />
|
||||||
<div className="text-xl font-medium mb-2">
|
<div className="text-xl font-medium mb-2">
|
||||||
|
|
@ -523,7 +523,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'history' && (
|
{activeTab === 'history' && (
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700">
|
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-xs border border-gray-200 dark:border-gray-700">
|
||||||
<div className="divide-y divide-gray-100 dark:divide-gray-800">
|
<div className="divide-y divide-gray-100 dark:divide-gray-800">
|
||||||
{importHistory.map((session) => (
|
{importHistory.map((session) => (
|
||||||
<div
|
<div
|
||||||
|
|
@ -643,7 +643,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
: 'bg-green-50 text-green-700 border border-green-200 dark:bg-gray-800 dark:text-green-300 dark:border-gray-700'
|
: 'bg-green-50 text-green-700 border border-green-200 dark:bg-gray-800 dark:text-green-300 dark:border-gray-700'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="mt-0.5 flex-shrink-0">
|
<span className="mt-0.5 shrink-0">
|
||||||
{session.status === 'executed_with_errors' ||
|
{session.status === 'executed_with_errors' ||
|
||||||
session.status === 'failed' ||
|
session.status === 'failed' ||
|
||||||
session.status === 'execute_failed' ? (
|
session.status === 'execute_failed' ? (
|
||||||
|
|
@ -660,7 +660,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
|
|
||||||
{/* Execute Details Section */}
|
{/* Execute Details Section */}
|
||||||
{expandedSessions.has(session.id) && (
|
{expandedSessions.has(session.id) && (
|
||||||
<div className="mt-3 bg-gradient-to-r from-indigo-50 to-blue-50 dark:from-gray-800 dark:to-gray-800 border border-indigo-100 dark:border-gray-700 rounded-lg shadow-sm hover:shadow-md transition-shadow">
|
<div className="mt-3 bg-linear-to-r from-indigo-50 to-blue-50 dark:from-gray-800 dark:to-gray-800 border border-indigo-100 dark:border-gray-700 rounded-lg shadow-xs hover:shadow-md transition-shadow">
|
||||||
<div className="p-3">
|
<div className="p-3">
|
||||||
{loadingExecutes.has(session.id) ? (
|
{loadingExecutes.has(session.id) ? (
|
||||||
<div className="flex items-center space-x-2 text-gray-500 dark:text-gray-400 py-2">
|
<div className="flex items-center space-x-2 text-gray-500 dark:text-gray-400 py-2">
|
||||||
|
|
@ -676,7 +676,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
<div key={execute.id} className="p-3 rounded-lg dark:bg-gray-900/40">
|
<div key={execute.id} className="p-3 rounded-lg dark:bg-gray-900/40">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
{/* Sol: Tarih */}
|
{/* Sol: Tarih */}
|
||||||
<div className="flex-shrink-0">
|
<div className="shrink-0">
|
||||||
<div className="text-lg text-gray-500 dark:text-gray-400">
|
<div className="text-lg text-gray-500 dark:text-gray-400">
|
||||||
{new Date(execute.creationTime).toLocaleString()}
|
{new Date(execute.creationTime).toLocaleString()}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -711,7 +711,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Sağ: Status */}
|
{/* Sağ: Status */}
|
||||||
<div className="flex items-center space-x-2 flex-shrink-0">
|
<div className="flex items-center space-x-2 shrink-0">
|
||||||
{getExecuteStatusIcon(execute.status)}
|
{getExecuteStatusIcon(execute.status)}
|
||||||
<div
|
<div
|
||||||
className={`text-xs font-medium ${getExecuteStatusColor(execute.status)}`}
|
className={`text-xs font-medium ${getExecuteStatusColor(execute.status)}`}
|
||||||
|
|
@ -753,7 +753,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{expandedErrors.has(execute.id) && (
|
{expandedErrors.has(execute.id) && (
|
||||||
<div className="mt-2 max-h-48 overflow-y-auto rounded border border-orange-200 bg-orange-50 dark:border-gray-700 dark:bg-gray-800">
|
<div className="mt-2 max-h-48 overflow-y-auto rounded-sm border border-orange-200 bg-orange-50 dark:border-gray-700 dark:bg-gray-800">
|
||||||
{parseErrors(execute.errorsJson).length > 0 ? (
|
{parseErrors(execute.errorsJson).length > 0 ? (
|
||||||
<table className="w-full text-xs">
|
<table className="w-full text-xs">
|
||||||
<thead className="bg-orange-100 dark:bg-gray-800 sticky top-0">
|
<thead className="bg-orange-100 dark:bg-gray-800 sticky top-0">
|
||||||
|
|
|
||||||
|
|
@ -147,12 +147,12 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700">
|
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-xs border border-gray-200 dark:border-gray-700">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="p-3 border-b border-gray-200 dark:border-gray-700">
|
<div className="p-3 border-b border-gray-200 dark:border-gray-700">
|
||||||
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-center gap-4">
|
<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 */}
|
{/* Başlık kısmı - Üstte mobile, solda desktop */}
|
||||||
<div className="flex items-center order-1 lg:order-none">
|
<div className="flex items-center order-1 lg:order-0">
|
||||||
<FaEye 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-gray-800 dark:text-gray-100">
|
<h3 className="text-xl font-semibold text-gray-800 dark:text-gray-100">
|
||||||
{translate('::App.ListFormImportManager.ImportPreviewTitle')}
|
{translate('::App.ListFormImportManager.ImportPreviewTitle')}
|
||||||
|
|
@ -160,7 +160,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* İstatistik kartları - Mobile'da alt alta, desktop'ta yan yana */}
|
{/* İstatistik kartları - Mobile'da alt alta, desktop'ta yan yana */}
|
||||||
<div className="order-3 lg:order-none lg:absolute lg:left-1/2 lg:transform lg:-translate-x-1/2">
|
<div className="order-3 lg:order-0 lg:absolute lg:left-1/2 lg:transform lg:-translate-x-1/2">
|
||||||
<div className="flex flex-col sm:flex-row justify-center gap-2">
|
<div className="flex flex-col sm:flex-row justify-center gap-2">
|
||||||
<div className="text-center px-3 py-1 bg-blue-50 dark:bg-gray-800 rounded-full border border-blue-200 dark:border-gray-700 font-bold text-blue-600 dark:text-blue-300">
|
<div className="text-center px-3 py-1 bg-blue-50 dark:bg-gray-800 rounded-full border border-blue-200 dark:border-gray-700 font-bold text-blue-600 dark:text-blue-300">
|
||||||
{previewData?.rows?.length || session.totalRows || 0}{' '}
|
{previewData?.rows?.length || session.totalRows || 0}{' '}
|
||||||
|
|
@ -172,7 +172,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Durum göstergesi - Altta mobile, sağda desktop */}
|
{/* Durum göstergesi - Altta mobile, sağda desktop */}
|
||||||
<div className="flex justify-center lg:justify-end items-center order-2 lg:order-none lg:ml-auto w-full lg:w-auto">
|
<div className="flex justify-center lg:justify-end items-center order-2 lg:order-0 lg:ml-auto w-full lg:w-auto">
|
||||||
<span
|
<span
|
||||||
className={`px-3 py-1 rounded-full text-sm font-medium border w-full lg:w-auto text-center ${getStatusColor(
|
className={`px-3 py-1 rounded-full text-sm font-medium border w-full lg:w-auto text-center ${getStatusColor(
|
||||||
session.status,
|
session.status,
|
||||||
|
|
@ -201,7 +201,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={selectAll}
|
checked={selectAll}
|
||||||
onChange={handleSelectAll}
|
onChange={handleSelectAll}
|
||||||
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
|
className="rounded-sm border-gray-300 text-blue-600 focus:ring-blue-500"
|
||||||
/>
|
/>
|
||||||
</th>
|
</th>
|
||||||
{previewData.headers.map((header: string, index: number) => (
|
{previewData.headers.map((header: string, index: number) => (
|
||||||
|
|
@ -228,7 +228,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={selectedRows.includes(rowIndex)}
|
checked={selectedRows.includes(rowIndex)}
|
||||||
onChange={() => handleRowSelect(rowIndex)}
|
onChange={() => handleRowSelect(rowIndex)}
|
||||||
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
|
className="rounded-sm border-gray-300 text-blue-600 focus:ring-blue-500"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
{row.map((cell, cellIndex) => (
|
{row.map((cell, cellIndex) => (
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ export const ImportProgress: React.FC<ImportProgressProps> = ({ session }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
<div className="bg-white dark:bg-gray-900 rounded-xl shadow-xs border border-gray-200 dark:border-gray-700 p-6">
|
||||||
<div className="text-center space-y-6">
|
<div className="text-center space-y-6">
|
||||||
{/* Status Icon */}
|
{/* Status Icon */}
|
||||||
<div className="flex justify-center">{getStatusIcon()}</div>
|
<div className="flex justify-center">{getStatusIcon()}</div>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const AuthLayout = () => {
|
||||||
const layoutType = useStoreState((state) => state.theme.layout.type)
|
const layoutType = useStoreState((state) => state.theme.layout.type)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-layout-blank flex flex-auto flex-col h-[100vh]">
|
<div className="app-layout-blank flex flex-auto flex-col h-screen">
|
||||||
{layoutType === LAYOUT_TYPE_BLANK ? (
|
{layoutType === LAYOUT_TYPE_BLANK ? (
|
||||||
<View />
|
<View />
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const ConfiguratorToggle = () => {
|
||||||
|
|
||||||
const BlankLayout = () => {
|
const BlankLayout = () => {
|
||||||
return (
|
return (
|
||||||
<div className="app-layout-blank flex flex-auto flex-col h-[100vh]">
|
<div className="app-layout-blank flex flex-auto flex-col h-screen">
|
||||||
<View />
|
<View />
|
||||||
<ConfiguratorToggle />
|
<ConfiguratorToggle />
|
||||||
<SidePanel className="hidden" />
|
<SidePanel className="hidden" />
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const ClassicLayout = () => {
|
||||||
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
||||||
<Header
|
<Header
|
||||||
container={false}
|
container={false}
|
||||||
className="shadow dark:shadow-2xl"
|
className="shadow-sm dark:shadow-2xl"
|
||||||
headerStart={<HeaderActionsStart />}
|
headerStart={<HeaderActionsStart />}
|
||||||
headerEnd={<HeaderActionsEnd />}
|
headerEnd={<HeaderActionsEnd />}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const DeckedLayout = () => {
|
||||||
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
||||||
<Header
|
<Header
|
||||||
container={false}
|
container={false}
|
||||||
className="shadow dark:shadow-2xl"
|
className="shadow-sm dark:shadow-2xl"
|
||||||
headerStart={<HeaderActionsStart />}
|
headerStart={<HeaderActionsStart />}
|
||||||
headerEnd={<HeaderActionsEnd />}
|
headerEnd={<HeaderActionsEnd />}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ class LayoutChunkErrorBoundary extends Component<{ children: ReactNode }, { fail
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded bg-indigo-600 px-4 py-2 text-sm font-medium text-white"
|
className="rounded-sm bg-indigo-600 px-4 py-2 text-sm font-medium text-white"
|
||||||
onClick={() => window.location.reload()}
|
onClick={() => window.location.reload()}
|
||||||
>
|
>
|
||||||
Reload
|
Reload
|
||||||
|
|
@ -145,7 +145,7 @@ const Layout = () => {
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-auto flex-col h-[100vh]">
|
<div className="flex flex-auto flex-col h-screen">
|
||||||
<Loading loading />
|
<Loading loading />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -158,7 +158,7 @@ const Layout = () => {
|
||||||
<SkipToContent />
|
<SkipToContent />
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<div className="flex flex-auto flex-col h-[100vh]">
|
<div className="flex flex-auto flex-col h-screen">
|
||||||
<Loading loading />
|
<Loading loading />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ const PublicLayout = () => {
|
||||||
{isComponentRegistered(PUBLIC_HEADER_COMPONENT) &&
|
{isComponentRegistered(PUBLIC_HEADER_COMPONENT) &&
|
||||||
renderComponent(PUBLIC_HEADER_COMPONENT)}
|
renderComponent(PUBLIC_HEADER_COMPONENT)}
|
||||||
|
|
||||||
<main className="flex-grow" id="main-content">
|
<main className="grow" id="main-content">
|
||||||
<View />
|
<View />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const SimpleLayout = () => {
|
||||||
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
||||||
<Header
|
<Header
|
||||||
container={false}
|
container={false}
|
||||||
className="shadow dark:shadow-2xl"
|
className="shadow-sm dark:shadow-2xl"
|
||||||
headerStart={<HeaderActionsStart />}
|
headerStart={<HeaderActionsStart />}
|
||||||
headerMiddle={<HorizontalNav />}
|
headerMiddle={<HorizontalNav />}
|
||||||
headerEnd={<HeaderActionsEnd />}
|
headerEnd={<HeaderActionsEnd />}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ const StackedSideLayout = () => {
|
||||||
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
<div className="flex flex-col flex-auto min-h-screen min-w-0 relative w-full">
|
||||||
<Header
|
<Header
|
||||||
container={false}
|
container={false}
|
||||||
className="shadow dark:shadow-2xl"
|
className="shadow-sm dark:shadow-2xl"
|
||||||
headerStart={<HeaderActionsStart />}
|
headerStart={<HeaderActionsStart />}
|
||||||
headerEnd={<HeaderActionsEnd />}
|
headerEnd={<HeaderActionsEnd />}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export const Basket: React.FC<BasketProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-50 overflow-hidden">
|
<div className="fixed inset-0 z-50 overflow-hidden">
|
||||||
<div className="absolute inset-0 bg-black bg-opacity-50" onClick={onClose} />
|
<div className="absolute inset-0 bg-black/50" onClick={onClose} />
|
||||||
|
|
||||||
<div className="absolute right-0 top-0 h-full w-full max-w-md bg-white shadow-xl dark:bg-gray-900">
|
<div className="absolute right-0 top-0 h-full w-full max-w-md bg-white shadow-xl dark:bg-gray-900">
|
||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ export const BillingControls: React.FC<BillingControlsProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`sticky z-20 bg-white border-b border-gray-200 shadow-sm mb-6 transition-all duration-300 dark:border-gray-800 dark:bg-gray-900 dark:shadow-gray-950/40 ${
|
className={`sticky z-20 bg-white border-b border-gray-200 shadow-xs mb-6 transition-all duration-300 dark:border-gray-800 dark:bg-gray-900 dark:shadow-gray-950/40 ${
|
||||||
isScrolled ? 'top-[6rem]' : 'top-[6.5rem]'
|
isScrolled ? 'top-24' : 'top-26'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-2">
|
<div className="p-2">
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ba
|
||||||
<form onSubmit={handleSubmit} className="flex flex-col lg:flex-row gap-6">
|
<form onSubmit={handleSubmit} className="flex flex-col lg:flex-row gap-6">
|
||||||
{/* 3 Sütun: Ödeme Yöntemi | Taksit Seçenekleri | Sipariş Özeti */}
|
{/* 3 Sütun: Ödeme Yöntemi | Taksit Seçenekleri | Sipariş Özeti */}
|
||||||
<div className="w-full lg:w-1/3 flex flex-col gap-6">
|
<div className="w-full lg:w-1/3 flex flex-col gap-6">
|
||||||
<div className="bg-white rounded-xl shadow border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
<div className="bg-white rounded-xl shadow-sm border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center text-gray-900 dark:text-gray-100">
|
<h2 className="text-lg font-semibold mb-4 flex items-center text-gray-900 dark:text-gray-100">
|
||||||
<FaCalendarAlt className="w-5 h-5 text-green-600 mr-2" />
|
<FaCalendarAlt className="w-5 h-5 text-green-600 mr-2" />
|
||||||
Lisans Bilgileri
|
Lisans Bilgileri
|
||||||
|
|
@ -198,7 +198,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ba
|
||||||
|
|
||||||
<div className="w-full lg:w-1/3 flex flex-col gap-6">
|
<div className="w-full lg:w-1/3 flex flex-col gap-6">
|
||||||
{/* 1. Sütun: Ödeme Yöntemi */}
|
{/* 1. Sütun: Ödeme Yöntemi */}
|
||||||
<div className="bg-white rounded-xl shadow border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
<div className="bg-white rounded-xl shadow-sm border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
||||||
<h2 className="text-lg font-semibold mb-4 flex items-center">
|
<h2 className="text-lg font-semibold mb-4 flex items-center">
|
||||||
<FaLock className="w-5 h-5 text-green-600 mr-2" />{' '}
|
<FaLock className="w-5 h-5 text-green-600 mr-2" />{' '}
|
||||||
{translate('::App.Listform.ListformField.PaymentMethodId')}
|
{translate('::App.Listform.ListformField.PaymentMethodId')}
|
||||||
|
|
@ -209,7 +209,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ba
|
||||||
key={method.id}
|
key={method.id}
|
||||||
className={`group flex items-center gap-3 rounded-xl border p-4 cursor-pointer transition-all ${
|
className={`group flex items-center gap-3 rounded-xl border p-4 cursor-pointer transition-all ${
|
||||||
selectedPaymentMethod === method.name
|
selectedPaymentMethod === method.name
|
||||||
? 'border-blue-500 bg-blue-50 shadow-sm ring-1 ring-blue-500/20 dark:border-blue-400 dark:bg-blue-950/30 dark:ring-blue-400/20'
|
? 'border-blue-500 bg-blue-50 shadow-xs ring-1 ring-blue-500/20 dark:border-blue-400 dark:bg-blue-950/30 dark:ring-blue-400/20'
|
||||||
: 'border-gray-200 bg-white hover:border-blue-300 hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-950/40 dark:hover:border-blue-500 dark:hover:bg-gray-800/70'
|
: 'border-gray-200 bg-white hover:border-blue-300 hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-950/40 dark:hover:border-blue-500 dark:hover:bg-gray-800/70'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|
@ -257,7 +257,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ba
|
||||||
|
|
||||||
{/* Taksit Seçenekleri */}
|
{/* Taksit Seçenekleri */}
|
||||||
{selectedPaymentMethod === defaultPaymentMethod && (
|
{selectedPaymentMethod === defaultPaymentMethod && (
|
||||||
<div className="bg-white rounded-xl shadow border p-4 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
<div className="bg-white rounded-xl shadow-sm border p-4 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
||||||
<h3 className="text-md font-medium text-gray-800 dark:text-gray-100 mb-2">
|
<h3 className="text-md font-medium text-gray-800 dark:text-gray-100 mb-2">
|
||||||
{translate('::App.Orders.InstallmentOptions')}
|
{translate('::App.Orders.InstallmentOptions')}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
@ -309,7 +309,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ba
|
||||||
<div className="w-full lg:w-1/3 flex flex-col gap-6">
|
<div className="w-full lg:w-1/3 flex flex-col gap-6">
|
||||||
{/* Kart Bilgileri */}
|
{/* Kart Bilgileri */}
|
||||||
{selectedPaymentMethod === defaultPaymentMethod && (
|
{selectedPaymentMethod === defaultPaymentMethod && (
|
||||||
<div className="bg-white rounded-xl shadow border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40 space-y-3">
|
<div className="bg-white rounded-xl shadow-sm border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40 space-y-3">
|
||||||
<h3 className="text-md font-medium text-gray-800 dark:text-gray-100 mb-3">
|
<h3 className="text-md font-medium text-gray-800 dark:text-gray-100 mb-3">
|
||||||
{translate('::App.PaymentCard.CardTitle')}
|
{translate('::App.PaymentCard.CardTitle')}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
@ -358,7 +358,7 @@ export const PaymentForm: React.FC<PaymentFormProps> = ({ onBack, onComplete, ba
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Sipariş Özeti ve Butonlar */}
|
{/* Sipariş Özeti ve Butonlar */}
|
||||||
<div className="bg-white rounded-xl shadow border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
<div className="bg-white rounded-xl shadow-sm border p-6 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
||||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
<h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
|
||||||
{translate('::App.PaymentSummary.SummaryTitle')}
|
{translate('::App.PaymentSummary.SummaryTitle')}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ export const ProductCard: React.FC<ProductCardProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden hover:shadow-lg transition-all duration-300 group flex flex-col h-full dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
<div className="bg-white rounded-xl shadow-xs border border-gray-200 overflow-hidden hover:shadow-lg transition-all duration-300 group flex flex-col h-full dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
||||||
{product.imageUrl && (
|
{product.imageUrl && (
|
||||||
<div className="aspect-video overflow-hidden">
|
<div className="aspect-video overflow-hidden">
|
||||||
<img
|
<img
|
||||||
|
|
|
||||||
|
|
@ -88,8 +88,8 @@ export const ProductCatalog: React.FC<ProductCatalogProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row gap-8">
|
<div className="flex flex-col lg:flex-row gap-8">
|
||||||
<aside className="lg:w-64 flex-shrink-0">
|
<aside className="lg:w-64 shrink-0">
|
||||||
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-2 sticky top-40 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
<div className="bg-white rounded-lg shadow-xs border border-gray-200 p-2 sticky top-40 dark:border-gray-700 dark:bg-gray-900 dark:shadow-gray-950/40">
|
||||||
<div className="flex items-center space-x-2 mb-4">
|
<div className="flex items-center space-x-2 mb-4">
|
||||||
<FaFilter className="w-5 h-5 text-gray-600 dark:text-gray-300" />
|
<FaFilter className="w-5 h-5 text-gray-600 dark:text-gray-300" />
|
||||||
<h3 className="font-semibold text-gray-900 dark:text-gray-100">
|
<h3 className="font-semibold text-gray-900 dark:text-gray-100">
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleCustomerTypeChange(true)}
|
onClick={() => handleCustomerTypeChange(true)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
className={`relative block h-auto w-full p-4 border-2 rounded-xl transition-all text-left select-none shadow-sm ${
|
className={`relative block h-auto w-full p-4 border-2 rounded-xl transition-all text-left select-none shadow-xs ${
|
||||||
isExisting === true
|
isExisting === true
|
||||||
? 'border-blue-600 bg-blue-100 shadow-lg ring-4 ring-blue-200 scale-[1.02] dark:border-sky-400 dark:bg-sky-950/60 dark:ring-sky-500/30'
|
? 'border-blue-600 bg-blue-100 shadow-lg ring-4 ring-blue-200 scale-[1.02] dark:border-sky-400 dark:bg-sky-950/60 dark:ring-sky-500/30'
|
||||||
: 'border-gray-200 bg-white hover:border-blue-400 hover:bg-blue-50/60 dark:border-gray-700 dark:bg-gray-800/70 dark:hover:border-sky-500 dark:hover:bg-sky-950/30'
|
: 'border-gray-200 bg-white hover:border-blue-400 hover:bg-blue-50/60 dark:border-gray-700 dark:bg-gray-800/70 dark:hover:border-sky-500 dark:hover:bg-sky-950/30'
|
||||||
|
|
@ -586,7 +586,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
<Button
|
<Button
|
||||||
onClick={() => handleCustomerTypeChange(false)}
|
onClick={() => handleCustomerTypeChange(false)}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
className={`relative block h-auto w-full p-4 border-2 rounded-xl transition-all text-left select-none shadow-sm ${
|
className={`relative block h-auto w-full p-4 border-2 rounded-xl transition-all text-left select-none shadow-xs ${
|
||||||
isExisting === false
|
isExisting === false
|
||||||
? 'border-blue-600 bg-blue-100 shadow-lg ring-4 ring-blue-200 scale-[1.02] dark:border-sky-400 dark:bg-sky-950/60 dark:ring-sky-500/30'
|
? 'border-blue-600 bg-blue-100 shadow-lg ring-4 ring-blue-200 scale-[1.02] dark:border-sky-400 dark:bg-sky-950/60 dark:ring-sky-500/30'
|
||||||
: 'border-gray-200 bg-white hover:border-blue-400 hover:bg-blue-50/60 dark:border-gray-700 dark:bg-gray-800/70 dark:hover:border-sky-500 dark:hover:bg-sky-950/30'
|
: 'border-gray-200 bg-white hover:border-blue-400 hover:bg-blue-50/60 dark:border-gray-700 dark:bg-gray-800/70 dark:hover:border-sky-500 dark:hover:bg-sky-950/30'
|
||||||
|
|
@ -641,7 +641,7 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
icon={<FaSearch className="w-4 h-4" />}
|
icon={<FaSearch className="w-4 h-4" />}
|
||||||
variant="solid"
|
variant="solid"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="!h-[40px] min-w-[180px] sm:mr-2 sm:rounded-r-lg sm:rounded-l-none [&>span]:gap-2"
|
className="h-[40px]! min-w-[180px] sm:mr-2 sm:rounded-r-lg sm:rounded-l-none [&>span]:gap-2"
|
||||||
>
|
>
|
||||||
{isLoadingTenant
|
{isLoadingTenant
|
||||||
? translate('::App.Tenant.Searching')
|
? translate('::App.Tenant.Searching')
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ interface PublicThemeToggleProps {
|
||||||
|
|
||||||
export const PublicThemeToggle = ({
|
export const PublicThemeToggle = ({
|
||||||
className = 'inline-flex h-9 items-center rounded-lg p-0.5',
|
className = 'inline-flex h-9 items-center rounded-lg p-0.5',
|
||||||
buttonClassName = '!h-8 !w-8 xl:!w-auto !px-0 xl:!px-2.5 !border-transparent !shadow-none !bg-transparent !text-gray-300 hover:!bg-transparent hover:!text-white',
|
buttonClassName = 'h-8! w-8! xl:w-auto! px-0! xl:px-2.5! border-transparent! shadow-none! bg-transparent! text-gray-300! hover:bg-transparent! hover:text-white!',
|
||||||
activeClassName = '!bg-white !text-gray-950',
|
activeClassName = 'bg-white! text-gray-950!',
|
||||||
iconSize = 15,
|
iconSize = 15,
|
||||||
}: PublicThemeToggleProps) => {
|
}: PublicThemeToggleProps) => {
|
||||||
const [isDarkMode, setThemeMode] = useDarkMode()
|
const [isDarkMode, setThemeMode] = useDarkMode()
|
||||||
|
|
@ -99,14 +99,14 @@ export const PublicThemeToggle = ({
|
||||||
active: !isDarkMode,
|
active: !isDarkMode,
|
||||||
title: '::App.Theme.LightMode',
|
title: '::App.Theme.LightMode',
|
||||||
icon: <LuSun size={iconSize} strokeWidth={1.8} />,
|
icon: <LuSun size={iconSize} strokeWidth={1.8} />,
|
||||||
shape: '!rounded-l-md !rounded-r-none',
|
shape: 'rounded-l-md! rounded-r-none!',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mode: THEME_ENUM.MODE_DARK,
|
mode: THEME_ENUM.MODE_DARK,
|
||||||
active: isDarkMode,
|
active: isDarkMode,
|
||||||
title: '::App.Theme.DarkMode',
|
title: '::App.Theme.DarkMode',
|
||||||
icon: <LuMoon size={iconSize} strokeWidth={1.8} />,
|
icon: <LuMoon size={iconSize} strokeWidth={1.8} />,
|
||||||
shape: '!rounded-r-md !rounded-l-none',
|
shape: 'rounded-r-md! rounded-l-none!',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ export const PublicDemoButton = ({ className = '' }: { className?: string }) =>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
className={`group !h-9 !w-9 !overflow-visible !bg-transparent !px-0 !text-gray-200 !shadow-none transition-colors hover:!bg-transparent hover:!text-white ${className}`}
|
className={`group h-9! w-9! overflow-visible! bg-transparent! px-0! text-gray-200! shadow-none! transition-colors hover:bg-transparent! hover:text-white! ${className}`}
|
||||||
size="sm"
|
size="sm"
|
||||||
type="button"
|
type="button"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
|
|
@ -147,9 +147,9 @@ export const PublicDemoButton = ({ className = '' }: { className?: string }) =>
|
||||||
closeMobileMenu?.()
|
closeMobileMenu?.()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="relative inline-flex h-7 w-7 items-center justify-center overflow-visible rounded-full border-2 border-stone-700 bg-gradient-to-b from-red-400 via-red-600 to-red-800 shadow-[inset_0_-3px_6px_rgba(0,0,0,0.35),0_1px_3px_rgba(0,0,0,0.35)] ring-1 ring-black/60 transition-all duration-200 group-hover:scale-105 group-hover:from-red-300 group-hover:via-red-500 group-hover:to-red-700 group-hover:shadow-[inset_0_-3px_6px_rgba(0,0,0,0.3),0_2px_8px_rgba(239,68,68,0.35)]">
|
<span className="relative inline-flex h-7 w-7 items-center justify-center overflow-visible rounded-full border-2 border-stone-700 bg-linear-to-b from-red-400 via-red-600 to-red-800 shadow-[inset_0_-3px_6px_rgba(0,0,0,0.35),0_1px_3px_rgba(0,0,0,0.35)] ring-1 ring-black/60 transition-all duration-200 group-hover:scale-105 group-hover:from-red-300 group-hover:via-red-500 group-hover:to-red-700 group-hover:shadow-[inset_0_-3px_6px_rgba(0,0,0,0.3),0_2px_8px_rgba(239,68,68,0.35)]">
|
||||||
<span className="absolute inset-x-1 top-1 h-2 rounded-full bg-white/35 blur-[1px] transition-colors group-hover:bg-white/50" />
|
<span className="absolute inset-x-1 top-1 h-2 rounded-full bg-white/35 blur-[1px] transition-colors group-hover:bg-white/50" />
|
||||||
<span className="absolute left-1/2 top-1/2 z-10 w-12 -translate-x-1/2 -translate-y-1/2 text-center uppercase leading-none tracking-tight text-white drop-shadow">
|
<span className="absolute left-1/2 top-1/2 z-10 w-12 -translate-x-1/2 -translate-y-1/2 text-center uppercase leading-none tracking-tight text-white drop-shadow-sm">
|
||||||
{translate('::App.Demos')}
|
{translate('::App.Demos')}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -276,7 +276,7 @@ export const PublicNav = ({
|
||||||
return (
|
return (
|
||||||
<div key={item.code} className="group/menu relative">
|
<div key={item.code} className="group/menu relative">
|
||||||
{renderItem(item)}
|
{renderItem(item)}
|
||||||
<div className="invisible absolute left-0 top-full z-20 min-w-[13rem] rounded-lg border border-white/10 bg-gray-950/98 py-2 opacity-0 shadow-xl backdrop-blur-md transition-all duration-150 group-hover/menu:visible group-hover/menu:opacity-100">
|
<div className="invisible absolute left-0 top-full z-20 min-w-52 rounded-lg border border-white/10 bg-gray-950/98 py-2 opacity-0 shadow-xl backdrop-blur-md transition-all duration-150 group-hover/menu:visible group-hover/menu:opacity-100">
|
||||||
{item.children.map((child) => renderItem(child, 'px-4 py-2'))}
|
{item.children.map((child) => renderItem(child, 'px-4 py-2'))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,10 @@ export type ScriptBuilderDialogProps = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const controlClass =
|
const controlClass =
|
||||||
'w-full min-w-0 h-8 px-2 rounded border border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-100 focus:outline-none focus:border-indigo-400'
|
'w-full min-w-0 h-8 px-2 rounded-sm border border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-100 focus:outline-hidden focus:border-indigo-400'
|
||||||
|
|
||||||
const cardClass =
|
const cardClass =
|
||||||
'rounded-lg border border-gray-200 bg-white shadow-sm dark:border-gray-700 dark:bg-gray-900'
|
'rounded-lg border border-gray-200 bg-white shadow-xs dark:border-gray-700 dark:bg-gray-900'
|
||||||
|
|
||||||
const editorOptions = {
|
const editorOptions = {
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
|
|
@ -427,7 +427,7 @@ function ScriptBuilderDialog({
|
||||||
}))
|
}))
|
||||||
|
|
||||||
/** Ayar satirindaki her alan ayni yukseklikte, dar panelde alt satira sarar. */
|
/** Ayar satirindaki her alan ayni yukseklikte, dar panelde alt satira sarar. */
|
||||||
const fieldClass = 'min-w-0 basis-[9.5rem] grow'
|
const fieldClass = 'min-w-0 basis-38 grow'
|
||||||
|
|
||||||
const fieldLabel = (text: string, title?: string) => (
|
const fieldLabel = (text: string, title?: string) => (
|
||||||
<span className="mb-1 block truncate text-xs text-gray-500" title={title}>
|
<span className="mb-1 block truncate text-xs text-gray-500" title={title}>
|
||||||
|
|
@ -446,7 +446,7 @@ function ScriptBuilderDialog({
|
||||||
return (
|
return (
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
{index > 0 ? (
|
{index > 0 ? (
|
||||||
<label className="min-w-0 basis-[6.5rem] grow-0">
|
<label className="min-w-0 basis-26 grow-0">
|
||||||
{fieldLabel(translate('::App.ScriptBuilder.Conjunction'))}
|
{fieldLabel(translate('::App.ScriptBuilder.Conjunction'))}
|
||||||
<Select
|
<Select
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
@ -574,14 +574,14 @@ function ScriptBuilderDialog({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{conditions.length > 1 && (
|
{conditions.length > 1 && (
|
||||||
<span className="shrink-0 rounded-full bg-violet-100 px-2 py-[1px] text-[11px] text-violet-700 dark:bg-violet-900 dark:text-violet-200">
|
<span className="shrink-0 rounded-full bg-violet-100 px-2 py-px text-[11px] text-violet-700 dark:bg-violet-900 dark:text-violet-200">
|
||||||
{translate('::App.ScriptBuilder.ConditionCount', { count: conditions.length })} ·{' '}
|
{translate('::App.ScriptBuilder.ConditionCount', { count: conditions.length })} ·{' '}
|
||||||
{translate(rule.join === 'or' ? '::App.Platform.Or' : '::App.Platform.And')}
|
{translate(rule.join === 'or' ? '::App.Platform.Or' : '::App.Platform.And')}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{triggerInfo && trigger !== dialect.triggers?.[0]?.value && (
|
{triggerInfo && trigger !== dialect.triggers?.[0]?.value && (
|
||||||
<span
|
<span
|
||||||
className="shrink-0 rounded-full bg-sky-100 px-2 py-[1px] text-[11px] text-sky-700 dark:bg-sky-900 dark:text-sky-200"
|
className="shrink-0 rounded-full bg-sky-100 px-2 py-px text-[11px] text-sky-700 dark:bg-sky-900 dark:text-sky-200"
|
||||||
title={triggerInfo.help}
|
title={triggerInfo.help}
|
||||||
>
|
>
|
||||||
{triggerInfo.label}
|
{triggerInfo.label}
|
||||||
|
|
@ -589,7 +589,7 @@ function ScriptBuilderDialog({
|
||||||
)}
|
)}
|
||||||
{!complete && (
|
{!complete && (
|
||||||
<span
|
<span
|
||||||
className="flex shrink-0 items-center gap-1 rounded-full bg-amber-100 px-2 py-[1px] text-[11px] text-amber-700 dark:bg-amber-900 dark:text-amber-200"
|
className="flex shrink-0 items-center gap-1 rounded-full bg-amber-100 px-2 py-px text-[11px] text-amber-700 dark:bg-amber-900 dark:text-amber-200"
|
||||||
title={
|
title={
|
||||||
dialect.getRuleWarning?.(rule) ||
|
dialect.getRuleWarning?.(rule) ||
|
||||||
translate('::App.ScriptBuilder.IncompleteRuleWarning')
|
translate('::App.ScriptBuilder.IncompleteRuleWarning')
|
||||||
|
|
@ -671,7 +671,7 @@ function ScriptBuilderDialog({
|
||||||
{recipe.params.map((param) => renderParam(rule, param))}
|
{recipe.params.map((param) => renderParam(rule, param))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<pre className="mt-3 overflow-x-auto rounded border border-gray-100 bg-gray-950 px-3 py-2 font-mono text-[11px] text-emerald-100 dark:border-gray-800">
|
<pre className="mt-3 overflow-x-auto rounded-sm border border-gray-100 bg-gray-950 px-3 py-2 font-mono text-[11px] text-emerald-100 dark:border-gray-800">
|
||||||
{dialect.buildRuleLine(rule, rules) || recipe.example}
|
{dialect.buildRuleLine(rule, rules) || recipe.example}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -686,7 +686,7 @@ function ScriptBuilderDialog({
|
||||||
<FaSearch className="text-gray-400" size={11} />
|
<FaSearch className="text-gray-400" size={11} />
|
||||||
<Input
|
<Input
|
||||||
unstyle
|
unstyle
|
||||||
className="w-full min-w-0 bg-transparent text-xs text-gray-700 outline-none dark:text-gray-100"
|
className="w-full min-w-0 bg-transparent text-xs text-gray-700 outline-hidden dark:text-gray-100"
|
||||||
placeholder={translate('::App.ScriptBuilder.SearchHelp')}
|
placeholder={translate('::App.ScriptBuilder.SearchHelp')}
|
||||||
value={helpSearch}
|
value={helpSearch}
|
||||||
onChange={(event) => setHelpSearch(event.target.value)}
|
onChange={(event) => setHelpSearch(event.target.value)}
|
||||||
|
|
@ -710,7 +710,7 @@ function ScriptBuilderDialog({
|
||||||
<button
|
<button
|
||||||
key={snippet.label}
|
key={snippet.label}
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded border border-gray-100 px-2 py-1.5 text-left hover:border-indigo-300 hover:bg-indigo-50 dark:border-gray-800 dark:hover:bg-gray-800"
|
className="rounded-sm border border-gray-100 px-2 py-1.5 text-left hover:border-indigo-300 hover:bg-indigo-50 dark:border-gray-800 dark:hover:bg-gray-800"
|
||||||
title={`${snippet.description}\n\n${snippet.code}`}
|
title={`${snippet.description}\n\n${snippet.code}`}
|
||||||
onClick={() => insertAtCursor(editorRef.current, snippet.code)}
|
onClick={() => insertAtCursor(editorRef.current, snippet.code)}
|
||||||
>
|
>
|
||||||
|
|
@ -734,7 +734,7 @@ function ScriptBuilderDialog({
|
||||||
<button
|
<button
|
||||||
key={entry.signature}
|
key={entry.signature}
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded px-1 py-1 text-left hover:bg-indigo-50 dark:hover:bg-gray-800"
|
className="rounded-sm px-1 py-1 text-left hover:bg-indigo-50 dark:hover:bg-gray-800"
|
||||||
title={entry.description}
|
title={entry.description}
|
||||||
onClick={() => insertAtCursor(editorRef.current, apiEntryName(entry))}
|
onClick={() => insertAtCursor(editorRef.current, apiEntryName(entry))}
|
||||||
>
|
>
|
||||||
|
|
@ -767,10 +767,10 @@ function ScriptBuilderDialog({
|
||||||
{/*
|
{/*
|
||||||
Yükseklik zinciri iki yerden kopuyordu: Dialog'un `height` prop'u yalnızca
|
Yükseklik zinciri iki yerden kopuyordu: Dialog'un `height` prop'u yalnızca
|
||||||
react-modal içeriğine uygulanıyor, ve `.dialog-body` global olarak `flex-1`
|
react-modal içeriğine uygulanıyor, ve `.dialog-body` global olarak `flex-1`
|
||||||
alıyor. `!flex-none` ile flex boyutlandırmasını kapatıp yüksekliği
|
alıyor. `flex-none!` ile flex boyutlandırmasını kapatıp yüksekliği
|
||||||
doğrudan veriyoruz.
|
doğrudan veriyoruz.
|
||||||
*/}
|
*/}
|
||||||
<Dialog.Body className="flex h-[calc(100vh-16rem)] max-h-[calc(90vh-7rem)] min-h-[320px] !flex-none flex-col gap-3 !overflow-hidden mt-5">
|
<Dialog.Body className="flex h-[calc(100vh-16rem)] max-h-[calc(90vh-7rem)] min-h-[320px] flex-none! flex-col gap-3 overflow-hidden! mt-5">
|
||||||
<div className="flex flex-wrap items-center gap-2 border-b border-gray-200 pb-3 dark:border-gray-700">
|
<div className="flex flex-wrap items-center gap-2 border-b border-gray-200 pb-3 dark:border-gray-700">
|
||||||
<FaCode className="text-indigo-500" />
|
<FaCode className="text-indigo-500" />
|
||||||
<h5 className="mr-1">{dialect.title}</h5>
|
<h5 className="mr-1">{dialect.title}</h5>
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ const AdaptableCard = (props: AdaptableCardProps) => {
|
||||||
type === LAYOUT_TYPE_MODERN && 'border-0',
|
type === LAYOUT_TYPE_MODERN && 'border-0',
|
||||||
type === LAYOUT_TYPE_MODERN &&
|
type === LAYOUT_TYPE_MODERN &&
|
||||||
rightSideBorder &&
|
rightSideBorder &&
|
||||||
'ltr:border-r-0 rtl:border-l-0 ltr:md:border-r rtl:md:border-l md:border-gray-200 md:dark:border-gray-600 rounded-tr-none rounded-br-none rtl:rounded-tr-none rtl:rounded-br-none',
|
'ltr:border-r-0 rtl:border-l-0 md:ltr:border-r md:rtl:border-l md:border-gray-200 md:dark:border-gray-600 rounded-tr-none rounded-br-none rtl:rounded-tr-none rtl:rounded-br-none',
|
||||||
type === LAYOUT_TYPE_MODERN &&
|
type === LAYOUT_TYPE_MODERN &&
|
||||||
leftSideBorder &&
|
leftSideBorder &&
|
||||||
'ltr:border-l-0 rtl:border-r-0 ltr:md:border-l rtl:md:border-r md:border-gray-200 md:dark:border-gray-600 rounded-tl-none rounded-bl-none rtl:rounded-tl-none rtl:rounded-bl-none',
|
'ltr:border-l-0 rtl:border-r-0 md:ltr:border-l md:rtl:border-r md:border-gray-200 md:dark:border-gray-600 rounded-tl-none rounded-bl-none rtl:rounded-tl-none rtl:rounded-bl-none',
|
||||||
type === LAYOUT_TYPE_MODERN &&
|
type === LAYOUT_TYPE_MODERN &&
|
||||||
divider &&
|
divider &&
|
||||||
`${
|
`${
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ const BarcodeScannerDialog = ({
|
||||||
<p className="mb-1 text-sm font-semibold">
|
<p className="mb-1 text-sm font-semibold">
|
||||||
{translate('::App.BarcodeScanner.ScannedCount')}: {scanned.length}
|
{translate('::App.BarcodeScanner.ScannedCount')}: {scanned.length}
|
||||||
</p>
|
</p>
|
||||||
<ul className="max-h-32 overflow-auto rounded border text-sm">
|
<ul className="max-h-32 overflow-auto rounded-sm border text-sm">
|
||||||
{scanned.map((code, index) => (
|
{scanned.map((code, index) => (
|
||||||
<li key={`${code}-${index}`} className="border-b px-2 py-1 last:border-b-0">
|
<li key={`${code}-${index}`} className="border-b px-2 py-1 last:border-b-0">
|
||||||
{code}
|
{code}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const BarcodeViewer = ({
|
||||||
// kaçışlanarak yazılır, bu yüzden gömmek güvenlidir.
|
// kaçışlanarak yazılır, bu yüzden gömmek güvenlidir.
|
||||||
dangerouslySetInnerHTML={{ __html: svg }}
|
dangerouslySetInnerHTML={{ __html: svg }}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'inline-block rounded bg-white p-2',
|
'inline-block rounded-sm bg-white p-2',
|
||||||
fitWidth && 'block w-full [&>svg]:h-auto [&>svg]:w-full',
|
fitWidth && 'block w-full [&>svg]:h-auto [&>svg]:w-full',
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,306 +0,0 @@
|
||||||
import type { CheckboxProps } from '@/components/ui/Checkbox'
|
|
||||||
import Checkbox from '@/components/ui/Checkbox'
|
|
||||||
import Pagination from '@/components/ui/Pagination'
|
|
||||||
import Select from '@/components/ui/Select'
|
|
||||||
import type { SkeletonProps } from '@/components/ui/Skeleton'
|
|
||||||
import Table from '@/components/ui/Table'
|
|
||||||
import {
|
|
||||||
CellContext,
|
|
||||||
ColumnDef,
|
|
||||||
ColumnSort,
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getFilteredRowModel,
|
|
||||||
getPaginationRowModel,
|
|
||||||
getSortedRowModel,
|
|
||||||
Row,
|
|
||||||
useReactTable,
|
|
||||||
} from '@tanstack/react-table'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
import type { ChangeEvent, ForwardedRef } from 'react'
|
|
||||||
import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
|
|
||||||
import TableRowSkeleton from './loaders/TableRowSkeleton'
|
|
||||||
import Loading from './Loading'
|
|
||||||
|
|
||||||
export type OnSortParam = { order: 'asc' | 'desc' | ''; key: string | number }
|
|
||||||
|
|
||||||
type DataTableProps<T> = {
|
|
||||||
columns: ColumnDef<T>[]
|
|
||||||
data?: unknown[]
|
|
||||||
loading?: boolean
|
|
||||||
onCheckBoxChange?: (checked: boolean, row: T) => void
|
|
||||||
onIndeterminateCheckBoxChange?: (checked: boolean, rows: Row<T>[]) => void
|
|
||||||
onPaginationChange?: (page: number) => void
|
|
||||||
onSelectChange?: (num: number) => void
|
|
||||||
onSort?: (sort: OnSortParam) => void
|
|
||||||
pageSizes?: number[]
|
|
||||||
selectable?: boolean
|
|
||||||
skeletonAvatarColumns?: number[]
|
|
||||||
skeletonAvatarProps?: SkeletonProps
|
|
||||||
pagingData?: {
|
|
||||||
total: number
|
|
||||||
pageIndex: number
|
|
||||||
pageSize: number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type CheckBoxChangeEvent = ChangeEvent<HTMLInputElement>
|
|
||||||
|
|
||||||
interface IndeterminateCheckboxProps extends Omit<CheckboxProps, 'onChange'> {
|
|
||||||
onChange: (event: CheckBoxChangeEvent) => void
|
|
||||||
indeterminate: boolean
|
|
||||||
onCheckBoxChange?: (event: CheckBoxChangeEvent) => void
|
|
||||||
onIndeterminateCheckBoxChange?: (event: CheckBoxChangeEvent) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
const { Tr, Th, Td, THead, TBody, Sorter } = Table
|
|
||||||
|
|
||||||
const IndeterminateCheckbox = (props: IndeterminateCheckboxProps) => {
|
|
||||||
const { indeterminate, onChange, onCheckBoxChange, onIndeterminateCheckBoxChange, ...rest } =
|
|
||||||
props
|
|
||||||
|
|
||||||
const ref = useRef<HTMLInputElement>(null)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof indeterminate === 'boolean' && ref.current) {
|
|
||||||
ref.current.indeterminate = !rest.checked && indeterminate
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [ref, indeterminate])
|
|
||||||
|
|
||||||
const handleChange = (e: CheckBoxChangeEvent) => {
|
|
||||||
onChange(e)
|
|
||||||
onCheckBoxChange?.(e)
|
|
||||||
onIndeterminateCheckBoxChange?.(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Checkbox ref={ref} className="mb-0" onChange={(_, e) => handleChange(e)} {...rest} />
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DataTableResetHandle = {
|
|
||||||
resetSorting: () => void
|
|
||||||
resetSelected: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
function DataTableBase<T>(props: DataTableProps<T>, ref: ForwardedRef<DataTableResetHandle>) {
|
|
||||||
const {
|
|
||||||
skeletonAvatarColumns,
|
|
||||||
columns: columnsProp = [],
|
|
||||||
data = [],
|
|
||||||
loading = false,
|
|
||||||
onCheckBoxChange,
|
|
||||||
onIndeterminateCheckBoxChange,
|
|
||||||
onPaginationChange,
|
|
||||||
onSelectChange,
|
|
||||||
onSort,
|
|
||||||
pageSizes = [10, 25, 50, 100],
|
|
||||||
selectable = false,
|
|
||||||
skeletonAvatarProps,
|
|
||||||
pagingData = {
|
|
||||||
total: 0,
|
|
||||||
pageIndex: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
},
|
|
||||||
} = props
|
|
||||||
|
|
||||||
const { pageSize, pageIndex, total } = pagingData
|
|
||||||
|
|
||||||
const [sorting, setSorting] = useState<ColumnSort[] | null>(null)
|
|
||||||
|
|
||||||
const pageSizeOption = useMemo(
|
|
||||||
() =>
|
|
||||||
pageSizes.map((number) => ({
|
|
||||||
value: number,
|
|
||||||
label: `${number} / page`,
|
|
||||||
})),
|
|
||||||
[pageSizes],
|
|
||||||
)
|
|
||||||
|
|
||||||
const handleCheckBoxChange = (checked: boolean, row: T) => {
|
|
||||||
if (!loading) {
|
|
||||||
onCheckBoxChange?.(checked, row)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleIndeterminateCheckBoxChange = (checked: boolean, rows: Row<T>[]) => {
|
|
||||||
if (!loading) {
|
|
||||||
onIndeterminateCheckBoxChange?.(checked, rows)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePaginationChange = (page: number) => {
|
|
||||||
if (!loading) {
|
|
||||||
onPaginationChange?.(page)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSelectChange = (value?: number) => {
|
|
||||||
if (!loading) {
|
|
||||||
onSelectChange?.(Number(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (Array.isArray(sorting)) {
|
|
||||||
const sortOrder = sorting.length > 0 ? (sorting[0].desc ? 'desc' : 'asc') : ''
|
|
||||||
const id = sorting.length > 0 ? sorting[0].id : ''
|
|
||||||
onSort?.({ order: sortOrder, key: id })
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [sorting])
|
|
||||||
|
|
||||||
const finalColumns: ColumnDef<T>[] = useMemo(() => {
|
|
||||||
const columns = columnsProp
|
|
||||||
|
|
||||||
if (selectable) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
id: 'select',
|
|
||||||
header: ({ table }) => (
|
|
||||||
<IndeterminateCheckbox
|
|
||||||
checked={table.getIsAllRowsSelected()}
|
|
||||||
indeterminate={table.getIsSomeRowsSelected()}
|
|
||||||
onChange={table.getToggleAllRowsSelectedHandler()}
|
|
||||||
onIndeterminateCheckBoxChange={(e) => {
|
|
||||||
handleIndeterminateCheckBoxChange(e.target.checked, table.getRowModel().rows)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<IndeterminateCheckbox
|
|
||||||
checked={row.getIsSelected()}
|
|
||||||
disabled={!row.getCanSelect()}
|
|
||||||
indeterminate={row.getIsSomeSelected()}
|
|
||||||
onChange={row.getToggleSelectedHandler()}
|
|
||||||
onCheckBoxChange={(e) => handleCheckBoxChange(e.target.checked, row.original)}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
...columns,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
return columns
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [columnsProp, selectable])
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
data,
|
|
||||||
columns: finalColumns as ColumnDef<unknown | object | any[], any>[],
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
getFilteredRowModel: getFilteredRowModel(),
|
|
||||||
getPaginationRowModel: getPaginationRowModel(),
|
|
||||||
getSortedRowModel: getSortedRowModel(),
|
|
||||||
manualPagination: true,
|
|
||||||
manualSorting: true,
|
|
||||||
onSortingChange: (sorter) => {
|
|
||||||
setSorting(sorter as ColumnSort[])
|
|
||||||
},
|
|
||||||
// Satir secimi tablonun kendi durumunda tutulur. Disaridan kontrol edilen bir
|
|
||||||
// `rowSelection` degeri `onRowSelectionChange` olmadan degisimi yutuyor, onay kutusu
|
|
||||||
// hicbir zaman isaretlenmiyordu; secilen satirlari cagiran taraf `onCheckBoxChange`
|
|
||||||
// ile zaten kendi durumunda biriktiriyor.
|
|
||||||
state: {
|
|
||||||
sorting: sorting as ColumnSort[],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const resetSorting = () => {
|
|
||||||
table.resetSorting()
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetSelected = () => {
|
|
||||||
table.toggleAllRowsSelected(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
resetSorting,
|
|
||||||
resetSelected,
|
|
||||||
}))
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Loading loading={loading && data.length !== 0} type="cover">
|
|
||||||
<Table>
|
|
||||||
<THead>
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
|
||||||
<Tr key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header) => {
|
|
||||||
return (
|
|
||||||
<Th key={header.id} colSpan={header.colSpan}>
|
|
||||||
{header.isPlaceholder ? null : (
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
header.column.getCanSort() && 'cursor-pointer select-none point',
|
|
||||||
loading && 'pointer-events-none',
|
|
||||||
)}
|
|
||||||
onClick={header.column.getToggleSortingHandler()}
|
|
||||||
>
|
|
||||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
||||||
{header.column.getCanSort() && (
|
|
||||||
<Sorter sort={header.column.getIsSorted()} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Th>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</THead>
|
|
||||||
{loading && data.length === 0 ? (
|
|
||||||
<TableRowSkeleton
|
|
||||||
columns={(finalColumns as Array<T>).length}
|
|
||||||
rows={pagingData.pageSize}
|
|
||||||
avatarInColumns={skeletonAvatarColumns}
|
|
||||||
avatarProps={skeletonAvatarProps}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<TBody>
|
|
||||||
{table
|
|
||||||
.getRowModel()
|
|
||||||
.rows.slice(0, pageSize)
|
|
||||||
.map((row) => {
|
|
||||||
return (
|
|
||||||
<Tr key={row.id}>
|
|
||||||
{row.getVisibleCells().map((cell) => {
|
|
||||||
return (
|
|
||||||
<Td key={cell.id}>
|
|
||||||
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
||||||
</Td>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Tr>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</TBody>
|
|
||||||
)}
|
|
||||||
</Table>
|
|
||||||
<div className="flex items-center justify-between mt-4">
|
|
||||||
<Pagination
|
|
||||||
pageSize={pageSize}
|
|
||||||
currentPage={pageIndex}
|
|
||||||
total={total}
|
|
||||||
onChange={handlePaginationChange}
|
|
||||||
/>
|
|
||||||
<div style={{ minWidth: 130 }}>
|
|
||||||
<Select
|
|
||||||
size="sm"
|
|
||||||
menuPlacement="top"
|
|
||||||
isSearchable={false}
|
|
||||||
value={pageSizeOption.filter((option) => option.value === pageSize)}
|
|
||||||
options={pageSizeOption}
|
|
||||||
onChange={(option) => handleSelectChange(option?.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Loading>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const DataTable = forwardRef(DataTableBase) as <T>(
|
|
||||||
props: DataTableProps<T> & {
|
|
||||||
ref?: ForwardedRef<DataTableResetHandle>
|
|
||||||
},
|
|
||||||
) => ReturnType<typeof DataTableBase>
|
|
||||||
|
|
||||||
export type { CellContext, ColumnDef, Row }
|
|
||||||
export default DataTable
|
|
||||||
|
|
@ -46,7 +46,7 @@ function DbMigrateLogPanel({ title, onClose }: DbMigrateLogPanelProps) {
|
||||||
}, [logs])
|
}, [logs])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/60">
|
<div className="fixed inset-0 z-9999 flex items-center justify-center bg-black/60">
|
||||||
<div className="flex flex-col w-[900px] max-w-[95vw] h-[520px] max-h-[90vh] rounded-xl shadow-2xl bg-gray-900 border border-gray-700">
|
<div className="flex flex-col w-[900px] max-w-[95vw] h-[520px] max-h-[90vh] rounded-xl shadow-2xl bg-gray-900 border border-gray-700">
|
||||||
<div className="flex items-center justify-between px-4 py-3 border-b border-gray-700">
|
<div className="flex items-center justify-between px-4 py-3 border-b border-gray-700">
|
||||||
<span className="text-white font-semibold text-sm">{title}</span>
|
<span className="text-white font-semibold text-sm">{title}</span>
|
||||||
|
|
@ -59,7 +59,7 @@ function DbMigrateLogPanel({ title, onClose }: DbMigrateLogPanelProps) {
|
||||||
<Button
|
<Button
|
||||||
variant="default"
|
variant="default"
|
||||||
size="xs"
|
size="xs"
|
||||||
className="!bg-gray-800 !border-gray-600 !text-gray-300 hover:!bg-gray-700 hover:!border-gray-400 hover:!text-white"
|
className="bg-gray-800! border-gray-600! text-gray-300! hover:bg-gray-700! hover:border-gray-400! hover:text-white!"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
|
|
@ -68,7 +68,7 @@ function DbMigrateLogPanel({ title, onClose }: DbMigrateLogPanelProps) {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 overflow-y-auto p-3 font-mono text-xs leading-relaxed">
|
<div className="flex-1 overflow-y-auto p-3 font-mono text-xs leading-relaxed">
|
||||||
{logs.map((log, i) => (
|
{logs.map((log, i) => (
|
||||||
<div key={i} className={`whitespace-pre-wrap break-words ${levelColor(log.level)}`}>
|
<div key={i} className={`whitespace-pre-wrap wrap-break-word ${levelColor(log.level)}`}>
|
||||||
<span className="text-gray-500 mr-2 select-none">{String(i + 1).padStart(4, '0')}</span>
|
<span className="text-gray-500 mr-2 select-none">{String(i + 1).padStart(4, '0')}</span>
|
||||||
{log.message}
|
{log.message}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const CoveredLoading = (props: BaseLoadingProps) => {
|
||||||
<Component className={classNames(loading ? 'relative' : '', className)}>
|
<Component className={classNames(loading ? 'relative' : '', className)}>
|
||||||
{children}
|
{children}
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="w-full h-full bg-white dark:bg-gray-800 dark:bg-opacity-60 bg-opacity-50 absolute inset-0" />
|
<div className="w-full h-full bg-white/50 dark:bg-gray-800/60 absolute inset-0" />
|
||||||
)}
|
)}
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-10">
|
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-10">
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ const withCode = (text: string, keyPrefix: string): ReactNode[] =>
|
||||||
const rest = part.slice(trimmed.length)
|
const rest = part.slice(trimmed.length)
|
||||||
return (
|
return (
|
||||||
<Fragment key={`${keyPrefix}-c${index}`}>
|
<Fragment key={`${keyPrefix}-c${index}`}>
|
||||||
<code className="rounded bg-gray-100 px-1 py-0.5 font-mono text-[0.9em] text-gray-800 dark:bg-gray-700 dark:text-gray-100">
|
<code className="rounded-sm bg-gray-100 px-1 py-0.5 font-mono text-[0.9em] text-gray-800 dark:bg-gray-700 dark:text-gray-100">
|
||||||
{trimmed}
|
{trimmed}
|
||||||
</code>
|
</code>
|
||||||
{rest}
|
{rest}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,11 @@ export { default as BarcodeViewer } from './BarcodeViewer'
|
||||||
export { default as PermissionCheck } from './PermissionCheck'
|
export { default as PermissionCheck } from './PermissionCheck'
|
||||||
export { default as ConfirmDialog } from './ConfirmDialog'
|
export { default as ConfirmDialog } from './ConfirmDialog'
|
||||||
export { default as Container } from './Container'
|
export { default as Container } from './Container'
|
||||||
export { default as DataTable } from './DataTable'
|
|
||||||
export { default as DoubleSidedImage } from './DoubleSidedImage'
|
export { default as DoubleSidedImage } from './DoubleSidedImage'
|
||||||
export { default as Loading } from './Loading'
|
export { default as Loading } from './Loading'
|
||||||
export { default as NavToggle } from './NavToggle'
|
export { default as NavToggle } from './NavToggle'
|
||||||
export { default as PasswordInput } from './PasswordInput'
|
export { default as PasswordInput } from './PasswordInput'
|
||||||
export { default as RichText } from './RichText'
|
export { default as RichText } from './RichText'
|
||||||
export { default as SegmentItemOption } from './SegmentItemOption'
|
export { default as SegmentItemOption } from './SegmentItemOption'
|
||||||
export { default as TableRowSkeleton } from './loaders/TableRowSkeleton'
|
|
||||||
export { default as TenantSelector } from './TenantSelector'
|
export { default as TenantSelector } from './TenantSelector'
|
||||||
|
|
||||||
export type { DataTableResetHandle, OnSortParam, ColumnDef, Row, CellContext } from './DataTable'
|
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import Skeleton from '@/components/ui/Skeleton'
|
|
||||||
import Table from '@/components/ui/Table'
|
|
||||||
import type { SkeletonProps } from '@/components/ui/Skeleton'
|
|
||||||
|
|
||||||
type TableRowSkeletonProps = {
|
|
||||||
columns?: number
|
|
||||||
rows?: number
|
|
||||||
avatarInColumns?: number[]
|
|
||||||
avatarProps?: SkeletonProps
|
|
||||||
}
|
|
||||||
|
|
||||||
const { Tr, Td, TBody } = Table
|
|
||||||
|
|
||||||
const TableRowSkeleton = (props: TableRowSkeletonProps) => {
|
|
||||||
const { columns = 1, rows = 10, avatarInColumns = [], avatarProps } = props
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TBody>
|
|
||||||
{Array.from(new Array(rows), (_, i) => i + 0).map((row) => (
|
|
||||||
<Tr key={`row-${row}`}>
|
|
||||||
{Array.from(new Array(columns), (_, i) => i + 0).map(
|
|
||||||
(col) => (
|
|
||||||
<Td key={`col-${col}`}>
|
|
||||||
<div className="flex flex-auto items-center gap-2">
|
|
||||||
{avatarInColumns.includes(col) && (
|
|
||||||
<div>
|
|
||||||
<Skeleton
|
|
||||||
variant="circle"
|
|
||||||
{...avatarProps}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<Skeleton />
|
|
||||||
</div>
|
|
||||||
</Td>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</TBody>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TableRowSkeleton
|
|
||||||
|
|
@ -50,7 +50,7 @@ const LanguageSelectorBase = ({ className }: CommonProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown renderTitle={selectedLanguage} placement="bottom-start" menuClass="z-[60]">
|
<Dropdown renderTitle={selectedLanguage} placement="bottom-start" menuClass="z-60">
|
||||||
{languageList?.map((lang) => (
|
{languageList?.map((lang) => (
|
||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
key={lang.cultureName}
|
key={lang.cultureName}
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
if (!auth.session.signedIn || !location.pathname.startsWith('/admin')) return null
|
if (!auth.session.signedIn || !location.pathname.startsWith('/admin')) return null
|
||||||
|
|
||||||
const panelClassName =
|
const panelClassName =
|
||||||
'pointer-events-auto fixed inset-2 z-[51] overflow-hidden rounded-xl border border-gray-200 bg-white/80 shadow-[0_24px_80px_rgba(15,23,42,0.35)] backdrop-blur-xl dark:border-gray-700 dark:bg-gray-900/85 sm:inset-4'
|
'pointer-events-auto fixed inset-2 z-51 overflow-hidden rounded-xl border border-gray-200 bg-white/80 shadow-[0_24px_80px_rgba(15,23,42,0.35)] backdrop-blur-xl dark:border-gray-700 dark:bg-gray-900/85 sm:inset-4'
|
||||||
|
|
||||||
const headerActionClassName =
|
const headerActionClassName =
|
||||||
'text-gray-600 hover:bg-gray-900/10 hover:text-gray-900 active:bg-gray-900/15 dark:text-gray-200 dark:hover:bg-white/10 dark:hover:text-white dark:active:bg-white/15'
|
'text-gray-600 hover:bg-gray-900/10 hover:text-gray-900 active:bg-gray-900/15 dark:text-gray-200 dark:hover:bg-white/10 dark:hover:text-white dark:active:bg-white/15'
|
||||||
|
|
@ -380,7 +380,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
aria-label={translate('::App.MessengerWidget.Minimize')}
|
aria-label={translate('::App.MessengerWidget.Minimize')}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
className="fixed inset-0 z-50 !h-auto cursor-default bg-slate-950/25 !px-0 backdrop-blur-[1px] hover:!bg-slate-950/25 active:!bg-slate-950/25 dark:bg-black/55 dark:hover:!bg-black/55 dark:active:!bg-black/55"
|
className="fixed inset-0 z-50 h-auto! cursor-default bg-slate-950/25 px-0! backdrop-blur-[1px] hover:bg-slate-950/25! active:bg-slate-950/25! dark:bg-black/55 dark:hover:bg-black/55! dark:active:bg-black/55!"
|
||||||
onClick={closeWidget}
|
onClick={closeWidget}
|
||||||
/>
|
/>
|
||||||
<div className={panelClassName} role="dialog" aria-modal="true">
|
<div className={panelClassName} role="dialog" aria-modal="true">
|
||||||
|
|
@ -429,7 +429,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 p-3">
|
<div className="flex items-center gap-2 p-3">
|
||||||
<div className="min-w-0 flex-[6]">
|
<div className="min-w-0 flex-6">
|
||||||
<Input
|
<Input
|
||||||
size="sm"
|
size="sm"
|
||||||
value={filter}
|
value={filter}
|
||||||
|
|
@ -465,7 +465,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
block
|
block
|
||||||
className={`mb-1 !flex !h-auto items-center gap-3 !rounded-md !px-2 !py-2 text-left transition ${
|
className={`mb-1 !flex h-auto! items-center gap-3 rounded-md! px-2! py-2! text-left transition ${
|
||||||
active
|
active
|
||||||
? 'bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-100'
|
? 'bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-100'
|
||||||
: 'hover:bg-white dark:hover:bg-gray-800'
|
: 'hover:bg-white dark:hover:bg-gray-800'
|
||||||
|
|
@ -593,7 +593,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
className={`group flex max-w-[76%] items-start gap-1.5 ${own ? 'flex-row-reverse' : ''}`}
|
className={`group flex max-w-[76%] items-start gap-1.5 ${own ? 'flex-row-reverse' : ''}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`rounded-lg px-3 py-2 shadow-sm ${
|
className={`rounded-lg px-3 py-2 shadow-xs ${
|
||||||
own
|
own
|
||||||
? 'bg-emerald-600 text-white'
|
? 'bg-emerald-600 text-white'
|
||||||
: 'bg-gray-100 text-gray-900 dark:bg-gray-700 dark:text-gray-100'
|
: 'bg-gray-100 text-gray-900 dark:bg-gray-700 dark:text-gray-100'
|
||||||
|
|
@ -660,7 +660,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<FaTrash />}
|
icon={<FaTrash />}
|
||||||
className="mt-1 !h-5 !w-5 shrink-0 !px-0 text-[10px] text-gray-400 opacity-0 transition hover:!bg-red-500 hover:text-white group-hover:opacity-100 focus:opacity-100"
|
className="mt-1 h-5! w-5! shrink-0 px-0! text-[10px] text-gray-400 opacity-0 transition hover:bg-red-500! hover:text-white group-hover:opacity-100 focus:opacity-100"
|
||||||
onClick={() => deleteMessage(message.id)}
|
onClick={() => deleteMessage(message.id)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -685,7 +685,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<FaTrash />}
|
icon={<FaTrash />}
|
||||||
className="!h-5 !w-5 shrink-0 !px-0 text-gray-500 hover:text-red-500"
|
className="h-5! w-5! shrink-0 px-0! text-gray-500 hover:text-red-500"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAttachments((prev) =>
|
setAttachments((prev) =>
|
||||||
prev.filter((item) => item.savedFileName !== file.savedFileName),
|
prev.filter((item) => item.savedFileName !== file.savedFileName),
|
||||||
|
|
@ -703,9 +703,10 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
<div className="absolute bottom-16 left-2 z-10 sm:left-10">
|
<div className="absolute bottom-16 left-2 z-10 sm:left-10">
|
||||||
<Suspense fallback={<div className="h-[380px] w-[320px] max-w-[calc(100vw-32px)]" />}>
|
<Suspense fallback={<div className="h-[380px] w-[320px] max-w-[calc(100vw-32px)]" />}>
|
||||||
<EmojiPicker
|
<EmojiPicker
|
||||||
onEmojiClick={onEmojiClick}
|
emojiStyle="apple"
|
||||||
width="min(320px, calc(100vw - 32px))"
|
|
||||||
height={380}
|
height={380}
|
||||||
|
width="min(320px, calc(100vw - 32px))"
|
||||||
|
onEmojiClick={onEmojiClick}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -751,7 +752,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
}
|
}
|
||||||
rows={1}
|
rows={1}
|
||||||
disabled={!canSendToSelectedContacts}
|
disabled={!canSendToSelectedContacts}
|
||||||
className="min-h-[36px] flex-1 resize-none border-0 bg-transparent px-2 py-2 text-sm text-gray-900 outline-none placeholder:text-gray-400 focus:ring-0 dark:text-gray-100"
|
className="min-h-[36px] flex-1 resize-none border-0 bg-transparent px-2 py-2 text-sm text-gray-900 outline-hidden placeholder:text-gray-400 focus:ring-0 dark:text-gray-100"
|
||||||
onChange={(event) => setText(event.target.value)}
|
onChange={(event) => setText(event.target.value)}
|
||||||
onKeyDown={(event) => {
|
onKeyDown={(event) => {
|
||||||
if (event.key === 'Enter' && !event.shiftKey) {
|
if (event.key === 'Enter' && !event.shiftKey) {
|
||||||
|
|
@ -785,7 +786,7 @@ const MessengerWidgetContent = ({ className }: { className?: string }) => {
|
||||||
className={classNames(
|
className={classNames(
|
||||||
className,
|
className,
|
||||||
textTheme,
|
textTheme,
|
||||||
'pointer-events-auto relative !mx-0 text-2xl transition-colors duration-300 ease-in-out hover:bg-black hover:bg-opacity-5 dark:hover:bg-black dark:hover:bg-opacity-40',
|
'pointer-events-auto relative mx-0! text-2xl transition-colors duration-300 ease-in-out hover:bg-black/5 dark:hover:bg-black/40',
|
||||||
)}
|
)}
|
||||||
aria-label={translate('::App.MessengerWidget.Title')}
|
aria-label={translate('::App.MessengerWidget.Title')}
|
||||||
role="button"
|
role="button"
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ type NotificationListItem = {
|
||||||
readed: boolean
|
readed: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const notificationHeight = 'h-[26rem]'
|
const notificationHeight = 'h-104'
|
||||||
/** SignalR duyurusu kaybolursa devreye giren yedek yoklama aralığı. */
|
/** SignalR duyurusu kaybolursa devreye giren yedek yoklama aralığı. */
|
||||||
const notificationInterval = 300000 // 5 minutes
|
const notificationInterval = 300000 // 5 minutes
|
||||||
const foregroundPollThrottle = 30000 // 30 seconds
|
const foregroundPollThrottle = 30000 // 30 seconds
|
||||||
|
|
@ -416,7 +416,7 @@ const NotificationDropdown = ({ className }: { className?: string }) => {
|
||||||
{notificationList.map((item, index) => (
|
{notificationList.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
key={item.ids[0]}
|
key={item.ids[0]}
|
||||||
className={`relative flex px-4 py-4 cursor-pointer hover:bg-gray-50 active:bg-gray-100 dark:hover:bg-black dark:hover:bg-opacity-20 ${
|
className={`relative flex px-4 py-4 cursor-pointer hover:bg-gray-50 active:bg-gray-100 dark:hover:bg-black/20 ${
|
||||||
!isLastChild(notificationList, index)
|
!isLastChild(notificationList, index)
|
||||||
? 'border-b border-gray-200 dark:border-gray-600'
|
? 'border-b border-gray-200 dark:border-gray-600'
|
||||||
: ''
|
: ''
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ const ListItem = (props: {
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
{/* <div
|
{/* <div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'mr-4 rounded-md ring-1 ring-slate-900/5 shadow-sm text-xl group-hover:shadow h-6 w-6 flex items-center justify-center bg-white dark:bg-gray-700',
|
'mr-4 rounded-md ring-1 ring-slate-900/5 shadow-xs text-xl group-hover:shadow-sm h-6 w-6 flex items-center justify-center bg-white dark:bg-gray-700',
|
||||||
textTheme,
|
textTheme,
|
||||||
'dark:text-gray-100',
|
'dark:text-gray-100',
|
||||||
)}
|
)}
|
||||||
|
|
@ -193,7 +193,7 @@ const SearchBase = ({ className }: { className?: string }) => {
|
||||||
<Input
|
<Input
|
||||||
unstyle
|
unstyle
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
className="ring-0 outline-none block w-full p-4 text-base bg-transparent text-gray-900 dark:text-gray-100"
|
className="ring-0 outline-hidden block w-full p-4 text-base bg-transparent text-gray-900 dark:text-gray-100"
|
||||||
placeholder={translate('::App.Platform.Search2')}
|
placeholder={translate('::App.Platform.Search2')}
|
||||||
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
|
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ const Alert = forwardRef<HTMLDivElement, AlertProps>((props, ref) => {
|
||||||
{showIcon && <StatusIcon iconColor={typeMap.iconColor} custom={customIcon} type={type} />}
|
{showIcon && <StatusIcon iconColor={typeMap.iconColor} custom={customIcon} type={type} />}
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'min-w-0 flex-1 whitespace-normal break-words leading-6',
|
'min-w-0 flex-1 whitespace-normal wrap-break-word leading-6',
|
||||||
showIcon ? 'ltr:ml-2 rtl:mr-2' : '',
|
showIcon ? 'ltr:ml-2 rtl:mr-2' : '',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -107,12 +107,12 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
|
||||||
const btn = {
|
const btn = {
|
||||||
bgColor: active
|
bgColor: active
|
||||||
? `bg-${buttonColor}-200 dark:bg-${buttonColor}-50`
|
? `bg-${buttonColor}-200 dark:bg-${buttonColor}-50`
|
||||||
: `bg-${buttonColor}-50 dark:bg-${buttonColor}-500 dark:bg-opacity-20`,
|
: `bg-${buttonColor}-50 dark:bg-${buttonColor}-500/20`,
|
||||||
textColor: `text-${buttonColor}-${buttonColorLevel} dark:text-${buttonColor}-50`,
|
textColor: `text-${buttonColor}-${buttonColorLevel} dark:text-${buttonColor}-50`,
|
||||||
hoverColor: active
|
hoverColor: active
|
||||||
? ''
|
? ''
|
||||||
: `hover:bg-${buttonColor}-100 dark:hover:bg-${buttonColor}-500 dark:hover:bg-opacity-30`,
|
: `hover:bg-${buttonColor}-100 dark:hover:bg-${buttonColor}-500/30`,
|
||||||
activeColor: `active:bg-${buttonColor}-200 dark:active:bg-${buttonColor}-500 dark:active:bg-opacity-40`,
|
activeColor: `active:bg-${buttonColor}-200 dark:active:bg-${buttonColor}-500/40`,
|
||||||
}
|
}
|
||||||
return getBtnColor(btn)
|
return getBtnColor(btn)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ const Day = forwardRef<HTMLButtonElement, DayProps>((props, ref) => {
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const { themeColor, primaryColorLevel } = useConfig()
|
const { themeColor, primaryColorLevel } = useConfig()
|
||||||
|
const inRangeOnly = inRange && !disabled && !firstInRange && !lastInRange && !selected
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
@ -78,6 +79,16 @@ const Day = forwardRef<HTMLButtonElement, DayProps>((props, ref) => {
|
||||||
ref={ref}
|
ref={ref}
|
||||||
type="button"
|
type="button"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
// Aralik gunu tema renginin %10'u: renk adi calisma aninda geldigi icin her renk/ton icin
|
||||||
|
// ayri `/10` sinifi uretmek yerine temanin renk degiskeni kullanilir.
|
||||||
|
style={
|
||||||
|
inRangeOnly
|
||||||
|
? {
|
||||||
|
...others.style,
|
||||||
|
backgroundColor: `color-mix(in oklab, var(--color-${themeColor}-${primaryColorLevel}) 10%, transparent)`,
|
||||||
|
}
|
||||||
|
: others.style
|
||||||
|
}
|
||||||
tabIndex={getDayTabIndex({
|
tabIndex={getDayTabIndex({
|
||||||
focusable,
|
focusable,
|
||||||
hasValue,
|
hasValue,
|
||||||
|
|
@ -102,12 +113,6 @@ const Day = forwardRef<HTMLButtonElement, DayProps>((props, ref) => {
|
||||||
selected &&
|
selected &&
|
||||||
!disabled &&
|
!disabled &&
|
||||||
`bg-${themeColor}-${primaryColorLevel} text-gray-100`,
|
`bg-${themeColor}-${primaryColorLevel} text-gray-100`,
|
||||||
inRange &&
|
|
||||||
!disabled &&
|
|
||||||
!firstInRange &&
|
|
||||||
!lastInRange &&
|
|
||||||
!selected &&
|
|
||||||
`bg-${themeColor}-${primaryColorLevel} bg-opacity-10`,
|
|
||||||
!inRange && !firstInRange && !lastInRange && 'rounded-lg',
|
!inRange && !firstInRange && !lastInRange && 'rounded-lg',
|
||||||
firstInRange &&
|
firstInRange &&
|
||||||
!disabled &&
|
!disabled &&
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import classNames from 'classnames'
|
||||||
import ReactSelect, { components as ReactSelectComponents } from 'react-select'
|
import ReactSelect, { components as ReactSelectComponents } from 'react-select'
|
||||||
import CreatableSelect from 'react-select/creatable'
|
import CreatableSelect from 'react-select/creatable'
|
||||||
import AsyncSelect from 'react-select/async'
|
import AsyncSelect from 'react-select/async'
|
||||||
import { TW_COLORS, BORDER_RADIUS } from '@/utils/tailwind'
|
import { themeColor as twColor } from '@/utils/tailwind'
|
||||||
import { isEmpty, get } from '@/utils/collection'
|
import { isEmpty, get } from '@/utils/collection'
|
||||||
import { useConfig } from '../ConfigProvider'
|
import { useConfig } from '../ConfigProvider'
|
||||||
import { useForm } from '../Form/context'
|
import { useForm } from '../Form/context'
|
||||||
|
|
@ -173,8 +173,6 @@ function SelectBase<
|
||||||
const selectSize = size || inputGroupSize || formControlSize || controlSize
|
const selectSize = size || inputGroupSize || formControlSize || controlSize
|
||||||
const sizeMetrics = SELECT_SIZE_METRICS[selectSize]
|
const sizeMetrics = SELECT_SIZE_METRICS[selectSize]
|
||||||
|
|
||||||
const twColor = TW_COLORS as any
|
|
||||||
|
|
||||||
let isInvalid = false
|
let isInvalid = false
|
||||||
|
|
||||||
if (!isEmpty(form)) {
|
if (!isEmpty(form)) {
|
||||||
|
|
@ -190,11 +188,11 @@ function SelectBase<
|
||||||
const shadaowBase = '0 0 0 1px '
|
const shadaowBase = '0 0 0 1px '
|
||||||
|
|
||||||
if (isInvalid) {
|
if (isInvalid) {
|
||||||
return shadaowBase + twColor.red['500']
|
return shadaowBase + twColor('red', 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.isFocused) {
|
if (state.isFocused) {
|
||||||
return shadaowBase + twColor[themeColor][primaryColorLevel]
|
return shadaowBase + twColor(themeColor, primaryColorLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'none'
|
return 'none'
|
||||||
|
|
@ -219,8 +217,8 @@ function SelectBase<
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
},
|
},
|
||||||
boxShadow: getBoxShadow(state),
|
boxShadow: getBoxShadow(state),
|
||||||
borderRadius: BORDER_RADIUS.md,
|
borderRadius: 'var(--radius-md)',
|
||||||
...(isInvalid ? { borderColor: twColor.red['500'] } : {}),
|
...(isInvalid ? { borderColor: twColor('red', 500) } : {}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
input: (css) => {
|
input: (css) => {
|
||||||
|
|
@ -257,14 +255,14 @@ function SelectBase<
|
||||||
...theme,
|
...theme,
|
||||||
colors: {
|
colors: {
|
||||||
...theme.colors,
|
...theme.colors,
|
||||||
neutral0: mode === 'dark' ? twColor.gray['800'] : (TW_COLORS as any).white,
|
neutral0: mode === 'dark' ? twColor('gray', 800) : twColor('white'),
|
||||||
neutral20: mode === 'dark' ? twColor.gray['600'] : twColor.gray['300'],
|
neutral20: mode === 'dark' ? twColor('gray', 600) : twColor('gray', 300),
|
||||||
neutral30: mode === 'dark' ? twColor.gray['600'] : twColor.gray['300'],
|
neutral30: mode === 'dark' ? twColor('gray', 600) : twColor('gray', 300),
|
||||||
neutral80: mode === 'dark' ? (TW_COLORS as any).white : twColor.gray['700'],
|
neutral80: mode === 'dark' ? twColor('white') : twColor('gray', 700),
|
||||||
neutral10: mode === 'dark' ? twColor.gray['600'] : twColor.gray['300'],
|
neutral10: mode === 'dark' ? twColor('gray', 600) : twColor('gray', 300),
|
||||||
primary25: twColor[themeColor]['50'],
|
primary25: twColor(themeColor, 50),
|
||||||
primary50: twColor[themeColor]['100'],
|
primary50: twColor(themeColor, 100),
|
||||||
primary: twColor[themeColor][primaryColorLevel],
|
primary: twColor(themeColor, primaryColorLevel),
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
themeColor={`${themeColor}-${primaryColorLevel}`}
|
themeColor={`${themeColor}-${primaryColorLevel}`}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ export default function Widget({
|
||||||
<div
|
<div
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4 flex flex-col justify-between',
|
'bg-white dark:bg-gray-900 rounded-lg shadow-xs border border-gray-200 dark:border-gray-700 p-4 flex flex-col justify-between',
|
||||||
onClick && 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800',
|
onClick && 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
|
@ -83,7 +83,7 @@ export default function Widget({
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-12 h-12 bg-gradient-to-br rounded-xl flex items-center justify-center shadow-sm',
|
'w-12 h-12 bg-linear-to-br rounded-xl flex items-center justify-center shadow-xs',
|
||||||
colorMap[safeColor].bg,
|
colorMap[safeColor].bg,
|
||||||
'dark:' + colorMap[safeColor].darkBg
|
'dark:' + colorMap[safeColor].darkBg
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -701,7 +701,7 @@ const PlatformPlaceholder = ({ node }: { node: DesignerNode }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`flex min-h-40 items-center justify-center rounded-lg border border-dashed border-sky-300 bg-gradient-to-br from-sky-50 to-indigo-50 p-6 text-center dark:border-sky-800 dark:from-slate-900 dark:to-sky-950 ${String(node.props.className || '')}`}
|
className={`flex min-h-40 items-center justify-center rounded-lg border border-dashed border-sky-300 bg-linear-to-br from-sky-50 to-indigo-50 p-6 text-center dark:border-sky-800 dark:from-slate-900 dark:to-sky-950 ${String(node.props.className || '')}`}
|
||||||
style={{ minHeight: String(node.props.height || '320px') }}
|
style={{ minHeight: String(node.props.height || '320px') }}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -740,7 +740,7 @@ const GridColumnHeaders = ({ columns }: { columns: string[] }) => {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-w-0 overflow-auto rounded-md border border-slate-200 bg-slate-100 [grid-column:1/-1] dark:border-slate-700 dark:bg-slate-800">
|
<div className="min-w-0 overflow-auto rounded-md border border-slate-200 bg-slate-100 col-span-full dark:border-slate-700 dark:bg-slate-800">
|
||||||
{columns.length ? (
|
{columns.length ? (
|
||||||
<div className="flex min-w-max divide-x divide-slate-200 dark:divide-slate-700">
|
<div className="flex min-w-max divide-x divide-slate-200 dark:divide-slate-700">
|
||||||
{columns.map((column) => (
|
{columns.map((column) => (
|
||||||
|
|
@ -797,7 +797,7 @@ const GridDataTablePreview = ({
|
||||||
|
|
||||||
if (!columns.length) {
|
if (!columns.length) {
|
||||||
return (
|
return (
|
||||||
<div className="rounded-lg border border-dashed border-slate-300 bg-slate-50 p-4 text-center text-xs text-slate-500 [grid-column:1/-1] dark:border-slate-700 dark:bg-slate-900 dark:text-slate-400">
|
<div className="rounded-lg border border-dashed border-slate-300 bg-slate-50 p-4 text-center text-xs text-slate-500 col-span-full dark:border-slate-700 dark:bg-slate-900 dark:text-slate-400">
|
||||||
{translate('::App.VisualDesignerCanvas.SelectAtLeastOneColumn')}
|
{translate('::App.VisualDesignerCanvas.SelectAtLeastOneColumn')}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -805,7 +805,7 @@ const GridDataTablePreview = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`min-w-0 rounded-lg border border-slate-200 bg-white shadow-sm [grid-column:1/-1] dark:border-slate-700 dark:bg-slate-900 ${overflow ? 'overflow-auto' : 'overflow-visible'}`}
|
className={`min-w-0 rounded-lg border border-slate-200 bg-white shadow-xs col-span-full dark:border-slate-700 dark:bg-slate-900 ${overflow ? 'overflow-auto' : 'overflow-visible'}`}
|
||||||
>
|
>
|
||||||
<table className={`w-full border-collapse text-left ${compact ? 'text-[11px]' : 'text-xs'}`}>
|
<table className={`w-full border-collapse text-left ${compact ? 'text-[11px]' : 'text-xs'}`}>
|
||||||
<thead className="bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-200">
|
<thead className="bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-200">
|
||||||
|
|
@ -1006,7 +1006,7 @@ const FormView = ({
|
||||||
? translate('::App.Platform.RecordCount', { count: rows.length })
|
? translate('::App.Platform.RecordCount', { count: rows.length })
|
||||||
: translate('::App.VisualDesignerCanvas.NoSelectEndpoint')}
|
: translate('::App.VisualDesignerCanvas.NoSelectEndpoint')}
|
||||||
</span>
|
</span>
|
||||||
<span className="rounded bg-sky-600 px-1.5 py-0.5 font-semibold text-white">
|
<span className="rounded-sm bg-sky-600 px-1.5 py-0.5 font-semibold text-white">
|
||||||
{translate(
|
{translate(
|
||||||
mode === 'new' ? '::App.VisualDesignerCanvas.NewRecord' : '::App.Platform.Editing',
|
mode === 'new' ? '::App.VisualDesignerCanvas.NewRecord' : '::App.Platform.Editing',
|
||||||
)}
|
)}
|
||||||
|
|
@ -1016,7 +1016,7 @@ const FormView = ({
|
||||||
{translate('::App.Platform.Row')}
|
{translate('::App.Platform.Row')}
|
||||||
<UiKit.Select
|
<UiKit.Select
|
||||||
size="xs"
|
size="xs"
|
||||||
className="min-w-[4.5rem]"
|
className="min-w-18"
|
||||||
maxMenuHeight={200}
|
maxMenuHeight={200}
|
||||||
menuPosition="fixed"
|
menuPosition="fixed"
|
||||||
menuPortalTarget={window.document.body}
|
menuPortalTarget={window.document.body}
|
||||||
|
|
@ -1049,7 +1049,7 @@ const FormView = ({
|
||||||
)}
|
)}
|
||||||
{/* The drop zone belongs with the content, above the command toolbar. */}
|
{/* The drop zone belongs with the content, above the command toolbar. */}
|
||||||
{interactive && !node.children.length && (
|
{interactive && !node.children.length && (
|
||||||
<div className="rounded border border-dashed border-slate-300 px-3 py-4 text-center text-xs text-slate-400 dark:border-slate-700">
|
<div className="rounded-sm border border-dashed border-slate-300 px-3 py-4 text-center text-xs text-slate-400 dark:border-slate-700">
|
||||||
{translate('::App.VisualDesignerCanvas.DropAndBind')}
|
{translate('::App.VisualDesignerCanvas.DropAndBind')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1461,7 +1461,7 @@ const HOISTED_LAYOUT_EXACT = new Set([
|
||||||
const SHARED_LAYOUT_PATTERN = /^(absolute|fixed|sticky|w-full|h-full)$|^-?(inset|top|right|bottom|left)-|^z-|^(min|max)-w-/
|
const SHARED_LAYOUT_PATTERN = /^(absolute|fixed|sticky|w-full|h-full)$|^-?(inset|top|right|bottom|left)-|^z-|^(min|max)-w-/
|
||||||
const NODE_POSITION_PATTERN = /^(absolute|fixed|sticky)$/
|
const NODE_POSITION_PATTERN = /^(absolute|fixed|sticky)$/
|
||||||
|
|
||||||
/** `md:`, `dark:hover:` gibi varyant onlerini atar; `[grid-column:1/-1]` bozulmadan kalir. */
|
/** `md:`, `dark:hover:` gibi varyant onlerini atar; `col-span-full` bozulmadan kalir. */
|
||||||
const stripVariants = (token: string) => token.replace(/^(?:(?:[\w-]+|\[[^\]]+\]):)+/, '')
|
const stripVariants = (token: string) => token.replace(/^(?:(?:[\w-]+|\[[^\]]+\]):)+/, '')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1781,7 +1781,7 @@ const NodeView = ({
|
||||||
<div
|
<div
|
||||||
className={`min-h-14 rounded py-2 transition ${
|
className={`min-h-14 rounded py-2 transition ${
|
||||||
overSlot === slot
|
overSlot === slot
|
||||||
? 'bg-emerald-50 outline outline-2 outline-emerald-500 dark:bg-emerald-950/40'
|
? 'bg-emerald-50 outline-solid outline-2 outline-emerald-500 dark:bg-emerald-950/40'
|
||||||
: dragging
|
: dragging
|
||||||
? 'outline-dashed outline-1 outline-sky-400/70'
|
? 'outline-dashed outline-1 outline-sky-400/70'
|
||||||
: ''
|
: ''
|
||||||
|
|
@ -1822,7 +1822,7 @@ const NodeView = ({
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{interactive && !tabNodes.length && !option.content && (
|
{interactive && !tabNodes.length && !option.content && (
|
||||||
<div className="flex min-h-12 items-center justify-center rounded border border-dashed border-slate-300 px-2 text-center text-[10px] text-slate-400 dark:border-slate-700">
|
<div className="flex min-h-12 items-center justify-center rounded-sm border border-dashed border-slate-300 px-2 text-center text-[10px] text-slate-400 dark:border-slate-700">
|
||||||
{translate('::App.VisualDesignerCanvas.DropComponentInTab')}
|
{translate('::App.VisualDesignerCanvas.DropComponentInTab')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1838,7 +1838,7 @@ const NodeView = ({
|
||||||
node.type === 'Table' ? (
|
node.type === 'Table' ? (
|
||||||
<UiKit.Table
|
<UiKit.Table
|
||||||
borderlessRow
|
borderlessRow
|
||||||
className={`${String(node.props.className || '')} [&>tbody>tr>td]:!px-1.5 [&>tbody>tr>td]:!py-1.5`}
|
className={`${String(node.props.className || '')} [&>tbody>tr>td]:px-1.5! [&>tbody>tr>td]:py-1.5!`}
|
||||||
compact={Boolean(node.props.compact)}
|
compact={Boolean(node.props.compact)}
|
||||||
hoverable={node.props.hoverable !== false}
|
hoverable={node.props.hoverable !== false}
|
||||||
overflow={node.props.overflow !== false}
|
overflow={node.props.overflow !== false}
|
||||||
|
|
@ -1912,7 +1912,7 @@ const NodeView = ({
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{interactive && !cellNodes.length && (
|
{interactive && !cellNodes.length && (
|
||||||
<div className="flex min-h-12 items-center justify-center rounded border border-dashed border-slate-300 px-2 text-center text-[10px] text-slate-400 dark:border-slate-700">
|
<div className="flex min-h-12 items-center justify-center rounded-sm border border-dashed border-slate-300 px-2 text-center text-[10px] text-slate-400 dark:border-slate-700">
|
||||||
{translate('::App.VisualDesignerCanvas.DropComponent')}
|
{translate('::App.VisualDesignerCanvas.DropComponent')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1972,7 +1972,7 @@ const NodeView = ({
|
||||||
? [
|
? [
|
||||||
<div
|
<div
|
||||||
key={`grid_loading_${node.id}`}
|
key={`grid_loading_${node.id}`}
|
||||||
className="rounded-lg border border-slate-200 bg-slate-50 p-4 text-center text-xs text-slate-500 [grid-column:1/-1] dark:border-slate-700 dark:bg-slate-900 dark:text-slate-400"
|
className="rounded-lg border border-slate-200 bg-slate-50 p-4 text-center text-xs text-slate-500 col-span-full dark:border-slate-700 dark:bg-slate-900 dark:text-slate-400"
|
||||||
>
|
>
|
||||||
{translate('::App.VisualDesignerCanvas.LoadingData')}
|
{translate('::App.VisualDesignerCanvas.LoadingData')}
|
||||||
</div>,
|
</div>,
|
||||||
|
|
@ -2058,15 +2058,15 @@ const NodeView = ({
|
||||||
isDragSource ? 'opacity-40' : ''
|
isDragSource ? 'opacity-40' : ''
|
||||||
} ${
|
} ${
|
||||||
dropHint === 'inside'
|
dropHint === 'inside'
|
||||||
? 'z-10 bg-emerald-500/10 outline outline-2 outline-emerald-500 outline-offset-2'
|
? 'z-10 bg-emerald-500/10 outline-solid outline-2 outline-emerald-500 outline-offset-2'
|
||||||
: // Sürükleme sürerken içine bırakılabilen her konteyner işaretlenir, böylece
|
: // Sürükleme sürerken içine bırakılabilen her konteyner işaretlenir, böylece
|
||||||
// kullanıcı hedefe varmadan önce nereye bırakabileceğini görür.
|
// kullanıcı hedefe varmadan önce nereye bırakabileceğini görür.
|
||||||
dragging && canDropInside
|
dragging && canDropInside
|
||||||
? 'outline-dashed outline-1 outline-sky-400/70 outline-offset-2'
|
? 'outline-dashed outline-1 outline-sky-400/70 outline-offset-2'
|
||||||
: interactive
|
: interactive
|
||||||
? selected
|
? selected
|
||||||
? 'z-10 outline outline-2 outline-sky-500 outline-offset-2'
|
? 'z-10 outline-solid outline-2 outline-sky-500 outline-offset-2'
|
||||||
: 'outline outline-1 outline-transparent hover:outline-sky-300'
|
: 'outline-solid outline-1 outline-transparent hover:outline-sky-300'
|
||||||
: ''
|
: ''
|
||||||
}`}
|
}`}
|
||||||
data-designer-node={node.id}
|
data-designer-node={node.id}
|
||||||
|
|
@ -2122,28 +2122,28 @@ const NodeView = ({
|
||||||
{/* Yanına bırakma çizgisi: bileşen tam olarak buraya girer. */}
|
{/* Yanına bırakma çizgisi: bileşen tam olarak buraya girer. */}
|
||||||
{dropHint === 'before' && (
|
{dropHint === 'before' && (
|
||||||
<div className="pointer-events-none absolute inset-x-0 -top-1 z-30 flex items-center gap-1">
|
<div className="pointer-events-none absolute inset-x-0 -top-1 z-30 flex items-center gap-1">
|
||||||
<span className="rounded bg-emerald-600 px-1.5 py-[1px] text-[10px] font-semibold text-white shadow">
|
<span className="rounded-sm bg-emerald-600 px-1.5 py-px text-[10px] font-semibold text-white shadow-sm">
|
||||||
{dragLabel} üstüne
|
{dragLabel} üstüne
|
||||||
</span>
|
</span>
|
||||||
<span className="h-[3px] flex-1 rounded bg-emerald-500" />
|
<span className="h-[3px] flex-1 rounded-sm bg-emerald-500" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{dropHint === 'after' && (
|
{dropHint === 'after' && (
|
||||||
<div className="pointer-events-none absolute inset-x-0 -bottom-1 z-30 flex items-center gap-1">
|
<div className="pointer-events-none absolute inset-x-0 -bottom-1 z-30 flex items-center gap-1">
|
||||||
<span className="rounded bg-emerald-600 px-1.5 py-[1px] text-[10px] font-semibold text-white shadow">
|
<span className="rounded-sm bg-emerald-600 px-1.5 py-px text-[10px] font-semibold text-white shadow-sm">
|
||||||
{dragLabel} altına
|
{dragLabel} altına
|
||||||
</span>
|
</span>
|
||||||
<span className="h-[3px] flex-1 rounded bg-emerald-500" />
|
<span className="h-[3px] flex-1 rounded-sm bg-emerald-500" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{dropHint === 'inside' && (
|
{dropHint === 'inside' && (
|
||||||
<span className="pointer-events-none absolute left-1 top-1 z-30 rounded bg-emerald-600 px-1.5 py-[1px] text-[10px] font-semibold text-white shadow">
|
<span className="pointer-events-none absolute left-1 top-1 z-30 rounded-sm bg-emerald-600 px-1.5 py-px text-[10px] font-semibold text-white shadow-sm">
|
||||||
{node.type} içine
|
{node.type} içine
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{/* Sürükleme sürerken bırakılamayan hedef açıkça söylenir. */}
|
{/* Sürükleme sürerken bırakılamayan hedef açıkça söylenir. */}
|
||||||
{dragging && insideDraggedSubtree && !isDragSource && (
|
{dragging && insideDraggedSubtree && !isDragSource && (
|
||||||
<span className="pointer-events-none absolute right-1 top-1 z-30 rounded bg-slate-500 px-1.5 py-[1px] text-[10px] font-semibold text-white shadow">
|
<span className="pointer-events-none absolute right-1 top-1 z-30 rounded-sm bg-slate-500 px-1.5 py-px text-[10px] font-semibold text-white shadow-sm">
|
||||||
{translate('::App.VisualDesignerCanvas.CannotMoveHere')}
|
{translate('::App.VisualDesignerCanvas.CannotMoveHere')}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
@ -2158,7 +2158,7 @@ const NodeView = ({
|
||||||
{interactive && (
|
{interactive && (
|
||||||
<span
|
<span
|
||||||
draggable
|
draggable
|
||||||
className={`absolute -right-2 -top-2 z-30 h-4 w-4 cursor-grab items-center justify-center rounded-full bg-sky-600 text-[8px] text-white shadow ring-1 ring-white active:cursor-grabbing dark:ring-gray-900 ${selected ? 'flex' : 'hidden'}`}
|
className={`absolute -right-2 -top-2 z-30 h-4 w-4 cursor-grab items-center justify-center rounded-full bg-sky-600 text-[8px] text-white shadow-sm ring-1 ring-white active:cursor-grabbing dark:ring-gray-900 ${selected ? 'flex' : 'hidden'}`}
|
||||||
title={translate('::App.VisualDesignerCanvas.DragToMove', {
|
title={translate('::App.VisualDesignerCanvas.DragToMove', {
|
||||||
name: node.ref || node.type,
|
name: node.ref || node.type,
|
||||||
})}
|
})}
|
||||||
|
|
@ -2169,7 +2169,7 @@ const NodeView = ({
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{interactive && refHidden && (
|
{interactive && refHidden && (
|
||||||
<span className="absolute left-1 top-1 z-10 rounded bg-slate-700 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wider text-white">
|
<span className="absolute left-1 top-1 z-10 rounded-sm bg-slate-700 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wider text-white">
|
||||||
Gizli
|
Gizli
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
@ -2204,7 +2204,7 @@ const NodeView = ({
|
||||||
// Form renders its own placeholder below the toolbar.
|
// Form renders its own placeholder below the toolbar.
|
||||||
!isFormNode(node.type) && (
|
!isFormNode(node.type) && (
|
||||||
<div
|
<div
|
||||||
className="m-2 rounded border border-dashed border-slate-300 px-3 py-4 text-center text-xs text-slate-400"
|
className="m-2 rounded-sm border border-dashed border-slate-300 px-3 py-4 text-center text-xs text-slate-400"
|
||||||
{...containerDropZoneProps}
|
{...containerDropZoneProps}
|
||||||
>
|
>
|
||||||
{translate('::App.VisualDesignerCanvas.DropComponentHere')}
|
{translate('::App.VisualDesignerCanvas.DropComponentHere')}
|
||||||
|
|
@ -2399,7 +2399,7 @@ const VisualCanvas = ({
|
||||||
].map(([name, icon]) => (
|
].map(([name, icon]) => (
|
||||||
<button
|
<button
|
||||||
key={name}
|
key={name}
|
||||||
className="rounded-lg border border-slate-200 bg-white p-3 text-xs font-semibold text-slate-600 shadow-sm transition hover:border-sky-400 hover:text-sky-700 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300"
|
className="rounded-lg border border-slate-200 bg-white p-3 text-xs font-semibold text-slate-600 shadow-xs transition hover:border-sky-400 hover:text-sky-700 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
|
||||||
|
|
@ -979,7 +979,7 @@ const renderNodeToCode = (
|
||||||
return `${indent('<tr>', level + 1)}\n${cells}\n${indent('</tr>', level + 1)}`
|
return `${indent('<tr>', level + 1)}\n${cells}\n${indent('</tr>', level + 1)}`
|
||||||
}).join('\n')
|
}).join('\n')
|
||||||
const className = JSON.stringify(String(node.props.className || ''))
|
const className = JSON.stringify(String(node.props.className || ''))
|
||||||
return `${indent(`<UiKit.Table className={${className} + " [&>tbody>tr>td]:!px-1.5 [&>tbody>tr>td]:!py-1.5"} borderlessRow compact={${Boolean(node.props.compact)}} hoverable={${node.props.hoverable !== false}} overflow={${node.props.overflow !== false}} style={{ minWidth: "100%", tableLayout: "fixed", width: "100%" }}>`, level)}
|
return `${indent(`<UiKit.Table className={${className} + " [&>tbody>tr>td]:px-1.5! [&>tbody>tr>td]:py-1.5!"} borderlessRow compact={${Boolean(node.props.compact)}} hoverable={${node.props.hoverable !== false}} overflow={${node.props.overflow !== false}} style={{ minWidth: "100%", tableLayout: "fixed", width: "100%" }}>`, level)}
|
||||||
${indent('<tbody>', level + 1)}
|
${indent('<tbody>', level + 1)}
|
||||||
${rows}
|
${rows}
|
||||||
${indent('</tbody>', level + 1)}
|
${indent('</tbody>', level + 1)}
|
||||||
|
|
@ -1058,7 +1058,7 @@ ${indent(`if (!Array.isArray(${itemsVariable})) return <div className="rounded-l
|
||||||
${indent(`const ${columnsVariable} = ${columnsExpression}`, level + 2)}
|
${indent(`const ${columnsVariable} = ${columnsExpression}`, level + 2)}
|
||||||
${captionEntries.length ? `${indent(`const ${captionsVariable} = ${captionsLiteral}`, level + 2)}\n` : ''}${lookupEntries.length ? `${indent(`const ${lookupsVariable} = ${lookupsLiteral}`, level + 2)}\n` : ''}${indent(`if (!${columnsVariable}.length) return <div className="rounded-lg border border-dashed border-slate-300 bg-slate-50 p-4 text-center text-xs text-slate-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-400">Preview için en az bir sütun seçin.</div>`, level + 2)}
|
${captionEntries.length ? `${indent(`const ${captionsVariable} = ${captionsLiteral}`, level + 2)}\n` : ''}${lookupEntries.length ? `${indent(`const ${lookupsVariable} = ${lookupsLiteral}`, level + 2)}\n` : ''}${indent(`if (!${columnsVariable}.length) return <div className="rounded-lg border border-dashed border-slate-300 bg-slate-50 p-4 text-center text-xs text-slate-500 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-400">Preview için en az bir sütun seçin.</div>`, level + 2)}
|
||||||
${indent('return (', level + 2)}
|
${indent('return (', level + 2)}
|
||||||
${indent(`<div className="min-w-0 ${overflowClass} rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-700 dark:bg-slate-900" style={{ gridColumn: "1 / -1" }}>`, level + 3)}
|
${indent(`<div className="min-w-0 ${overflowClass} rounded-lg border border-slate-200 bg-white shadow-xs dark:border-slate-700 dark:bg-slate-900" style={{ gridColumn: "1 / -1" }}>`, level + 3)}
|
||||||
${indent(`<table className="w-full border-collapse text-left ${tableTextClass}">`, level + 4)}
|
${indent(`<table className="w-full border-collapse text-left ${tableTextClass}">`, level + 4)}
|
||||||
${indent('<thead className="bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-200"><tr>', level + 5)}
|
${indent('<thead className="bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-200"><tr>', level + 5)}
|
||||||
${indent(`{${columnsVariable}.map((column) => <th key={column} className="whitespace-nowrap border-b border-slate-200 dark:border-slate-700 ${cellSpacingClass}">{${captionEntries.length ? `${captionsVariable}[column] ?? ` : ''}(column === "value" ? "Value" : column)}</th>)}`, level + 6)}
|
${indent(`{${columnsVariable}.map((column) => <th key={column} className="whitespace-nowrap border-b border-slate-200 dark:border-slate-700 ${cellSpacingClass}">{${captionEntries.length ? `${captionsVariable}[column] ?? ` : ''}(column === "value" ? "Value" : column)}</th>)}`, level + 6)}
|
||||||
|
|
@ -1091,7 +1091,7 @@ ${indent('})()}', level + 1)}`
|
||||||
.map((child) => nodeToCode(child, level + 4, repeatedItemVariable, formScope))
|
.map((child) => nodeToCode(child, level + 4, repeatedItemVariable, formScope))
|
||||||
.join('\n')
|
.join('\n')
|
||||||
: indent(
|
: indent(
|
||||||
`<pre className="min-w-0 overflow-auto rounded-lg border border-slate-200 bg-white p-3 text-xs text-slate-800 shadow-sm dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100">{typeof ${repeatedItemVariable} === "string" ? ${repeatedItemVariable} : JSON.stringify(${repeatedItemVariable}, null, 2)}</pre>`,
|
`<pre className="min-w-0 overflow-auto rounded-lg border border-slate-200 bg-white p-3 text-xs text-slate-800 shadow-xs dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100">{typeof ${repeatedItemVariable} === "string" ? ${repeatedItemVariable} : JSON.stringify(${repeatedItemVariable}, null, 2)}</pre>`,
|
||||||
level + 4,
|
level + 4,
|
||||||
)
|
)
|
||||||
// The collection is read once into a local: it is tested for three cases
|
// The collection is read once into a local: it is tested for three cases
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
/** Liste/kart yonetim ekranlarindaki aksiyon ikonlari notr durur, rengi yalnizca hover'da gosterir. */
|
/** Liste/kart yonetim ekranlarindaki aksiyon ikonlari notr durur, rengi yalnizca hover'da gosterir. */
|
||||||
export const ACTION_BUTTON_CLASS =
|
export const ACTION_BUTTON_CLASS =
|
||||||
'!h-8 !w-8 !rounded !p-0 text-slate-500 transition-colors dark:text-gray-400'
|
'h-8! w-8! rounded-sm! p-0! text-slate-500 transition-colors dark:text-gray-400'
|
||||||
|
|
||||||
export const ACTION_BUTTON_HOVER = {
|
export const ACTION_BUTTON_HOVER = {
|
||||||
blue: 'hover:!bg-blue-50 hover:text-blue-600 dark:hover:!bg-gray-800 dark:hover:text-blue-400',
|
blue: 'hover:bg-blue-50! hover:text-blue-600 dark:hover:bg-gray-800! dark:hover:text-blue-400',
|
||||||
green:
|
green:
|
||||||
'hover:!bg-green-50 hover:text-green-600 dark:hover:!bg-gray-800 dark:hover:text-green-400',
|
'hover:bg-green-50! hover:text-green-600 dark:hover:bg-gray-800! dark:hover:text-green-400',
|
||||||
red: 'hover:!bg-red-50 hover:text-red-600 dark:hover:!bg-gray-800 dark:hover:text-red-400',
|
red: 'hover:bg-red-50! hover:text-red-600 dark:hover:bg-gray-800! dark:hover:text-red-400',
|
||||||
slate:
|
slate:
|
||||||
'hover:!bg-slate-100 hover:text-slate-700 dark:hover:!bg-gray-800 dark:hover:text-gray-200',
|
'hover:bg-slate-100! hover:text-slate-700 dark:hover:bg-gray-800! dark:hover:text-gray-200',
|
||||||
} as const
|
} as const
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -139,5 +139,4 @@ export abstract class UiEvalService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const _global = (window || global) as any
|
;(globalThis as any).UiEvalService = UiEvalService
|
||||||
_global.UiEvalService = UiEvalService
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ function useAuth() {
|
||||||
access_token: token,
|
access_token: token,
|
||||||
refresh_token: refreshToken,
|
refresh_token: refreshToken,
|
||||||
expires_in: expiresIn,
|
expires_in: expiresIn,
|
||||||
} = resp?.data as any
|
} = resp.data as any
|
||||||
handleToken({ token, refreshToken, expiresIn })
|
handleToken({ token, refreshToken, expiresIn })
|
||||||
// if (resp.data.user) {
|
// if (resp.data.user) {
|
||||||
// setUser(
|
// setUser(
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,5 @@
|
||||||
// src/utils/tailwind.ts
|
// src/utils/tailwind.ts
|
||||||
|
|
||||||
import colors from 'tailwindcss/colors'
|
|
||||||
// Tailwind eski renk isimlerinden kaynaklı uyarıları engelle
|
|
||||||
delete (colors as any).lightBlue
|
|
||||||
delete (colors as any).warmGray
|
|
||||||
delete (colors as any).trueGray
|
|
||||||
delete (colors as any).coolGray
|
|
||||||
delete (colors as any).blueGray
|
|
||||||
|
|
||||||
// Tailwind breakpoints (px)
|
// Tailwind breakpoints (px)
|
||||||
export const SCREENS = {
|
export const SCREENS = {
|
||||||
xs: 576,
|
xs: 576,
|
||||||
|
|
@ -18,28 +10,9 @@ export const SCREENS = {
|
||||||
'2xl': 1536,
|
'2xl': 1536,
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
// Border radius (Tailwind ile uyumlu)
|
/**
|
||||||
export const BORDER_RADIUS = {
|
* Temanin renk degiskeni (`@theme`, src/assets/styles/tailwind/index.css). Deger koda kopyalanmaz;
|
||||||
none: '0px',
|
* ozel gri paleti ve `sozsoft-*` renkleri dahil, CSS ile JS ayni rengi gosterir.
|
||||||
xs: '0.0625rem',
|
*/
|
||||||
sm: '0.125rem',
|
export const themeColor = (name: string, shade?: string | number) =>
|
||||||
DEFAULT: '0.25rem',
|
`var(--color-${shade === undefined ? name : `${name}-${shade}`})`
|
||||||
md: '0.375rem',
|
|
||||||
lg: '0.5rem',
|
|
||||||
xl: '0.75rem',
|
|
||||||
'2xl': '1rem',
|
|
||||||
'3xl': '1.5rem',
|
|
||||||
full: '9999px',
|
|
||||||
} as const
|
|
||||||
|
|
||||||
// Tailwind renk paleti + senin custom 'sozsoft' renklerin
|
|
||||||
export const TW_COLORS = {
|
|
||||||
...colors,
|
|
||||||
sozsoft: {
|
|
||||||
main: '#FF99C8',
|
|
||||||
secondary: '#FCF6BD',
|
|
||||||
active: '#D0F4DE',
|
|
||||||
x: '#A9DEF9',
|
|
||||||
y: '#E4C1F9',
|
|
||||||
},
|
|
||||||
} as const
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue