diff --git a/.DS_Store b/.DS_Store index bdac594..c626809 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/app/.DS_Store b/app/.DS_Store index 54216e1..dfef461 100644 Binary files a/app/.DS_Store and b/app/.DS_Store differ diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php new file mode 100644 index 0000000..6730dcc --- /dev/null +++ b/app/Http/Controllers/TaskController.php @@ -0,0 +1,215 @@ + 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 7d617a4..dd6c0b0 100644 Binary files a/database/.DS_Store and b/database/.DS_Store differ diff --git a/public/.DS_Store b/public/.DS_Store index 8dfd80e..4d11401 100644 Binary files a/public/.DS_Store and b/public/.DS_Store differ 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 15460b3..e1cb67f 100644 Binary files a/resources/.DS_Store and b/resources/.DS_Store differ diff --git a/resources/js/pages/apps/chat.vue b/resources/js/pages/apps/chat.vue index c636460..0429acd 100644 --- a/resources/js/pages/apps/chat.vue +++ b/resources/js/pages/apps/chat.vue @@ -184,7 +184,7 @@ const isQuickRepliesVisible = computed(() => { 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 754f583..bb999eb 100644 Binary files a/storage/.DS_Store and b/storage/.DS_Store differ diff --git a/tests/.DS_Store b/tests/.DS_Store index b73118f..e0c002f 100644 Binary files a/tests/.DS_Store and b/tests/.DS_Store differ diff --git a/vendor/.DS_Store b/vendor/.DS_Store index eb8338c..0ea84ea 100644 Binary files a/vendor/.DS_Store and b/vendor/.DS_Store differ