From 2f6a7242c41bb0400415dd083a2a65e1538db221 Mon Sep 17 00:00:00 2001 From: Moein Moradi Date: Mon, 25 Aug 2025 12:19:58 +0330 Subject: [PATCH] first commit --- .DS_Store | Bin 10244 -> 10244 bytes README.md | 0 app/.DS_Store | Bin 6148 -> 6148 bytes app/Http/Controllers/TaskController.php | 215 ++ components.d.ts | 2 +- database/.DS_Store | Bin 6148 -> 6148 bytes public/.DS_Store | Bin 6148 -> 6148 bytes public/hot | 1 + resources/.DS_Store | Bin 6148 -> 6148 bytes resources/js/pages/apps/chat.vue | 14 +- resources/js/pages/dashboards/gantt.vue | 1768 +++++------------ resources/js/pages/login.vue | 167 +- resources/js/pages/tables/data-table.vue | 2 +- resources/js/plugins/webfontloader.js | 10 +- ...oDataTableCellSlot.vue => AgGridTable.vue} | 2 +- resources/views/application.blade.php | 2 + routes/api.php | 4 + storage/.DS_Store | Bin 6148 -> 6148 bytes tests/.DS_Store | Bin 6148 -> 6148 bytes vendor/.DS_Store | Bin 12292 -> 12292 bytes 20 files changed, 885 insertions(+), 1302 deletions(-) create mode 100644 README.md create mode 100644 app/Http/Controllers/TaskController.php create mode 100644 public/hot rename resources/js/views/demos/forms/tables/data-table/{DemoDataTableCellSlot.vue => AgGridTable.vue} (99%) diff --git a/.DS_Store b/.DS_Store index bdac59441d30dba191c7fc0aa14d85ad2aac15a4..c626809b88dacb374bb1507da9487bf8007a669a 100644 GIT binary patch delta 508 zcmZn(XbIS$A`s6ME;*5bfq{iVk0G5Qlc6Lx-^C>0QBmS}!aHU_%}=sh-uB8GgR4J8bz48_RigVjt9mnvYERh>Th zgOteRds1Ai)>=TFlix}yLRrGnN=)(!lg*`*S^v9%q~=S@LRgy*N&^EZZ`UHA;71wZ W$q!_BAiT{VWo~d#=IhDV#PtAuP@K5{ delta 508 zcmZn(XbIS$A`s8OkhY6~fq{iVk0G5Qlc6Lx-^C> 1, + 'text' => 'Project Planning', + 'start_date' => '2024-01-01', + 'duration' => 5, + 'progress' => 100, + 'priority' => 'high', + 'notes' => 'Initial project planning and requirements gathering', + 'parent' => null + ], + [ + 'id' => 2, + 'text' => 'Design Phase', + 'start_date' => '2024-01-06', + 'duration' => 10, + 'progress' => 60, + 'priority' => 'medium', + 'notes' => 'UI/UX design and wireframing', + 'parent' => null + ], + [ + 'id' => 3, + 'text' => 'Development', + 'start_date' => '2024-01-16', + 'duration' => 15, + 'progress' => 30, + 'priority' => 'high', + 'notes' => 'Core development work', + 'parent' => null + ], + [ + 'id' => 4, + 'text' => 'Testing', + 'start_date' => '2024-01-31', + 'duration' => 7, + 'progress' => 0, + 'priority' => 'medium', + 'notes' => 'Quality assurance and testing', + 'parent' => null + ], + [ + 'id' => 5, + 'text' => 'Deployment', + 'start_date' => '2024-02-07', + 'duration' => 3, + 'progress' => 0, + 'priority' => 'critical', + 'notes' => 'Production deployment and launch', + 'parent' => null + ], + [ + 'id' => 6, + 'text' => 'Frontend Development', + 'start_date' => '2024-01-16', + 'duration' => 8, + 'progress' => 40, + 'priority' => 'high', + 'notes' => 'Vue.js frontend development', + 'parent' => 3 + ], + [ + 'id' => 7, + 'text' => 'Backend Development', + 'start_date' => '2024-01-24', + 'duration' => 7, + 'progress' => 20, + 'priority' => 'high', + 'notes' => 'Laravel backend development', + 'parent' => 3 + ] + ]; + + return response()->json([ + 'success' => true, + 'data' => $tasks, + 'message' => 'Tasks retrieved successfully' + ]); + } + + /** + * Store a newly created task + */ + public function store(Request $request): JsonResponse + { + $validator = Validator::make($request->all(), [ + 'text' => 'required|string|max:255', + 'start_date' => 'required|date', + 'duration' => 'required|integer|min:1', + 'priority' => 'required|in:low,medium,high,critical', + 'notes' => 'nullable|string', + 'parent' => 'nullable|integer' + ]); + + if ($validator->fails()) { + return response()->json([ + 'success' => false, + 'message' => 'Validation failed', + 'errors' => $validator->errors() + ], 422); + } + + // In real app, save to database + $task = [ + 'id' => rand(1000, 9999), // Generate random ID for demo + 'text' => $request->text, + 'start_date' => $request->start_date, + 'duration' => $request->duration, + 'progress' => 0, + 'priority' => $request->priority, + 'notes' => $request->notes, + 'parent' => $request->parent + ]; + + return response()->json([ + 'success' => true, + 'data' => $task, + 'message' => 'Task created successfully' + ], 201); + } + + /** + * Display the specified task + */ + public function show(int $id): JsonResponse + { + // Sample task data - in real app, fetch from database + $task = [ + 'id' => $id, + 'text' => 'Sample Task', + 'start_date' => '2024-01-01', + 'duration' => 5, + 'progress' => 50, + 'priority' => 'medium', + 'notes' => 'This is a sample task', + 'parent' => null + ]; + + return response()->json([ + 'success' => true, + 'data' => $task, + 'message' => 'Task retrieved successfully' + ]); + } + + /** + * Update the specified task + */ + public function update(Request $request, int $id): JsonResponse + { + $validator = Validator::make($request->all(), [ + 'text' => 'required|string|max:255', + 'start_date' => 'required|date', + 'duration' => 'required|integer|min:1', + 'priority' => 'required|in:low,medium,high,critical', + 'notes' => 'nullable|string', + 'parent' => 'nullable|integer' + ]); + + if ($validator->fails()) { + return response()->json([ + 'success' => false, + 'message' => 'Validation failed', + 'errors' => $validator->errors() + ], 422); + } + + // In real app, update in database + $task = [ + 'id' => $id, + 'text' => $request->text, + 'start_date' => $request->start_date, + 'duration' => $request->duration, + 'progress' => $request->progress ?? 0, + 'priority' => $request->priority, + 'notes' => $request->notes, + 'parent' => $request->parent + ]; + + return response()->json([ + 'success' => true, + 'data' => $task, + 'message' => 'Task updated successfully' + ]); + } + + /** + * Remove the specified task + */ + public function destroy(int $id): JsonResponse + { + // In real app, delete from database + + return response()->json([ + 'success' => true, + 'message' => 'Task deleted successfully' + ]); + } +} diff --git a/components.d.ts b/components.d.ts index dc6b8e0..5fdcac1 100644 --- a/components.d.ts +++ b/components.d.ts @@ -12,6 +12,7 @@ declare module 'vue' { AddEditPermissionDialog: typeof import('./resources/js/components/dialogs/AddEditPermissionDialog.vue')['default'] AddEditRoleDialog: typeof import('./resources/js/components/dialogs/AddEditRoleDialog.vue')['default'] AddPaymentMethodDialog: typeof import('./resources/js/components/dialogs/AddPaymentMethodDialog.vue')['default'] + AgGridTable: typeof import('./resources/js/views/demos/forms/tables/data-table/AgGridTable.vue')['default'] AnalysisCard: typeof import('./resources/js/components/AnalysisCard.vue')['default'] AppAutocomplete: typeof import('./resources/js/@core/components/app-form-elements/AppAutocomplete.vue')['default'] AppBarSearch: typeof import('./resources/js/@core/components/AppBarSearch.vue')['default'] @@ -133,7 +134,6 @@ declare module 'vue' { DemoCustomInputCustomRadiosWithIcon: typeof import('./resources/js/views/demos/forms/form-elements/custom-input/DemoCustomInputCustomRadiosWithIcon.vue')['default'] DemoCustomInputCustomRadiosWithImage: typeof import('./resources/js/views/demos/forms/form-elements/custom-input/DemoCustomInputCustomRadiosWithImage.vue')['default'] DemoDataTableBasic: typeof import('./resources/js/views/demos/forms/tables/data-table/DemoDataTableBasic.vue')['default'] - DemoDataTableCellSlot: typeof import('./resources/js/views/demos/forms/tables/data-table/DemoDataTableCellSlot.vue')['default'] DemoDataTableDense: typeof import('./resources/js/views/demos/forms/tables/data-table/DemoDataTableDense.vue')['default'] DemoDataTableExpandableRows: typeof import('./resources/js/views/demos/forms/tables/data-table/DemoDataTableExpandableRows.vue')['default'] DemoDataTableExternalPagination: typeof import('./resources/js/views/demos/forms/tables/data-table/DemoDataTableExternalPagination.vue')['default'] diff --git a/database/.DS_Store b/database/.DS_Store index 7d617a4cfcf397577f32eaec7f9e990ce49e96b1..dd6c0b0866a628547ec577f9c0452b92088e3ee6 100644 GIT binary patch delta 78 zcmZoMXffCj!o;euS|MQG;cec}>?#5P96uVf delta 78 zcmZoMXffCj!o(`Gk>|Y3vx#-$M{ diff --git a/public/hot b/public/hot new file mode 100644 index 0000000..34adf08 --- /dev/null +++ b/public/hot @@ -0,0 +1 @@ +http://localhost:5173 \ No newline at end of file diff --git a/resources/.DS_Store b/resources/.DS_Store index 15460b34f527f1cfced829e852cb82b08d09a48d..e1cb67fbb0edcf5c8493257b5cb56651fc5717f4 100644 GIT binary patch delta 160 zcmZoMXffDO!oqrcn?}IA$(1bf5Z30oESikc8zdMQ7?>Ec7>aZAU0jlK@{@pk4q { if (activeForm.value !== null) return false; if (isConfirmationActive.value) return false; if (isWebSearchEnabled.value) return false; - if (pendingConfirmationFormId.value !== null) return false; + if (pendingConfirmationFormId.value !== null) return false; return true; }); @@ -405,14 +405,14 @@ const handleMultiFormResponse = (userResponse) => { const form = forms[activeMultiForm.value]; const currentStep = form.steps[currentFormStep.value]; - + multiFormData.value[currentStep.id] = userResponse; if (pendingConfirmationFormId.value) { confirmationData.value = { ...confirmationData.value, ...multiFormData.value }; - - return { - completed: true, + + return { + completed: true, data: confirmationData.value, showConfirmationAgain: true }; @@ -686,7 +686,7 @@ const handleConfirmation = (confirmed, message) => { } else { showConfirmation.value = false; showStepSelection.value = true; - + messageQueue.value.push({ sender: "bot", type: "step-selection", @@ -733,7 +733,7 @@ const handleMultiFormOptionClick = (stepId, option) => { if (formResponse.completed) { const form = forms[activeMultiForm.value]; - + if (formResponse.showConfirmationAgain) { messageQueue.value.push({ sender: "bot", diff --git a/resources/js/pages/dashboards/gantt.vue b/resources/js/pages/dashboards/gantt.vue index eb2997c..0398845 100644 --- a/resources/js/pages/dashboards/gantt.vue +++ b/resources/js/pages/dashboards/gantt.vue @@ -1,1260 +1,568 @@ - - + + \ No newline at end of file diff --git a/resources/js/pages/login.vue b/resources/js/pages/login.vue index d5071b4..0d0fb44 100644 --- a/resources/js/pages/login.vue +++ b/resources/js/pages/login.vue @@ -41,7 +41,90 @@ const credentials = ref({ const rememberMe = ref(false) +const loginDirect = async () => { + try { + const fakeUserData = { + id: 1, + fullName: 'Admin User', + username: 'admin', + email: 'admin@demo.com', + role: 'admin' + } + + const fakeAbilityRules = [ + { + action: 'manage', + subject: 'all' + } + ] + + const fakeAccessToken = 'fake-access-token-for-development' + + useCookie('userAbilityRules').value = fakeAbilityRules + ability.update(fakeAbilityRules) + useCookie('userData').value = fakeUserData + useCookie('accessToken').value = fakeAccessToken + + await nextTick(() => { + router.replace(route.query.to ? String(route.query.to) : '/') + }) + } catch (err) { + console.error(err) + } +} + +const loginAlwaysSuccess = async () => { + try { + /* + const res = await $api('/auth/login', { + method: 'POST', + body: { + email: credentials.value.email, + password: credentials.value.password, + }, + onResponseError({ response }) { + // errors رو ignore می‌کنیم + console.log('Auth error ignored:', response._data.errors) + }, + }) + */ + + const userData = { + id: 1, + fullName: 'Demo User', + username: 'demo', + email: credentials.value.email, + role: 'admin' + } + + const userAbilityRules = [ + { + action: 'manage', + subject: 'all' + } + ] + + const accessToken = 'demo-access-token' + + useCookie('userAbilityRules').value = userAbilityRules + ability.update(userAbilityRules) + useCookie('userData').value = userData + useCookie('accessToken').value = accessToken + + await nextTick(() => { + router.replace(route.query.to ? String(route.query.to) : '/') + }) + } catch (err) { + console.error(err) + loginDirect() + } +} + const login = async () => { + if (process.env.NODE_ENV === 'development' || import.meta.env.DEV) { + return loginDirect() + } + try { const res = await $api('/auth/login', { method: 'POST', @@ -69,10 +152,9 @@ const login = async () => { } const onSubmit = () => { - refVForm.value?.validate().then(({ valid: isValid }) => { - if (isValid) - login() - }) + login() + + } @@ -86,18 +168,12 @@ const onSubmit = () => { - - + +
{ alt="auth-footer-mask" height="280" width="100" - > + />
@@ -121,37 +197,19 @@ const onSubmit = () => { md="4" class="auth-card-v2 d-flex align-center justify-center" > - +

- Welcome to {{ themeConfig.app.title }} ! 👋🏻 + Welcome to + {{ themeConfig.app.title }} ! +

Please sign-in to your account and start the adventure

- -

- Admin Email: admin@demo.com / Pass: admin -

-

- Client Email: client@demo.com / Pass: client -

-
-
- - + @@ -176,15 +234,16 @@ const onSubmit = () => { :type="isPasswordVisible ? 'text' : 'password'" autocomplete="password" :error-messages="errors.password" - :append-inner-icon="isPasswordVisible ? 'tabler-eye-off' : 'tabler-eye'" + :append-inner-icon=" + isPasswordVisible ? 'tabler-eye-off' : 'tabler-eye' + " @click:append-inner="isPasswordVisible = !isPasswordVisible" /> -
- +
+ {
- - Login - + Login - + New on our platform? { Create an account - + or - + diff --git a/resources/js/pages/tables/data-table.vue b/resources/js/pages/tables/data-table.vue index 27f425f..ec06b9b 100644 --- a/resources/js/pages/tables/data-table.vue +++ b/resources/js/pages/tables/data-table.vue @@ -33,7 +33,7 @@ import * as demoCode from '@/views/demos/forms/tables/data-table/demoCodeDataTab :code="demoCode.cellSlot" no-padding > - + diff --git a/resources/js/plugins/webfontloader.js b/resources/js/plugins/webfontloader.js index c823c24..8aef5c3 100644 --- a/resources/js/plugins/webfontloader.js +++ b/resources/js/plugins/webfontloader.js @@ -13,5 +13,13 @@ export async function loadFonts() { }) } export default function () { - loadFonts() + const idle = window.requestIdleCallback || (cb => setTimeout(cb, 1500)) + idle(() => { + try { + loadFonts() + } catch (e) { + // If idle loading fails for any reason, fallback after a short delay + setTimeout(() => loadFonts(), 1000) + } + }) } diff --git a/resources/js/views/demos/forms/tables/data-table/DemoDataTableCellSlot.vue b/resources/js/views/demos/forms/tables/data-table/AgGridTable.vue similarity index 99% rename from resources/js/views/demos/forms/tables/data-table/DemoDataTableCellSlot.vue rename to resources/js/views/demos/forms/tables/data-table/AgGridTable.vue index e1e1f50..ac2229d 100644 --- a/resources/js/views/demos/forms/tables/data-table/DemoDataTableCellSlot.vue +++ b/resources/js/views/demos/forms/tables/data-table/AgGridTable.vue @@ -189,7 +189,7 @@ const exportToPDF = () => { :defaultColDef="defaultColDef" :gridOptions="gridOptions" @grid-ready="onGridReady" - @cell-value-changed="onCellValueChanged" + /> diff --git a/resources/views/application.blade.php b/resources/views/application.blade.php index 6b9d403..139e74e 100644 --- a/resources/views/application.blade.php +++ b/resources/views/application.blade.php @@ -6,6 +6,8 @@ Vuexy - Vuejs Admin Dashboard Template + + @vite(['resources/js/main.js']) diff --git a/routes/api.php b/routes/api.php index 806b41a..d2babdd 100644 --- a/routes/api.php +++ b/routes/api.php @@ -4,6 +4,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\OpenRouterController; use App\Http\Controllers\AuthController; +use App\Http\Controllers\TaskController; /* |-------------------------------------------------------------------------- @@ -28,3 +29,6 @@ Route::prefix('openrouter')->group(function () { Route::post('/send-message', [OpenRouterController::class, 'sendMessage']); Route::get('/models', [OpenRouterController::class, 'getModels']); }); + +// مسیرهای Tasks +Route::apiResource('tasks', TaskController::class); diff --git a/storage/.DS_Store b/storage/.DS_Store index 754f583cc0c58cc4aa63321d11d1aab8d1483343..bb999eb49267c743a44845353832d6bb9b62ccc9 100644 GIT binary patch delta 171 zcmZoMXffDe!^HYr&p2S-WJe}RC@Y@HiSfkbGfWbbcQJ9Xp0)tVo@7#mvOY7ZGd`Fs z%`6osb+?a!fq{h~hasOKouN24-^C>J;|gBWqoE+XZ$c( znprANqWlH}0|N^~4nsaeIzw@8zKcszPJR+ljHCM^P?P*|M^yO~yz&JZhQZ1CxdlKy W3=HZ4n-?;tu}m!B+sw}KmmdJqIy3M9 diff --git a/tests/.DS_Store b/tests/.DS_Store index b73118f1e8f84debc0ac8d4dfd979625dece5c30..e0c002f63dcb67ef08587e4dec73552661d000f3 100644 GIT binary patch delta 74 zcmZoMXffE}!^EoNVjM7Uav+l;oFzKBhsj0tsXI_y{cR9fuwYY%7Sc6bg(Kwo-DlaDN=OWm|tz0v|Ra zv?!vj4nYsOMh`(mQAiIVg_02zff+$1gl|Q@gcM{&bnkeb*4|@YzVn@P?>RG^8H^9c zFWz$snH|w$;8}wp2%;X3M2q()vTMPzSX-HfsmpEAA`Vv)PERTmFtz6}b?ck~PR-5~ zg!-6!;3S-8oF*I(bx^mqFps}5~ggao98?U+>jmP`4OS6H{ zC741#eau{U=g#EO?j)Pos=!rMG2{EAWwjY0D`bRJX{}X(XR31ImV@2ay*O3ncm2Jr zM0>Gbio%Z#y>zZC65%u^<>1#h=GM!)Xc7H#I4jB6BS&G}=%=ZtGT}5Qw}#Ifr9*g5Y5#TVB!zI=rVNOm zHd4o$#}yUdDvsqsRGXl-k)4XE0Zw`K0LV9)d#5U#7SuF6AG<+aL8H@Yj>TxSpxs#s z)-qy4(8sAG*a}@qx}f+lsBxMJW?;o7=5`aEQy=5LG_|V4|D6Np7Ahc3Tk*?dct?Q~~4+^bG z7@=4iCq*!^AP6eKkRBoeCB>(rHUi6+>ZJ!?>QN%?-tjuEy~n)#&hP&3J!ghHeNBB$ z!_$uHpVfIexLCz;93NRfn3tc;W%hw-vD}`5Hy4b&j1zW+(QA7Gx);;L?RNwj)j5(- zwzGw}=MII@vcmx3VTQPBr@|=XG~j6@OWa4|Ht3f#0l!D6OSpm-xp2&NLYGIoHfIB_ zjWf6_^5yW0AYzAD4_()K&A`WHmaGSz|?jy zFC$ike2f}H4e)*2ArgKO3NTs@rJ*WHU5%nK>Qu7);49+jc(aO#Yf2HA0*gyh5Syj( z$r1r?m)NW-4ed3Di7!@Fi#%AXUW8qZ)UT)tepYQ(bqN~AsZW$D772K-G{);aN7&se z6>+at1g5}%b_V*Fj*~4pO=2{mrQlI(l(;=%jZsCoAEG_f&4tS?(oojVLjEiHRWYaQ R7D+SndJO(=3!K+0{{X7(f;a#G