From b9964bad2114c0936212eb7984d800cc40c0ca40 Mon Sep 17 00:00:00 2001 From: Babak Alizadeh Date: Mon, 1 Sep 2025 13:21:04 -0400 Subject: [PATCH] progress in base system --- .env | 8 +- .env.local.php | 3 +- README.md | 40 +- core/composer.json | 1 + core/composer.lock | 64 ++- core/config/bundles.php | 1 + core/config/packages/nelmio_cors.yaml | 13 + core/config/packages/translation.yaml | 8 +- core/config/packages/twig.yaml | 1 - core/config/services.yaml | 17 + core/migrations/Version20241201000001.php | 31 ++ core/src/Controller/Api/AuthController.php | 282 ++++++++++ .../Controller/Api/LocaleApiController.php | 48 ++ .../Controller/Api/TestEventController.php | 64 +++ .../Auth/RegistrationController.php | 78 --- .../Auth/ResetPasswordController.php | 128 ----- .../Controller/Auth/SecurityController.php | 36 -- core/src/Controller/LocaleController.php | 46 ++ core/src/Controller/UIController.php | 39 +- core/src/Entity/User.php | 28 + core/src/Event/Auth/UserLoginEvent.php | 38 ++ core/src/Event/BaseEvent.php | 64 +++ .../EventListener/Auth/LoginAuditListener.php | 55 ++ .../Auth/UserActivityListener.php | 71 +++ core/src/EventListener/LocaleListener.php | 40 ++ .../RollbackableEventListenerInterface.php | 23 + core/src/Form/Auth/ChangePasswordFormType.php | 54 -- core/src/Form/Auth/RegistrationFormType.php | 106 ---- .../Auth/ResetPasswordRequestFormType.php | 35 -- core/src/Service/EventTransactionManager.php | 123 +++++ core/symfony.lock | 12 + core/templates/auth/base.html.twig | 514 ------------------ .../auth/registration/register.html.twig | 109 ---- .../auth/reset_password/check_email.html.twig | 61 --- .../auth/reset_password/request.html.twig | 64 --- .../auth/reset_password/reset.html.twig | 90 --- core/templates/auth/security/login.html.twig | 103 ---- core/templates/base.html.twig | 10 +- .../reset_password.html.twig} | 59 +- core/templates/home/index.html.twig | 18 +- core/templates/ui/app.html.twig | 7 +- core/templates/ui/auth.html.twig | 17 + core/translations/messages.en.yaml | 59 ++ core/translations/messages.fa.yaml | 59 ++ frontend/package-lock.json | 61 +++ frontend/package.json | 1 + frontend/public/index.html | 12 - frontend/src/app.js | 7 + frontend/src/assets/styles/components-rtl.css | 387 +++++++++++++ frontend/src/assets/styles/rtl-ltr.css | 172 ++++++ frontend/src/assets/styles/theme.css | 65 +++ frontend/src/assets/styles/vuetify-rtl.css | 171 ++++++ frontend/src/auth.js | 7 + frontend/src/components/LanguageSwitcher.vue | 153 ++++++ frontend/src/components/ThemeSwitcher.vue | 151 +++++ frontend/src/i18n/index.js | 47 ++ frontend/src/locales/en.js | 74 +++ frontend/src/locales/fa.js | 74 +++ frontend/src/main.js | 146 +++-- frontend/src/plugins/vuetify.js | 63 +++ frontend/src/router/app.js | 75 +++ frontend/src/router/auth.js | 68 +++ frontend/src/router/index.js | 96 +--- frontend/src/views/auth/forgot-password.vue | 107 ++++ frontend/src/views/auth/login.vue | 226 ++++++++ frontend/src/views/auth/register.vue | 171 ++++++ frontend/webpack.config.js | 13 +- public_html/.htaccess | 8 + public_html/favicon.ico | Bin 0 -> 15406 bytes public_html/img/avatar.jpg | Bin 0 -> 71783 bytes public_html/img/avatar.png | Bin 0 -> 16277 bytes public_html/img/logo-blue.png | Bin 0 -> 10697 bytes public_html/img/logo-light.png | Bin 0 -> 9994 bytes public_html/img/logo.png | Bin 0 -> 23715 bytes public_html/img/logo32.png | Bin 0 -> 858 bytes public_html/robots.txt | 3 + 76 files changed, 3493 insertions(+), 1592 deletions(-) create mode 100644 core/config/packages/nelmio_cors.yaml create mode 100644 core/migrations/Version20241201000001.php create mode 100644 core/src/Controller/Api/AuthController.php create mode 100644 core/src/Controller/Api/LocaleApiController.php create mode 100644 core/src/Controller/Api/TestEventController.php delete mode 100644 core/src/Controller/Auth/RegistrationController.php delete mode 100644 core/src/Controller/Auth/ResetPasswordController.php delete mode 100644 core/src/Controller/Auth/SecurityController.php create mode 100644 core/src/Controller/LocaleController.php create mode 100644 core/src/Event/Auth/UserLoginEvent.php create mode 100644 core/src/Event/BaseEvent.php create mode 100644 core/src/EventListener/Auth/LoginAuditListener.php create mode 100644 core/src/EventListener/Auth/UserActivityListener.php create mode 100644 core/src/EventListener/LocaleListener.php create mode 100644 core/src/EventListener/RollbackableEventListenerInterface.php delete mode 100644 core/src/Form/Auth/ChangePasswordFormType.php delete mode 100644 core/src/Form/Auth/RegistrationFormType.php delete mode 100644 core/src/Form/Auth/ResetPasswordRequestFormType.php create mode 100644 core/src/Service/EventTransactionManager.php delete mode 100644 core/templates/auth/base.html.twig delete mode 100644 core/templates/auth/registration/register.html.twig delete mode 100644 core/templates/auth/reset_password/check_email.html.twig delete mode 100644 core/templates/auth/reset_password/request.html.twig delete mode 100644 core/templates/auth/reset_password/reset.html.twig delete mode 100644 core/templates/auth/security/login.html.twig rename core/templates/{auth/reset_password/email.html.twig => emails/reset_password.html.twig} (66%) create mode 100644 core/templates/ui/auth.html.twig create mode 100644 core/translations/messages.en.yaml create mode 100644 core/translations/messages.fa.yaml delete mode 100644 frontend/public/index.html create mode 100644 frontend/src/app.js create mode 100644 frontend/src/assets/styles/components-rtl.css create mode 100644 frontend/src/assets/styles/rtl-ltr.css create mode 100644 frontend/src/assets/styles/theme.css create mode 100644 frontend/src/assets/styles/vuetify-rtl.css create mode 100644 frontend/src/auth.js create mode 100644 frontend/src/components/LanguageSwitcher.vue create mode 100644 frontend/src/components/ThemeSwitcher.vue create mode 100644 frontend/src/i18n/index.js create mode 100644 frontend/src/locales/en.js create mode 100644 frontend/src/locales/fa.js create mode 100644 frontend/src/plugins/vuetify.js create mode 100644 frontend/src/router/app.js create mode 100644 frontend/src/router/auth.js create mode 100644 frontend/src/views/auth/forgot-password.vue create mode 100644 frontend/src/views/auth/login.vue create mode 100644 frontend/src/views/auth/register.vue create mode 100644 public_html/favicon.ico create mode 100644 public_html/img/avatar.jpg create mode 100644 public_html/img/avatar.png create mode 100644 public_html/img/logo-blue.png create mode 100644 public_html/img/logo-light.png create mode 100644 public_html/img/logo.png create mode 100644 public_html/img/logo32.png create mode 100644 public_html/robots.txt diff --git a/.env b/.env index 42ad71d..f2ba6d2 100644 --- a/.env +++ b/.env @@ -24,9 +24,9 @@ APP_SECRET= # IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml # # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db" -# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" +DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" -DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" +# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" ###< doctrine/doctrine-bundle ### ###> symfony/messenger ### @@ -39,3 +39,7 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 ###> symfony/mailer ### MAILER_DSN=null://null ###< symfony/mailer ### + +###> nelmio/cors-bundle ### +CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$' +###< nelmio/cors-bundle ### diff --git a/.env.local.php b/.env.local.php index c8c314e..d91628d 100644 --- a/.env.local.php +++ b/.env.local.php @@ -6,7 +6,8 @@ return array ( 'APP_ENV' => 'dev', 'SYMFONY_DOTENV_PATH' => './../.env', 'APP_SECRET' => '6c6ccf94990dea080eeba986bf7e23af', - 'DATABASE_URL' => 'postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8', + 'DATABASE_URL' => 'mysql://root:136431@127.0.0.1:3306/hsx?serverVersion=8.0.32&charset=utf8mb4', 'MESSENGER_TRANSPORT_DSN' => 'doctrine://default?auto_setup=0', 'MAILER_DSN' => 'null://null', + 'CORS_ALLOW_ORIGIN' => '^https?://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?$', ); diff --git a/README.md b/README.md index 172be4f..62df869 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ │ │ ├── views/ # صفحات اصلی │ │ ├── router/ # Vue Router │ │ ├── store/ # Vuex store -│ │ └── assets/ # فایل‌های استاتیک +│ │ ├── assets/ # فایل‌های استاتیک +│ │ │ └── styles/ # فایل‌های CSS +│ │ └── i18n/ # بین‌المللی‌سازی │ ├── public/ │ ├── package.json │ └── webpack.config.js @@ -87,10 +89,33 @@ npm run build # Build production ## 🎨 UI/UX Features - **RTL Support**: پشتیبانی کامل از راست به چپ -- **Persian Font**: فونت Vazirmatn +- **Persian Font**: فونت Vazir و Tahoma - **Material Design**: کامپوننت‌های زیبا - **Responsive**: سازگار با همه دستگاه‌ها - **Dark/Light Theme**: تم‌های مختلف +- **Multilingual**: پشتیبانی از فارسی و انگلیسی + +## 🌍 پشتیبانی از RTL (راست‌چین) + +### ویژگی‌های RTL +- **تغییر خودکار جهت**: صفحه به صورت خودکار راست‌چین/چپ‌چین می‌شود +- **فونت‌های مناسب**: Vazir برای فارسی، Roboto برای انگلیسی +- **کامپوننت‌های Vuetify**: تمام کامپوننت‌ها از RTL پشتیبانی می‌کنند +- **Responsive RTL**: سازگار با تمام اندازه‌های صفحه + +### فایل‌های RTL +- `src/assets/styles/rtl-ltr.css` - استایل‌های پایه RTL/LTR +- `src/assets/styles/vuetify-rtl.css` - پشتیبانی RTL برای Vuetify +- `src/assets/styles/components-rtl.css` - RTL برای کامپوننت‌های خاص +- `src/components/RTLTest.vue` - کامپوننت تست RTL + +### نحوه استفاده +```javascript +// تغییر زبان و جهت +import { changeLocale } from './i18n' +changeLocale('fa') // فارسی - راست‌چین +changeLocale('en') // انگلیسی - چپ‌چین +``` ## 📊 کامپوننت‌های Vuetify @@ -129,7 +154,8 @@ npm run build - Build process کاملاً مستقل است - Symfony به عنوان API backend عمل می‌کند - Vue Router برای client-side routing استفاده می‌شود -- فونت فارسی Vazirmatn برای RTL استفاده شده +- فونت فارسی Vazir برای RTL استفاده شده +- پشتیبانی کامل از RTL در تمام کامپوننت‌ها ## 🐛 عیب‌یابی @@ -137,14 +163,22 @@ npm run build 1. **Node modules**: `rm -rf node_modules && npm install` 2. **Build errors**: بررسی webpack.config.js 3. **Routing issues**: بررسی .htaccess +4. **RTL issues**: بررسی فایل‌های CSS و i18n ### Logs - Symfony: `core/var/log/` - Webpack: `frontend/` console +## 📚 مستندات اضافی + +- `frontend/RTL_SETUP.md` - راهنمای کامل RTL +- `frontend/MULTILINGUAL_SETUP.md` - راهنمای چندزبانه +- `frontend/THEME_SETUP.md` - راهنمای تم‌ها + ## 📞 پشتیبانی برای سوالات و مشکلات: - بررسی documentation - بررسی console errors - بررسی network tab +- تست کامپوننت RTLTest diff --git a/core/composer.json b/core/composer.json index bde38e4..a9d3e16 100644 --- a/core/composer.json +++ b/core/composer.json @@ -11,6 +11,7 @@ "doctrine/doctrine-bundle": "^2.15", "doctrine/doctrine-migrations-bundle": "^3.4", "doctrine/orm": "^3.5", + "nelmio/cors-bundle": "^2.5", "phpdocumentor/reflection-docblock": "^5.6", "phpstan/phpdoc-parser": "^2.3", "symfony/apache-pack": "*", diff --git a/core/composer.lock b/core/composer.lock index 2db0a93..b683e48 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0c02e701f0667561c6de51c5995abb1f", + "content-hash": "42015cabfb93805b806ccf473df84f01", "packages": [ { "name": "doctrine/collections", @@ -1300,6 +1300,68 @@ ], "time": "2025-03-24T10:02:05+00:00" }, + { + "name": "nelmio/cors-bundle", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/nelmio/NelmioCorsBundle.git", + "reference": "3a526fe025cd20e04a6a11370cf5ab28dbb5a544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/3a526fe025cd20e04a6a11370cf5ab28dbb5a544", + "reference": "3a526fe025cd20e04a6a11370cf5ab28dbb5a544", + "shasum": "" + }, + "require": { + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.3.6", + "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Nelmio\\CorsBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nelmio", + "homepage": "http://nelm.io" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/nelmio/NelmioCorsBundle/contributors" + } + ], + "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony application", + "keywords": [ + "api", + "cors", + "crossdomain" + ], + "support": { + "issues": "https://github.com/nelmio/NelmioCorsBundle/issues", + "source": "https://github.com/nelmio/NelmioCorsBundle/tree/2.5.0" + }, + "time": "2024-06-24T21:25:28+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", diff --git a/core/config/bundles.php b/core/config/bundles.php index 3325715..57b43cb 100644 --- a/core/config/bundles.php +++ b/core/config/bundles.php @@ -12,4 +12,5 @@ return [ Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true], ]; diff --git a/core/config/packages/nelmio_cors.yaml b/core/config/packages/nelmio_cors.yaml new file mode 100644 index 0000000..92c5b67 --- /dev/null +++ b/core/config/packages/nelmio_cors.yaml @@ -0,0 +1,13 @@ +nelmio_cors: + defaults: + origin_regex: true + allow_origin: ['%env(CORS_ALLOW_ORIGIN)%'] + allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE'] + allow_headers: ['Content-Type', 'Authorization'] + expose_headers: ['Link'] + max_age: 3600 + paths: + '^/api/': + allow_origin: ['*'] + allow_headers: ['*'] + allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS'] diff --git a/core/config/packages/translation.yaml b/core/config/packages/translation.yaml index 490bfc2..43fe1da 100644 --- a/core/config/packages/translation.yaml +++ b/core/config/packages/translation.yaml @@ -1,5 +1,11 @@ framework: - default_locale: en + default_locale: fa translator: default_path: '%kernel.project_dir%/translations' + fallbacks: + - fa providers: + app: + dsn: 'app://translations' + set_content_language_from_locale: true + set_locale_from_accept_language: true diff --git a/core/config/packages/twig.yaml b/core/config/packages/twig.yaml index 3f795d9..a9a3559 100644 --- a/core/config/packages/twig.yaml +++ b/core/config/packages/twig.yaml @@ -1,6 +1,5 @@ twig: file_name_pattern: '*.twig' - when@test: twig: strict_variables: true diff --git a/core/config/services.yaml b/core/config/services.yaml index 6bbad87..2cfa29e 100644 --- a/core/config/services.yaml +++ b/core/config/services.yaml @@ -16,5 +16,22 @@ services: App\: resource: '../src/' + # Locale Listener + App\EventListener\LocaleListener: + arguments: + $requestStack: '@request_stack' + $localeSwitcher: '@translation.locale_switcher' + tags: + - { name: kernel.event_listener, event: kernel.request, priority: 17 } + + # Event Listeners + App\EventListener\Auth\LoginAuditListener: + tags: + - { name: kernel.event_listener, event: App\Event\Auth\UserLoginEvent, method: onEvent, priority: 100 } + + App\EventListener\Auth\UserActivityListener: + tags: + - { name: kernel.event_listener, event: App\Event\Auth\UserLoginEvent, method: onEvent, priority: 200 } + # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones diff --git a/core/migrations/Version20241201000001.php b/core/migrations/Version20241201000001.php new file mode 100644 index 0000000..7e35798 --- /dev/null +++ b/core/migrations/Version20241201000001.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE `user` ADD last_login_at DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE `user` ADD login_count INT NOT NULL DEFAULT 0'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE `user` DROP last_login_at'); + $this->addSql('ALTER TABLE `user` DROP login_count'); + } +} diff --git a/core/src/Controller/Api/AuthController.php b/core/src/Controller/Api/AuthController.php new file mode 100644 index 0000000..1ecf51e --- /dev/null +++ b/core/src/Controller/Api/AuthController.php @@ -0,0 +1,282 @@ +getContent(), true); + + if (!$data || !isset($data['email']) || !isset($data['password'])) { + return $this->json([ + 'success' => false, + 'message' => 'ایمیل و رمز عبور الزامی است' + ], Response::HTTP_BAD_REQUEST); + } + + $user = $this->userRepository->findByEmail($data['email']); + + if (!$user || !$this->userPasswordHasher->isPasswordValid($user, $data['password'])) { + return $this->json([ + 'success' => false, + 'message' => 'ایمیل یا رمز عبور اشتباه است' + ], Response::HTTP_UNAUTHORIZED); + } + + try { + // ایجاد رویداد ورود کاربر + $loginEvent = new UserLoginEvent( + $user, + $request->getClientIp() ?? 'unknown', + $request->headers->get('User-Agent') ?? 'unknown' + ); + + // اجرای عملیات با رویدادها + $this->eventTransactionManager->executeWithEvents( + function () { + // عملیات اصلی (فعلاً خالی) + return true; + }, + [$loginEvent] + ); + + return $this->json([ + 'success' => true, + 'message' => 'ورود موفقیت‌آمیز', + 'user' => [ + 'id' => $user->getId(), + 'email' => $user->getEmail(), + 'fullName' => $user->getFullName(), + 'mobile' => $user->getMobile(), + 'roles' => $user->getRoles(), + 'lastLoginAt' => $user->getLastLoginAt()?->format('Y-m-d H:i:s'), + 'loginCount' => $user->getLoginCount() + ] + ]); + + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'message' => 'خطا در ورود: ' . $e->getMessage() + ], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } + + #[Route('/register', name: 'register', methods: ['POST'])] + public function register(Request $request): JsonResponse + { + $data = json_decode($request->getContent(), true); + + if (!$data || !isset($data['email']) || !isset($data['password']) || !isset($data['fullName']) || !isset($data['mobile'])) { + return $this->json([ + 'success' => false, + 'message' => 'تمام فیلدها الزامی است' + ], Response::HTTP_BAD_REQUEST); + } + + // بررسی تکراری نبودن ایمیل و موبایل + $existingUser = $this->userRepository->findByEmail($data['email']); + if ($existingUser) { + return $this->json([ + 'success' => false, + 'message' => 'این ایمیل قبلاً ثبت شده است' + ], Response::HTTP_CONFLICT); + } + + $existingUser = $this->userRepository->findByMobile($data['mobile']); + if ($existingUser) { + return $this->json([ + 'success' => false, + 'message' => 'این شماره موبایل قبلاً ثبت شده است' + ], Response::HTTP_CONFLICT); + } + + $user = new User(); + $user->setEmail($data['email']); + $user->setMobile($data['mobile']); + $user->setFullName($data['fullName']); + $user->setPassword($this->userPasswordHasher->hashPassword($user, $data['password'])); + $user->setRoles(['ROLE_USER']); + $user->setIsVerified(true); + + // اعتبارسنجی entity + $errors = $this->validator->validate($user); + if (count($errors) > 0) { + $errorMessages = []; + foreach ($errors as $error) { + $errorMessages[] = $error->getMessage(); + } + return $this->json([ + 'success' => false, + 'message' => 'خطا در اعتبارسنجی داده‌ها', + 'errors' => $errorMessages + ], Response::HTTP_BAD_REQUEST); + } + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return $this->json([ + 'success' => true, + 'message' => 'ثبت‌نام با موفقیت انجام شد', + 'user' => [ + 'id' => $user->getId(), + 'email' => $user->getEmail(), + 'fullName' => $user->getFullName(), + 'mobile' => $user->getMobile() + ] + ], Response::HTTP_CREATED); + } + + #[Route('/forgot-password', name: 'forgot_password', methods: ['POST'])] + public function forgotPassword(Request $request): JsonResponse + { + $data = json_decode($request->getContent(), true); + + if (!$data || !isset($data['email'])) { + return $this->json([ + 'success' => false, + 'message' => 'ایمیل الزامی است' + ], Response::HTTP_BAD_REQUEST); + } + + $user = $this->userRepository->findByEmail($data['email']); + + if (!$user) { + // برای امنیت، همیشه پیام موفقیت نمایش می‌دهیم + return $this->json([ + 'success' => true, + 'message' => 'اگر ایمیل در سیستم موجود باشد، لینک بازنشانی ارسال خواهد شد' + ]); + } + + try { + $resetToken = $this->tokenGenerator->generateToken(); + $user->setResetToken($resetToken); + $user->setResetTokenExpiresAt(new \DateTimeImmutable('+1 hour')); + + $this->entityManager->flush(); + + // ارسال ایمیل (در حالت واقعی باید template مناسب ایجاد شود) + $email = (new TemplatedEmail()) + ->from('noreply@hesabix.ir') + ->to($user->getEmail()) + ->subject('درخواست بازنشانی رمز عبور') + ->htmlTemplate('emails/reset_password.html.twig') + ->context([ + 'resetToken' => $resetToken, + 'user' => $user, + ]) + ; + + $this->mailer->send($email); + + return $this->json([ + 'success' => true, + 'message' => 'لینک بازنشانی رمز عبور به ایمیل شما ارسال شد' + ]); + + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'message' => 'خطا در ارسال ایمیل بازنشانی' + ], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } + + #[Route('/reset-password', name: 'reset_password', methods: ['POST'])] + public function resetPassword(Request $request): JsonResponse + { + $data = json_decode($request->getContent(), true); + + if (!$data || !isset($data['token']) || !isset($data['password'])) { + return $this->json([ + 'success' => false, + 'message' => 'توکن و رمز عبور جدید الزامی است' + ], Response::HTTP_BAD_REQUEST); + } + + $user = $this->userRepository->findByResetToken($data['token']); + + if (!$user || $user->isResetTokenExpired()) { + return $this->json([ + 'success' => false, + 'message' => 'توکن بازنشانی نامعتبر یا منقضی شده است' + ], Response::HTTP_BAD_REQUEST); + } + + $user->setPassword($this->userPasswordHasher->hashPassword($user, $data['password'])); + $user->setResetToken(null); + $user->setResetTokenExpiresAt(null); + + $this->entityManager->flush(); + + return $this->json([ + 'success' => true, + 'message' => 'رمز عبور شما با موفقیت تغییر یافت' + ]); + } + + #[Route('/logout', name: 'logout', methods: ['POST'])] + public function logout(): JsonResponse + { + // در اینجا می‌توانید JWT token را invalid کنید یا session را پاک کنید + return $this->json([ + 'success' => true, + 'message' => 'خروج موفقیت‌آمیز' + ]); + } + + #[Route('/me', name: 'me', methods: ['GET'])] + #[IsGranted('ROLE_USER')] + public function me(): JsonResponse + { + $user = $this->getUser(); + + return $this->json([ + 'success' => true, + 'user' => [ + 'id' => $user->getId(), + 'email' => $user->getEmail(), + 'fullName' => $user->getFullName(), + 'mobile' => $user->getMobile(), + 'roles' => $user->getRoles(), + 'isVerified' => $user->isVerified(), + 'createdAt' => $user->getCreatedAt()->format('Y-m-d H:i:s') + ] + ]); + } +} diff --git a/core/src/Controller/Api/LocaleApiController.php b/core/src/Controller/Api/LocaleApiController.php new file mode 100644 index 0000000..f4aae1c --- /dev/null +++ b/core/src/Controller/Api/LocaleApiController.php @@ -0,0 +1,48 @@ +get('_locale', 'fa'); + + return $this->json([ + 'locale' => $locale, + 'direction' => $locale === 'fa' ? 'rtl' : 'ltr', + 'language' => $locale === 'fa' ? 'فارسی' : 'English' + ]); + } + + #[Route('/change/{locale}', name: 'api_locale_change', methods: ['POST'], requirements: ['locale' => 'fa|en'])] + public function changeLocale( + string $locale, + Request $request, + SessionInterface $session, + LocaleSwitcher $localeSwitcher + ): JsonResponse { + // Set locale in session + $session->set('_locale', $locale); + + // Set locale for current request + $localeSwitcher->setLocale($locale); + + return $this->json([ + 'success' => true, + 'locale' => $locale, + 'direction' => $locale === 'fa' ? 'rtl' : 'ltr', + 'language' => $locale === 'fa' ? 'فارسی' : 'English', + 'message' => 'زبان با موفقیت تغییر کرد' + ]); + } +} diff --git a/core/src/Controller/Api/TestEventController.php b/core/src/Controller/Api/TestEventController.php new file mode 100644 index 0000000..367da9e --- /dev/null +++ b/core/src/Controller/Api/TestEventController.php @@ -0,0 +1,64 @@ +setEmail('test@example.com'); + $user->setFullName('کاربر تست'); + $user->setMobile('09123456789'); + $user->setPassword('password'); + $user->setRoles(['ROLE_USER']); + + // ایجاد رویداد ورود + $loginEvent = new UserLoginEvent( + $user, + '127.0.0.1', + 'Test Browser' + ); + + // اجرای عملیات با رویدادها + $result = $this->eventTransactionManager->executeWithEvents( + function () { + // عملیات اصلی (فعلاً خالی) + return 'عملیات اصلی با موفقیت انجام شد'; + }, + [$loginEvent] + ); + + return $this->json([ + 'success' => true, + 'message' => 'سیستم رویدادها با موفقیت کار کرد', + 'result' => $result, + 'eventData' => $loginEvent->getData(), + 'eventSuccess' => $loginEvent->isSuccessful(), + 'eventErrors' => $loginEvent->getErrors() + ]); + + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'message' => 'خطا در تست سیستم رویدادها: ' . $e->getMessage() + ], 500); + } + } +} diff --git a/core/src/Controller/Auth/RegistrationController.php b/core/src/Controller/Auth/RegistrationController.php deleted file mode 100644 index f39f09b..0000000 --- a/core/src/Controller/Auth/RegistrationController.php +++ /dev/null @@ -1,78 +0,0 @@ -getUser()) { - return $this->redirectToRoute('app_home'); - } - - $user = new User(); - $form = $this->createForm(RegistrationFormType::class, $user); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - // بررسی تکراری نبودن ایمیل و موبایل - $existingUser = $userRepository->findByEmail($user->getEmail()); - if ($existingUser) { - $this->addFlash('error', 'این ایمیل قبلاً ثبت شده است'); - return $this->render('auth/registration/register.html.twig', [ - 'registrationForm' => $form->createView(), - ]); - } - - $existingUser = $userRepository->findByMobile($user->getMobile()); - if ($existingUser) { - $this->addFlash('error', 'این شماره موبایل قبلاً ثبت شده است'); - return $this->render('auth/registration/register.html.twig', [ - 'registrationForm' => $form->createView(), - ]); - } - - // رمزگذاری رمز عبور - $user->setPassword( - $userPasswordHasher->hashPassword( - $user, - $form->get('plainPassword')->getData() - ) - ); - - // تنظیم نقش کاربر - $user->setRoles(['ROLE_USER']); - $user->setIsVerified(true); // در حالت واقعی باید تایید ایمیل انجام شود - - $entityManager->persist($user); - $entityManager->flush(); - - $this->addFlash('success', 'ثبت‌نام با موفقیت انجام شد. حالا می‌توانید وارد شوید.'); - - return $this->redirectToRoute('app_login'); - } - - return $this->render('auth/registration/register.html.twig', [ - 'registrationForm' => $form->createView(), - ]); - } -} diff --git a/core/src/Controller/Auth/ResetPasswordController.php b/core/src/Controller/Auth/ResetPasswordController.php deleted file mode 100644 index cfa8214..0000000 --- a/core/src/Controller/Auth/ResetPasswordController.php +++ /dev/null @@ -1,128 +0,0 @@ -createForm(ResetPasswordRequestFormType::class); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - return $this->processSendingPasswordResetEmail( - $form->get('email')->getData() - ); - } - - return $this->render('auth/reset_password/request.html.twig', [ - 'requestForm' => $form->createView(), - ]); - } - - #[Route('/check-email', name: 'app_check_email')] - public function checkEmail(): Response - { - // این صفحه فقط برای نمایش پیام استفاده می‌شود - return $this->render('auth/reset_password/check_email.html.twig'); - } - - #[Route('/reset/{token}', name: 'app_reset_password')] - public function reset(string $token, Request $request, UserPasswordHasherInterface $userPasswordHasher): Response - { - $user = $this->userRepository->findByResetToken($token); - - if (null === $user || $user->isResetTokenExpired()) { - $this->addFlash('error', 'توکن بازنشانی نامعتبر یا منقضی شده است'); - return $this->redirectToRoute('app_forgot_password_request'); - } - - $form = $this->createForm(ChangePasswordFormType::class); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $user->setPassword( - $userPasswordHasher->hashPassword( - $user, - $form->get('plainPassword')->getData() - ) - ); - - $user->setResetToken(null); - $user->setResetTokenExpiresAt(null); - - $this->entityManager->flush(); - - $this->addFlash('success', 'رمز عبور شما با موفقیت تغییر یافت'); - - return $this->redirectToRoute('app_login'); - } - - return $this->render('auth/reset_password/reset.html.twig', [ - 'resetForm' => $form->createView(), - ]); - } - - private function processSendingPasswordResetEmail(string $emailFormData): RedirectResponse - { - $user = $this->userRepository->findByEmail($emailFormData); - - if (!$user) { - // برای امنیت، همیشه پیام موفقیت نمایش می‌دهیم - return $this->redirectToRoute('app_check_email'); - } - - try { - $resetToken = $this->tokenGenerator->generateToken(); - $user->setResetToken($resetToken); - $user->setResetTokenExpiresAt(new \DateTimeImmutable('+1 hour')); - - $this->entityManager->flush(); - } catch (\Exception $e) { - $this->addFlash('error', 'خطا در ایجاد توکن بازنشانی'); - return $this->redirectToRoute('app_forgot_password_request'); - } - - $email = (new TemplatedEmail()) - ->from('noreply@hesabix.ir') - ->to($user->getEmail()) - ->subject('درخواست بازنشانی رمز عبور') - ->htmlTemplate('reset_password/email.html.twig') - ->context([ - 'resetToken' => $resetToken, - 'user' => $user, - ]) - ; - - $this->mailer->send($email); - - return $this->redirectToRoute('app_check_email'); - } -} diff --git a/core/src/Controller/Auth/SecurityController.php b/core/src/Controller/Auth/SecurityController.php deleted file mode 100644 index a311cb1..0000000 --- a/core/src/Controller/Auth/SecurityController.php +++ /dev/null @@ -1,36 +0,0 @@ -getUser()) { - return $this->redirectToRoute('app_home'); - } - - $error = $authenticationUtils->getLastAuthenticationError(); - $lastUsername = $authenticationUtils->getLastUsername(); - - return $this->render('auth/security/login.html.twig', [ - 'last_username' => $lastUsername, - 'error' => $error, - ]); - } - - #[Route(path: '/logout', name: 'app_logout')] - public function logout(): void - { - // این متد توسط Symfony Security Bundle مدیریت می‌شود - // کد اینجا اجرا نمی‌شود - throw new \LogicException('این متد باید توسط Symfony Security Bundle مدیریت شود'); - } -} diff --git a/core/src/Controller/LocaleController.php b/core/src/Controller/LocaleController.php new file mode 100644 index 0000000..dcd8620 --- /dev/null +++ b/core/src/Controller/LocaleController.php @@ -0,0 +1,46 @@ + 'fa|en'])] + public function switchLocale( + string $locale, + Request $request, + SessionInterface $session, + LocaleSwitcher $localeSwitcher + ): Response { + // Set locale in session + $session->set('_locale', $locale); + + // Set locale for current request + $localeSwitcher->setLocale($locale); + + // Redirect back to previous page or home + $referer = $request->headers->get('referer'); + if ($referer) { + return $this->redirect($referer); + } + + return $this->redirectToRoute('app_home'); + } + + #[Route('/api/locale', name: 'api_locale_get', methods: ['GET'])] + public function getCurrentLocale(SessionInterface $session): Response + { + $locale = $session->get('_locale', 'fa'); + + return $this->json([ + 'locale' => $locale, + 'direction' => $locale === 'fa' ? 'rtl' : 'ltr' + ]); + } +} diff --git a/core/src/Controller/UIController.php b/core/src/Controller/UIController.php index c99d481..3a9d900 100644 --- a/core/src/Controller/UIController.php +++ b/core/src/Controller/UIController.php @@ -10,39 +10,22 @@ final class UIController extends AbstractController { #[Route('/ui', name: 'app_ui_home')] #[Route('/ui/{route}', name: 'app_ui_route', requirements: ['route' => '.+'])] - public function index(string $route = ''): Response + public function app_ui_home(string $route = ''): Response { - // Extract the main page from route - $page = $this->extractPageFromRoute($route); return $this->render('ui/app.html.twig', [ - 'page' => $page, + 'route' => $route + ]); + } + + #[Route('/auth', name: 'app_auth_home')] + #[Route('/auth/{route}', name: 'app_auth_route', requirements: ['route' => '.+'])] + public function app_auth_home(string $route = ''): Response + { + + return $this->render('ui/auth.html.twig', [ 'route' => $route ]); } - private function extractPageFromRoute(string $route): string - { - // Remove leading slash and get first segment - $route = ltrim($route, '/'); - - if (empty($route)) { - return 'dashboard'; - } - - // Split by slash and get first part - $segments = explode('/', $route); - $mainPage = $segments[0]; - - // Map route to page - $pageMap = [ - 'dashboard' => 'dashboard', - 'accounts' => 'accounts', - 'transactions' => 'transactions', - 'reports' => 'reports', - 'settings' => 'settings' - ]; - - return $pageMap[$mainPage] ?? 'dashboard'; - } } diff --git a/core/src/Entity/User.php b/core/src/Entity/User.php index 4b87c4d..b54b2a0 100644 --- a/core/src/Entity/User.php +++ b/core/src/Entity/User.php @@ -64,6 +64,12 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(nullable: true)] private ?\DateTimeImmutable $resetTokenExpiresAt = null; + #[ORM\Column(nullable: true)] + private ?\DateTimeImmutable $lastLoginAt = null; + + #[ORM\Column] + private int $loginCount = 0; + public function __construct() { $this->createdAt = new \DateTimeImmutable(); @@ -205,4 +211,26 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface } return $this->resetTokenExpiresAt < new \DateTimeImmutable(); } + + public function getLastLoginAt(): ?\DateTimeImmutable + { + return $this->lastLoginAt; + } + + public function setLastLoginAt(?\DateTimeImmutable $lastLoginAt): static + { + $this->lastLoginAt = $lastLoginAt; + return $this; + } + + public function getLoginCount(): int + { + return $this->loginCount; + } + + public function setLoginCount(int $loginCount): static + { + $this->loginCount = $loginCount; + return $this; + } } diff --git a/core/src/Event/Auth/UserLoginEvent.php b/core/src/Event/Auth/UserLoginEvent.php new file mode 100644 index 0000000..c13e29b --- /dev/null +++ b/core/src/Event/Auth/UserLoginEvent.php @@ -0,0 +1,38 @@ +setData([ + 'userId' => $user->getId(), + 'email' => $user->getEmail(), + 'ipAddress' => $ipAddress, + 'userAgent' => $userAgent, + 'timestamp' => new \DateTimeImmutable() + ]); + } + + public function getUser(): User + { + return $this->user; + } + + public function getIpAddress(): string + { + return $this->ipAddress; + } + + public function getUserAgent(): string + { + return $this->userAgent; + } +} diff --git a/core/src/Event/BaseEvent.php b/core/src/Event/BaseEvent.php new file mode 100644 index 0000000..e5241e2 --- /dev/null +++ b/core/src/Event/BaseEvent.php @@ -0,0 +1,64 @@ +success = false; + $this->errors[] = $error; + } + + public function markAsSuccessful(): void + { + $this->success = true; + } + + public function isSuccessful(): bool + { + return $this->success; + } + + public function canRollback(): bool + { + return $this->canRollback; + } + + public function setCanRollback(bool $canRollback): void + { + $this->canRollback = $canRollback; + } + + public function getErrors(): array + { + return $this->errors; + } + + public function hasErrors(): bool + { + return count($this->errors) > 0; + } + + public function setData(array $data): void + { + $this->data = $data; + } + + public function getData(): array + { + return $this->data; + } + + public function addData(string $key, mixed $value): void + { + $this->data[$key] = $value; + } +} diff --git a/core/src/EventListener/Auth/LoginAuditListener.php b/core/src/EventListener/Auth/LoginAuditListener.php new file mode 100644 index 0000000..01de89c --- /dev/null +++ b/core/src/EventListener/Auth/LoginAuditListener.php @@ -0,0 +1,55 @@ +getUser(); + $data = $event->getData(); + + $this->logger->info('User login attempt', [ + 'userId' => $user->getId(), + 'email' => $user->getEmail(), + 'ipAddress' => $data['ipAddress'], + 'userAgent' => $data['userAgent'], + 'timestamp' => $data['timestamp']->format('Y-m-d H:i:s') + ]); + + $event->markAsSuccessful(); + } catch (\Exception $e) { + $event->markAsFailed('خطا در ثبت لاگ ورود: ' . $e->getMessage()); + } + } + + public function rollback(BaseEvent $event): void + { + if (!$event instanceof UserLoginEvent) { + return; + } + + // برای لاگ نیازی به rollback نیست + $this->logger->warning('Login audit rollback - no action needed'); + } + + public function getPriority(): int + { + return 100; // اولویت بالا + } +} diff --git a/core/src/EventListener/Auth/UserActivityListener.php b/core/src/EventListener/Auth/UserActivityListener.php new file mode 100644 index 0000000..938ad64 --- /dev/null +++ b/core/src/EventListener/Auth/UserActivityListener.php @@ -0,0 +1,71 @@ +getUser(); + + // ذخیره زمان ورود قبلی برای rollback + $this->previousLastLoginAt = $user->getLastLoginAt(); + + // به‌روزرسانی زمان آخرین ورود + $user->setLastLoginAt(new \DateTimeImmutable()); + $user->setLoginCount($user->getLoginCount() + 1); + + $this->entityManager->flush(); + + $event->markAsSuccessful(); + } catch (\Exception $e) { + $event->markAsFailed('خطا در به‌روزرسانی فعالیت کاربر: ' . $e->getMessage()); + } + } + + public function rollback(BaseEvent $event): void + { + if (!$event instanceof UserLoginEvent) { + return; + } + + try { + $user = $event->getUser(); + + // بازگرداندن مقادیر قبلی + if ($this->previousLastLoginAt) { + $user->setLastLoginAt($this->previousLastLoginAt); + } + $user->setLoginCount($user->getLoginCount() - 1); + + $this->entityManager->flush(); + } catch (\Exception $e) { + // در صورت خطا در rollback، لاگ می‌کنیم + // این یک وضعیت بحرانی است + } + } + + public function getPriority(): int + { + return 200; // اولویت متوسط + } +} diff --git a/core/src/EventListener/LocaleListener.php b/core/src/EventListener/LocaleListener.php new file mode 100644 index 0000000..9b86d14 --- /dev/null +++ b/core/src/EventListener/LocaleListener.php @@ -0,0 +1,40 @@ +getRequest(); + + // Skip for API routes + if (str_starts_with($request->getPathInfo(), '/api/')) { + return; + } + + // Get session from request + $session = $request->getSession(); + if (!$session) { + return; + } + + // Get locale from session or default to 'fa' + $locale = $session->get('_locale', 'fa'); + + // Set locale for current request + $this->localeSwitcher->setLocale($locale); + + // Set locale in request attributes + $request->setLocale($locale); + } +} diff --git a/core/src/EventListener/RollbackableEventListenerInterface.php b/core/src/EventListener/RollbackableEventListenerInterface.php new file mode 100644 index 0000000..68754c7 --- /dev/null +++ b/core/src/EventListener/RollbackableEventListenerInterface.php @@ -0,0 +1,23 @@ +add('plainPassword', RepeatedType::class, [ - 'type' => PasswordType::class, - 'mapped' => false, - 'first_options' => [ - 'label' => 'رمز عبور جدید', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'رمز عبور جدید را وارد کنید' - ] - ], - 'second_options' => [ - 'label' => 'تکرار رمز عبور جدید', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'رمز عبور جدید را دوباره وارد کنید' - ] - ], - 'invalid_message' => 'رمزهای عبور یکسان نیستند', - 'constraints' => [ - new NotBlank([ - 'message' => 'رمز عبور جدید الزامی است', - ]), - new Length([ - 'min' => 6, - 'minMessage' => 'رمز عبور باید حداقل {{ limit }} کاراکتر باشد', - 'max' => 4096, - ]), - ], - ]) - ; - } - - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([]); - } -} diff --git a/core/src/Form/Auth/RegistrationFormType.php b/core/src/Form/Auth/RegistrationFormType.php deleted file mode 100644 index 22bcc42..0000000 --- a/core/src/Form/Auth/RegistrationFormType.php +++ /dev/null @@ -1,106 +0,0 @@ -add('fullName', TextType::class, [ - 'label' => 'نام و نام خانوادگی', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'نام و نام خانوادگی خود را وارد کنید' - ], - 'constraints' => [ - new NotBlank([ - 'message' => 'نام و نام خانوادگی الزامی است', - ]), - new Length([ - 'min' => 2, - 'max' => 100, - 'minMessage' => 'نام باید حداقل {{ limit }} کاراکتر باشد', - 'maxMessage' => 'نام نمی‌تواند بیشتر از {{ limit }} کاراکتر باشد', - ]), - ], - ]) - ->add('email', EmailType::class, [ - 'label' => 'ایمیل', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'example@email.com' - ], - 'constraints' => [ - new NotBlank([ - 'message' => 'ایمیل الزامی است', - ]), - ], - ]) - ->add('mobile', TextType::class, [ - 'label' => 'شماره موبایل', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => '09123456789' - ], - 'constraints' => [ - new NotBlank([ - 'message' => 'شماره موبایل الزامی است', - ]), - new Regex([ - 'pattern' => '/^09[0-9]{9}$/', - 'message' => 'فرمت شماره موبایل صحیح نیست (مثال: 09123456789)', - ]), - ], - ]) - ->add('plainPassword', RepeatedType::class, [ - 'type' => PasswordType::class, - 'mapped' => false, - 'first_options' => [ - 'label' => 'رمز عبور', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'رمز عبور خود را وارد کنید' - ] - ], - 'second_options' => [ - 'label' => 'تکرار رمز عبور', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'رمز عبور را دوباره وارد کنید' - ] - ], - 'invalid_message' => 'رمزهای عبور یکسان نیستند', - 'constraints' => [ - new NotBlank([ - 'message' => 'رمز عبور الزامی است', - ]), - new Length([ - 'min' => 6, - 'minMessage' => 'رمز عبور باید حداقل {{ limit }} کاراکتر باشد', - 'max' => 4096, - ]), - ], - ]) - ; - } - - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'data_class' => User::class, - ]); - } -} diff --git a/core/src/Form/Auth/ResetPasswordRequestFormType.php b/core/src/Form/Auth/ResetPasswordRequestFormType.php deleted file mode 100644 index 97a3049..0000000 --- a/core/src/Form/Auth/ResetPasswordRequestFormType.php +++ /dev/null @@ -1,35 +0,0 @@ -add('email', EmailType::class, [ - 'label' => 'ایمیل', - 'attr' => [ - 'class' => 'form-control', - 'placeholder' => 'ایمیل خود را وارد کنید' - ], - 'constraints' => [ - new NotBlank([ - 'message' => 'لطفاً ایمیل خود را وارد کنید', - ]), - ], - ]) - ; - } - - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([]); - } -} diff --git a/core/src/Service/EventTransactionManager.php b/core/src/Service/EventTransactionManager.php new file mode 100644 index 0000000..35c6235 --- /dev/null +++ b/core/src/Service/EventTransactionManager.php @@ -0,0 +1,123 @@ +entityManager->beginTransaction(); + + try { + // اجرای عملیات اصلی + $result = $operation(); + + // انتشار رویدادها + $this->dispatchEvents($events); + + // بررسی موفقیت همه رویدادها + if ($this->areAllEventsSuccessful($events)) { + $this->entityManager->commit(); + $this->logger->info('Transaction committed successfully'); + return $result; + } else { + // rollback در صورت شکست رویدادها + $this->rollbackEvents($events); + $this->entityManager->rollback(); + $this->logger->warning('Transaction rolled back due to event failures'); + throw new \RuntimeException('عملیات به دلیل شکست در رویدادها لغو شد'); + } + + } catch (\Exception $e) { + $this->entityManager->rollback(); + $this->rollbackEvents($events); + $this->logger->error('Transaction rolled back due to exception: ' . $e->getMessage()); + throw $e; + } + } + + /** + * انتشار رویدادها + */ + private function dispatchEvents(array $events): void + { + foreach ($events as $event) { + $this->eventDispatcher->dispatch($event); + } + } + + /** + * بررسی موفقیت همه رویدادها + */ + private function areAllEventsSuccessful(array $events): bool + { + foreach ($events as $event) { + if (!$event->isSuccessful()) { + $this->logger->warning('Event failed: ' . get_class($event), [ + 'errors' => $event->getErrors() + ]); + return false; + } + } + return true; + } + + /** + * Rollback رویدادها + */ + private function rollbackEvents(array $events): void + { + foreach ($events as $event) { + if ($event->canRollback()) { + $this->rollbackEvent($event); + } + } + } + + /** + * Rollback یک رویداد خاص + */ + private function rollbackEvent(BaseEvent $event): void + { + $listeners = $this->getEventListeners($event); + + foreach ($listeners as $listener) { + if ($listener instanceof RollbackableEventListenerInterface) { + try { + $listener->rollback($event); + } catch (\Exception $e) { + $this->logger->error('Error during event rollback: ' . $e->getMessage(), [ + 'event' => get_class($event), + 'listener' => get_class($listener) + ]); + } + } + } + } + + /** + * دریافت Listener های یک رویداد + */ + private function getEventListeners(BaseEvent $event): array + { + // این متد باید بر اساس Event Dispatcher پیاده‌سازی شود + // فعلاً یک پیاده‌سازی ساده + return []; + } +} diff --git a/core/symfony.lock b/core/symfony.lock index 9c6149e..b23c310 100644 --- a/core/symfony.lock +++ b/core/symfony.lock @@ -35,6 +35,18 @@ "migrations/.gitignore" ] }, + "nelmio/cors-bundle": { + "version": "2.5", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.5", + "ref": "6bea22e6c564fba3a1391615cada1437d0bde39c" + }, + "files": [ + "config/packages/nelmio_cors.yaml" + ] + }, "phpunit/phpunit": { "version": "12.3", "recipe": { diff --git a/core/templates/auth/base.html.twig b/core/templates/auth/base.html.twig deleted file mode 100644 index b1515a5..0000000 --- a/core/templates/auth/base.html.twig +++ /dev/null @@ -1,514 +0,0 @@ - - - - - - {% block title %}سیستم احراز هویت - حسابی‌کس{% endblock %} - - - - - - - - - - - - {% block stylesheets %}{% endblock %} - - -
-
- -
-

- - {% block auth_title %}احراز هویت{% endblock %} -

-

{% block auth_subtitle %}به سیستم حسابی‌کس خوش آمدید{% endblock %}

-
- - -
- - {% for message in app.flashes('success') %} - - {% endfor %} - - {% for message in app.flashes('error') %} - - {% endfor %} - - {% for message in app.flashes('info') %} - - {% endfor %} - - {% for message in app.flashes('warning') %} - - {% endfor %} - - - {% block auth_body %}{% endblock %} -
- - - -
-
- - - - - - - - {% block javascripts %}{% endblock %} - - diff --git a/core/templates/auth/registration/register.html.twig b/core/templates/auth/registration/register.html.twig deleted file mode 100644 index bcd05a9..0000000 --- a/core/templates/auth/registration/register.html.twig +++ /dev/null @@ -1,109 +0,0 @@ -{% extends 'auth/base.html.twig' %} - -{% block title %}ثبت‌نام - سیستم حسابداری{% endblock %} - -{% block auth_title %}ثبت‌نام در سیستم{% endblock %} - -{% block auth_subtitle %}حساب کاربری جدید ایجاد کنید{% endblock %} - -{% block auth_body %} -
-
- - {{ form_widget(registrationForm.fullName, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'نام و نام خانوادگی خود را وارد کنید', - 'id': 'registration_form_fullName' - } - }) }} - {{ form_errors(registrationForm.fullName) }} -
- -
- - {{ form_widget(registrationForm.email, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'example@email.com', - 'id': 'registration_form_email' - } - }) }} - {{ form_errors(registrationForm.email) }} -
- -
- - {{ form_widget(registrationForm.mobile, { - 'attr': { - 'class': 'form-control', - 'placeholder': '09123456789', - 'id': 'registration_form_mobile' - } - }) }} - {{ form_errors(registrationForm.mobile) }} -
- -
- - {{ form_widget(registrationForm.plainPassword.first, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'رمز عبور خود را وارد کنید', - 'id': 'registration_form_plainPassword_first' - } - }) }} - {{ form_errors(registrationForm.plainPassword.first) }} -
- -
- - {{ form_widget(registrationForm.plainPassword.second, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'رمز عبور را دوباره وارد کنید', - 'id': 'registration_form_plainPassword_second' - } - }) }} - {{ form_errors(registrationForm.plainPassword.second) }} -
- -
- -
-
- -
- قبلاً ثبت‌نام کرده‌اید؟ -
- -
- - وارد شوید - -
-{% endblock %} - -{% block auth_footer %} - -{% endblock %} diff --git a/core/templates/auth/reset_password/check_email.html.twig b/core/templates/auth/reset_password/check_email.html.twig deleted file mode 100644 index 1db450e..0000000 --- a/core/templates/auth/reset_password/check_email.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{% extends 'auth/base.html.twig' %} - -{% block title %}بررسی ایمیل - سیستم حسابداری{% endblock %} - -{% block auth_title %}بررسی ایمیل{% endblock %} - -{% block auth_subtitle %}لینک بازنشانی رمز عبور ارسال شد{% endblock %} - -{% block auth_body %} -
-
- -
- -
-
- ایمیل ارسال شد! -
-

- اگر ایمیلی با آدرس وارد شده در سیستم ثبت شده باشد، - لینک بازنشانی رمز عبور برای شما ارسال شده است. -

-
- -
-
- مهم! -
-
    -
  • لینک ارسال شده تا 1 ساعت معتبر است
  • -
  • پوشه اسپم خود را بررسی کنید
  • -
  • اگر ایمیل دریافت نکردید، دوباره تلاش کنید
  • -
-
-
- -
- مراحل بعدی -
- -
- - بازگشت به صفحه ورود - - - تلاش مجدد - -
-{% endblock %} - -{% block auth_footer %} - -{% endblock %} diff --git a/core/templates/auth/reset_password/request.html.twig b/core/templates/auth/reset_password/request.html.twig deleted file mode 100644 index 1f9d178..0000000 --- a/core/templates/auth/reset_password/request.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{% extends 'auth/base.html.twig' %} - -{% block title %}فراموشی رمز عبور - سیستم حسابداری{% endblock %} - -{% block auth_title %}فراموشی رمز عبور{% endblock %} - -{% block auth_subtitle %}ایمیل خود را وارد کنید تا لینک بازنشانی ارسال شود{% endblock %} - -{% block auth_body %} -
- -

- نگران نباشید! ما لینک بازنشانی رمز عبور را برای شما ارسال خواهیم کرد. -

-
- -
-
- - {{ form_widget(requestForm.email, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'ایمیل خود را وارد کنید', - 'id': 'request_form_email' - } - }) }} - {{ form_errors(requestForm.email) }} -
- -
- -
-
- -
- یا -
- -
- - بازگشت به صفحه ورود - -
-{% endblock %} - -{% block auth_footer %} - -{% endblock %} diff --git a/core/templates/auth/reset_password/reset.html.twig b/core/templates/auth/reset_password/reset.html.twig deleted file mode 100644 index a80edc0..0000000 --- a/core/templates/auth/reset_password/reset.html.twig +++ /dev/null @@ -1,90 +0,0 @@ -{% extends 'auth/base.html.twig' %} - -{% block title %}تغییر رمز عبور - سیستم حسابداری{% endblock %} - -{% block auth_title %}تغییر رمز عبور{% endblock %} - -{% block auth_subtitle %}رمز عبور جدید خود را وارد کنید{% endblock %} - -{% block auth_body %} -
- -

- رمز عبور جدید خود را انتخاب کنید. این رمز عبور جایگزین رمز عبور قبلی خواهد شد. -

-
- -
-
- - {{ form_widget(resetForm.plainPassword.first, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'رمز عبور جدید را وارد کنید', - 'id': 'change_password_form_plainPassword_first' - } - }) }} - {{ form_errors(resetForm.plainPassword.first) }} -
- -
- - {{ form_widget(resetForm.plainPassword.second, { - 'attr': { - 'class': 'form-control', - 'placeholder': 'رمز عبور جدید را دوباره وارد کنید', - 'id': 'change_password_form_plainPassword_second' - } - }) }} - {{ form_errors(resetForm.plainPassword.second) }} -
- -
- -
-
- -
- نکات امنیتی -
- -
-
- رمز عبور قوی: -
- -
- -
- یا -
- -
- - بازگشت به صفحه ورود - -
-{% endblock %} - -{% block auth_footer %} - -{% endblock %} diff --git a/core/templates/auth/security/login.html.twig b/core/templates/auth/security/login.html.twig deleted file mode 100644 index 30a812e..0000000 --- a/core/templates/auth/security/login.html.twig +++ /dev/null @@ -1,103 +0,0 @@ -{% extends 'auth/base.html.twig' %} - -{% block title %}ورود - سیستم حسابداری{% endblock %} - -{% block auth_title %}ورود به سیستم{% endblock %} - -{% block auth_subtitle %}برای دسترسی به سیستم حسابداری وارد شوید{% endblock %} - -{% block auth_body %} - {% if error %} -
- - {{ error.messageKey|trans(error.messageData, 'security') }} -
- {% endif %} - -
- {% if csrf_token('authenticate') %} - - {% endif %} - -
- - -
- لطفاً یک ایمیل معتبر وارد کنید -
-
- -
- - -
- لطفاً رمز عبور خود را وارد کنید -
-
- -
-
- - -
-
- -
- -
-
- -
- یا -
- -
- - فراموشی رمز عبور - -
- -
- حساب کاربری ندارید؟ -
- -
- - ثبت‌نام کنید - -
-{% endblock %} - -{% block auth_footer %} - -{% endblock %} diff --git a/core/templates/base.html.twig b/core/templates/base.html.twig index 0abe3d6..05a85e5 100644 --- a/core/templates/base.html.twig +++ b/core/templates/base.html.twig @@ -1,17 +1,17 @@ - + - {% block title %}سیستم حسابداری{% endblock %} - + {% block title %}{{ 'common.brand_name'|trans }}{% endblock %} + {% block stylesheets %} - {{ encore_entry_link_tags('app') }} + {{ encore_entry_link_tags('main') }} {% endblock %} {% block javascripts %} - {{ encore_entry_script_tags('app') }} + {{ encore_entry_script_tags('main') }} {% endblock %} diff --git a/core/templates/auth/reset_password/email.html.twig b/core/templates/emails/reset_password.html.twig similarity index 66% rename from core/templates/auth/reset_password/email.html.twig rename to core/templates/emails/reset_password.html.twig index c74608b..6fbd650 100644 --- a/core/templates/auth/reset_password/email.html.twig +++ b/core/templates/emails/reset_password.html.twig @@ -1,35 +1,36 @@ - + بازنشانی رمز عبور diff --git a/frontend/src/components/ThemeSwitcher.vue b/frontend/src/components/ThemeSwitcher.vue new file mode 100644 index 0000000..bc9a409 --- /dev/null +++ b/frontend/src/components/ThemeSwitcher.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js new file mode 100644 index 0000000..9518ccd --- /dev/null +++ b/frontend/src/i18n/index.js @@ -0,0 +1,47 @@ +import { createI18n } from 'vue-i18n' +import fa from '../locales/fa' +import en from '../locales/en' + +const i18n = createI18n({ + legacy: false, + locale: 'fa', + fallbackLocale: 'fa', + messages: { + fa, + en + }, + allowComposition: true, + useScope: 'global' +}) + +export const changeLocale = (locale) => { + if (['fa', 'en'].includes(locale)) { + i18n.global.locale.value = locale + localStorage.setItem('locale', locale) + + const isRTL = locale === 'fa' + + // Set document direction and language + document.documentElement.dir = isRTL ? 'rtl' : 'ltr' + document.documentElement.lang = locale + document.body.style.direction = isRTL ? 'rtl' : 'ltr' + + // Apply font family + if (isRTL) { + document.body.style.fontFamily = "'Vazir', 'Tahoma', sans-serif" + } else { + document.body.style.fontFamily = "'Roboto', 'Arial', sans-serif" + } + + // Force Vuetify components to update + setTimeout(() => { + window.dispatchEvent(new Event('resize')) + }, 100) + } +} + +// Initialize +const savedLocale = localStorage.getItem('locale') || 'fa' +changeLocale(savedLocale) + +export default i18n diff --git a/frontend/src/locales/en.js b/frontend/src/locales/en.js new file mode 100644 index 0000000..5e8f43a --- /dev/null +++ b/frontend/src/locales/en.js @@ -0,0 +1,74 @@ +export default { + // Authentication + auth: { + welcome: 'Welcome', + subtitle: 'Sign in to your account to continue', + email: 'Email', + password: 'Password', + rememberMe: 'Remember me', + forgotPassword: 'Forgot password', + login: 'Login', + register: 'Register', + noAccount: 'Do not have an account', + registerHere: 'Sign up here', + or: 'or', + emailRequired: 'Email is required', + emailInvalid: 'Invalid email format', + passwordRequired: 'Password is required', + passwordMinLength: 'Password must be at least 6 characters', + placeholder: { + email: 'example at email dot com', + password: 'Enter your password' + } + }, + + // Common + common: { + brandName: 'Hesabix', + loading: 'Loading', + error: 'Error', + success: 'Success', + cancel: 'Cancel', + save: 'Save', + edit: 'Edit', + delete: 'Delete', + search: 'Search', + filter: 'Filter', + sort: 'Sort' + }, + + // Navigation + nav: { + dashboard: 'Dashboard', + accounts: 'Accounts', + transactions: 'Transactions', + reports: 'Reports', + settings: 'Settings', + profile: 'Profile', + logout: 'Logout' + }, + + // Dashboard + dashboard: { + title: 'Dashboard', + totalBalance: 'Total Balance', + monthlyIncome: 'Monthly Income', + monthlyExpense: 'Monthly Expense', + recentTransactions: 'Recent Transactions', + quickActions: 'Quick Actions' + }, + + // Language + language: { + fa: 'Farsi', + en: 'English', + changeLanguage: 'Change Language' + }, + + // Theme + theme: { + light: 'Light', + dark: 'Dark', + system: 'System' + } +} diff --git a/frontend/src/locales/fa.js b/frontend/src/locales/fa.js new file mode 100644 index 0000000..d1609fb --- /dev/null +++ b/frontend/src/locales/fa.js @@ -0,0 +1,74 @@ +export default { + // Authentication + auth: { + welcome: 'خوش آمدید', + subtitle: 'برای ادامه وارد حساب کاربری خود شوید', + email: 'ایمیل', + password: 'رمز عبور', + rememberMe: 'مرا به خاطر بسپار', + forgotPassword: 'فراموشی رمز عبور', + login: 'ورود', + register: 'ثبت نام', + noAccount: 'حساب کاربری ندارید؟', + registerHere: 'اینجا ثبت نام کنید', + or: 'یا', + emailRequired: 'ایمیل الزامی است', + emailInvalid: 'ایمیل نامعتبر است', + passwordRequired: 'رمز عبور الزامی است', + passwordMinLength: 'رمز عبور باید حداقل 6 کاراکتر باشد', + placeholder: { + email: 'example at email dot com', + password: 'رمز عبور خود را وارد کنید' + } + }, + + // Common + common: { + brandName: 'حسابی‌کس', + loading: 'در حال بارگذاری', + error: 'خطا', + success: 'موفقیت', + cancel: 'انصراف', + save: 'ذخیره', + edit: 'ویرایش', + delete: 'حذف', + search: 'جستجو', + filter: 'فیلتر', + sort: 'مرتب‌سازی' + }, + + // Navigation + nav: { + dashboard: 'داشبورد', + accounts: 'حساب‌ها', + transactions: 'تراکنش‌ها', + reports: 'گزارش‌ها', + settings: 'تنظیمات', + profile: 'پروفایل', + logout: 'خروج' + }, + + // Dashboard + dashboard: { + title: 'داشبورد', + totalBalance: 'موجودی کل', + monthlyIncome: 'درآمد ماهانه', + monthlyExpense: 'هزینه ماهانه', + recentTransactions: 'تراکنش‌های اخیر', + quickActions: 'عملیات سریع' + }, + + // Language + language: { + fa: 'فارسی', + en: 'انگلیسی', + changeLanguage: 'تغییر زبان' + }, + + // Theme + theme: { + light: 'روشن', + dark: 'تاریک', + system: 'سیستم' + } +} diff --git a/frontend/src/main.js b/frontend/src/main.js index d3d6309..9169512 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -1,48 +1,110 @@ import { createApp } from 'vue' import router from './router' +import i18n from './i18n' +import vuetify from './plugins/vuetify' +import './assets/styles/theme.css' +import './assets/styles/rtl-ltr.css' +import './assets/styles/vuetify-rtl.css' +import './assets/styles/components-rtl.css' -// Vuetify -import 'vuetify/styles' -import { createVuetify } from 'vuetify' -import * as components from 'vuetify/components' -import * as directives from 'vuetify/directives' -import '@mdi/font/css/materialdesignicons.css' - -const vuetify = createVuetify({ - components, - directives, - theme: { - defaultTheme: 'light' - } -}) - -const app = createApp({ - template: ` - - - - - - - - ` -}) - -// Get initial page and route from data attributes -const appElement = document.getElementById('app') -const initialPage = appElement ? appElement.dataset.page : 'dashboard' -const initialRoute = appElement ? appElement.dataset.route : '' - -// Set initial route based on page and route -if (initialPage && initialPage !== 'dashboard') { - // Use router.push for programmatic navigation - router.push(`/${initialPage}`) -} else if (initialRoute && initialRoute !== 'dashboard') { - // Handle nested routes - router.push(`/${initialRoute}`) +// Theme detection and management +function detectSystemTheme() { + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + return 'dark' + } + return 'light' } -app.use(router) -app.use(vuetify) +function initializeTheme() { + // Check for saved theme preference or default to light + const savedTheme = localStorage.getItem('vuetify-theme') + let currentTheme = savedTheme || 'light' + + if (currentTheme === 'system') { + currentTheme = detectSystemTheme() + } + + // Apply theme - Vuetify 3 syntax + vuetify.theme.global.name = currentTheme + + // Apply CSS classes for better theme support + if (currentTheme === 'dark') { + document.body.classList.add('v-theme--dark') + document.body.classList.remove('v-theme--light') + document.documentElement.setAttribute('data-theme', 'dark') + } else { + document.body.classList.add('v-theme--light') + document.body.classList.remove('v-theme--dark') + document.documentElement.setAttribute('data-theme', 'light') + } + + // Listen for system theme changes + if (window.matchMedia) { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + if (localStorage.getItem('vuetify-theme') === 'system') { + const newTheme = e.matches ? 'dark' : 'light' + vuetify.theme.global.name = newTheme + + // Update CSS classes + if (newTheme === 'dark') { + document.body.classList.add('v-theme--dark') + document.body.classList.remove('v-theme--light') + document.documentElement.setAttribute('data-theme', 'dark') + } else { + document.body.classList.add('v-theme--light') + document.body.classList.remove('v-theme--dark') + document.documentElement.setAttribute('data-theme', 'light') + } + } + }) + } + + return currentTheme +} -app.mount('#app') +// Common function to create and configure app +function createAndMountApp(mountElement, initialRoute, defaultRoute) { + const app = createApp({ + template: ` + + + + + + + + ` + }) + + // Set initial route if provided + if (initialRoute && initialRoute !== '') { + router.push(`${defaultRoute}/${initialRoute}`) + } else { + router.push(defaultRoute) + } + + app.use(i18n) + app.use(router) + app.use(vuetify) + + // Initialize theme after mounting + app.mount(mountElement) + initializeTheme() +} + +// Check which section we're in +const appElement = document.getElementById('app') +const authElement = document.getElementById('auth') + +if (appElement) { + // App section + const initialRoute = appElement.dataset.route || '' + createAndMountApp('#app', initialRoute, '/ui') +} else if (authElement) { + // Auth section + const initialRoute = authElement.dataset.route || '' + createAndMountApp('#auth', initialRoute, '/auth') +} else { + // Fallback - create main app + createAndMountApp('#app', '', '/ui') +} diff --git a/frontend/src/plugins/vuetify.js b/frontend/src/plugins/vuetify.js new file mode 100644 index 0000000..7a93878 --- /dev/null +++ b/frontend/src/plugins/vuetify.js @@ -0,0 +1,63 @@ +import 'vuetify/styles' +import { createVuetify } from 'vuetify' +import * as components from 'vuetify/components' +import * as directives from 'vuetify/directives' +import '@mdi/font/css/materialdesignicons.css' + +// Theme configuration for Vuetify 3 +const vuetify = createVuetify({ + components, + directives, + theme: { + defaultTheme: 'system', + themes: { + light: { + dark: false, + colors: { + primary: '#1976d2', + secondary: '#424242', + accent: '#82b1ff', + error: '#ff5252', + info: '#2196f3', + success: '#4caf50', + warning: '#ff9800', + surface: '#ffffff', + background: '#fafafa', + 'on-surface': '#000000', + 'on-background': '#000000', + } + }, + dark: { + dark: true, + colors: { + primary: '#90caf9', + secondary: '#bdbdbd', + accent: '#82b1ff', + error: '#ff5252', + info: '#2196f3', + success: '#4caf50', + warning: '#ff9800', + surface: '#121212', + background: '#000000', + 'on-surface': '#ffffff', + 'on-background': '#ffffff', + } + } + } + }, + defaults: { + VCard: { + rounded: 'lg', + elevation: 2 + }, + VTextField: { + variant: 'outlined', + density: 'comfortable' + }, + VBtn: { + rounded: 'lg' + } + } +}) + +export default vuetify diff --git a/frontend/src/router/app.js b/frontend/src/router/app.js new file mode 100644 index 0000000..3940dab --- /dev/null +++ b/frontend/src/router/app.js @@ -0,0 +1,75 @@ +import { createRouter, createMemoryHistory } from 'vue-router' + +// Placeholder component for app pages +const AppPlaceholderComponent = { + template: ` + + + + + {{ $route.name }} + +

این صفحه در حال توسعه است.

+

Route: {{ $route.path }}

+

Page: {{ $route.meta.page }}

+
+
+
+
+
+ ` +} + +const appRoutes = [ + { + path: '/', + name: 'Dashboard', + component: AppPlaceholderComponent, + meta: { page: 'dashboard' } + }, + { + path: '/dashboard', + name: 'DashboardAlt', + component: AppPlaceholderComponent, + meta: { page: 'dashboard' } + }, + { + path: '/accounts', + name: 'Accounts', + component: AppPlaceholderComponent, + meta: { page: 'accounts' } + }, + { + path: '/transactions', + name: 'Transactions', + component: AppPlaceholderComponent, + meta: { page: 'transactions' } + }, + { + path: '/reports', + name: 'Reports', + component: AppPlaceholderComponent, + meta: { page: 'reports' } + }, + { + path: '/settings', + name: 'Settings', + component: AppPlaceholderComponent, + meta: { page: 'settings' } + }, + { + path: '/users', + name: 'Users', + component: AppPlaceholderComponent, + meta: { page: 'users' } + }, + { + path: '/profile', + name: 'Profile', + component: AppPlaceholderComponent, + meta: { page: 'profile' } + } +] + +// Export routes array instead of router instance +export default appRoutes diff --git a/frontend/src/router/auth.js b/frontend/src/router/auth.js new file mode 100644 index 0000000..5f98cee --- /dev/null +++ b/frontend/src/router/auth.js @@ -0,0 +1,68 @@ +import { createRouter, createMemoryHistory } from 'vue-router' +import LoginPage from '../views/auth/login.vue' +import RegisterPage from '../views/auth/register.vue' +import ForgotPasswordPage from '../views/auth/forgot-password.vue' + +// Placeholder component for other auth pages +const AuthPlaceholderComponent = { + template: ` + + + + + + {{ $route.name }} + + +

صفحه احراز هویت در حال توسعه است.

+

Route: {{ $route.path }}

+

Page: {{ $route.meta.page }}

+
+
+
+
+
+ ` +} + +const authRoutes = [ + { + path: '/', + name: 'Login', + component: LoginPage, + meta: { page: 'login' } + }, + { + path: '/login', + name: 'LoginAlt', + component: LoginPage, + meta: { page: 'login' } + }, + { + path: '/register', + name: 'Register', + component: RegisterPage, + meta: { page: 'register' } + }, + { + path: '/forgot-password', + name: 'ForgotPassword', + component: ForgotPasswordPage, + meta: { page: 'forgot-password' } + }, + { + path: '/reset-password', + name: 'ResetPassword', + component: AuthPlaceholderComponent, + meta: { page: 'reset-password' } + }, + { + path: '/verify-email', + name: 'VerifyEmail', + component: AuthPlaceholderComponent, + meta: { page: 'verify-email' } + } +] + +// Export routes array instead of router instance +export default authRoutes diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index f027df1..44c3462 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -1,76 +1,34 @@ import { createRouter, createWebHistory } from 'vue-router' +import appRoutes from './app' +import authRoutes from './auth' -// Placeholder component for now -const PlaceholderComponent = { - template: ` - - - - - {{ $route.name }} - -

این صفحه در حال توسعه است.

-

Route: {{ $route.path }}

-

Page: {{ $route.meta.page }}

-
-
-
-
-
- ` -} - -const routes = [ - { - path: '/', - name: 'Dashboard', - component: PlaceholderComponent, - meta: { page: 'dashboard' } - }, - { - path: '/dashboard', - name: 'DashboardAlt', - component: PlaceholderComponent, - meta: { page: 'dashboard' } - }, - { - path: '/accounts', - name: 'Accounts', - component: PlaceholderComponent, - meta: { page: 'accounts' } - }, - { - path: '/transactions', - name: 'Transactions', - component: PlaceholderComponent, - meta: { page: 'transactions' } - }, - { - path: '/reports', - name: 'Reports', - component: PlaceholderComponent, - meta: { page: 'reports' } - }, - { - path: '/settings', - name: 'Settings', - component: PlaceholderComponent, - meta: { page: 'settings' } - } -] - -const router = createRouter({ - history: createWebHistory('/ui/'), - routes +// Main router that handles both app and auth sections +const mainRouter = createRouter({ + history: createWebHistory(), + routes: [ + // App routes with /ui prefix + ...appRoutes.map(route => ({ + ...route, + path: `/ui${route.path === '/' ? '' : route.path}` + })), + // Auth routes with /auth prefix + ...authRoutes.map(route => ({ + ...route, + path: `/auth${route.path === '/' ? '' : route.path}` + })), + // Default redirect + { + path: '/', + redirect: '/ui' + } + ] }) -// Navigation guard to handle page changes -router.beforeEach((to, from, next) => { - // Update current page in meta - if (to.meta.page) { - console.log('Navigating to:', to.meta.page) - } +// Navigation guard for main router +mainRouter.beforeEach((to, from, next) => { + console.log('Main router navigating to:', to.path) + console.log('Route matched:', to.matched) next() }) -export default router +export default mainRouter diff --git a/frontend/src/views/auth/forgot-password.vue b/frontend/src/views/auth/forgot-password.vue new file mode 100644 index 0000000..222a5c8 --- /dev/null +++ b/frontend/src/views/auth/forgot-password.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/frontend/src/views/auth/login.vue b/frontend/src/views/auth/login.vue new file mode 100644 index 0000000..213ed0f --- /dev/null +++ b/frontend/src/views/auth/login.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/frontend/src/views/auth/register.vue b/frontend/src/views/auth/register.vue new file mode 100644 index 0000000..95e0db0 --- /dev/null +++ b/frontend/src/views/auth/register.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/frontend/webpack.config.js b/frontend/webpack.config.js index 61b1593..b95ba1b 100644 --- a/frontend/webpack.config.js +++ b/frontend/webpack.config.js @@ -1,15 +1,24 @@ const Encore = require('@symfony/webpack-encore'); +const webpack = require('webpack'); Encore .setOutputPath('../public_html/build/') .setPublicPath('/build/') - .addEntry('app', './src/main.js') + .addEntry('main', './src/main.js') .enableVueLoader() .enableSassLoader() .enableVersioning() .disableSingleRuntimeChunk() .splitEntryChunks() .enableSourceMaps(!Encore.isProduction()) - .enableBuildNotifications(); + .enableBuildNotifications() + .addStyleEntry('rtl-ltr', './src/assets/styles/rtl-ltr.css') + .addStyleEntry('vuetify-rtl', './src/assets/styles/vuetify-rtl.css') + .addStyleEntry('components-rtl', './src/assets/styles/components-rtl.css') + .addPlugin(new webpack.DefinePlugin({ + __VUE_OPTIONS_API__: JSON.stringify(true), + __VUE_PROD_DEVTOOLS__: JSON.stringify(false), + __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(false) + })); module.exports = Encore.getWebpackConfig(); diff --git a/public_html/.htaccess b/public_html/.htaccess index 2f17e92..cc7d049 100644 --- a/public_html/.htaccess +++ b/public_html/.htaccess @@ -25,6 +25,14 @@ DirectoryIndex index.php RewriteCond %{REQUEST_URI} ^/ui RewriteRule ^ %{ENV:BASE}/index.php [L] + # Handle Auth routes - let Symfony handle /auth/* routes + RewriteCond %{REQUEST_URI} ^/auth + RewriteRule ^ %{ENV:BASE}/index.php [L] + + # Handle API routes - let Symfony handle /api/* routes + RewriteCond %{REQUEST_URI} ^/api + RewriteRule ^ %{ENV:BASE}/index.php [L] + # If the requested filename exists, simply serve it RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ %{ENV:BASE}/index.php [L] diff --git a/public_html/favicon.ico b/public_html/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ab60ead214af88e584568a8ba82689f44baa9bac GIT binary patch literal 15406 zcmeI3dx#ZP9LIl~JvGbM?%jJga(ih{vl5GfG|LLgv?wwV%8K=|-g|e~Oev)TDC;De*30C>MTUz=ef|FL)BB1nC2r`@Qu-i~kE%sZCl4Y>?2qSR{cFm~ zCB<5~x0sd1#hfg0hkUi1VghQ&$^c~EZK{)hO(9<^SDWO~^Oi}@i7(X31V4FX2NOD+ ze5Pk1D@8x~LQclJWx#r`P$QS~9O@3lW&Gre8M&>Sd`3q4?76JPKcYg0X_$y7a8jt<+UK!^b-K|q=WnhpzZSX?!FLDPh6TD^x@eaZaOVe?t zo-mT2<5QBqhQ4w<{o;&i85y3hlZ%3asb5CnbDzjzO&PfcTQ6_Q$xjr=N&&h(M^q6qa|F%g#^Z0a= zTvGAW=hH_0Sy_~n9utnXCzF2K#ve@sBx{mQBEIEV*2@9oE@_`8F|P%2rJXM}*+AoI zBO3`<1!0tv#u!-5T)R1tgRaL|JL$Tx99<^ad`2$A)_(_a=u9IIJQgRob0B5KAQBJE#M^!?@-4$~B)L$6(|8!QE-ggS^{W z`aB=mSBnuh$%arEn$5{4a?j_z#}uwfkiGj)#>VV~j01^Fl9 z=vEos^B^C4?T_s4uzhJ5H!yzjE0;~2_Kh(7uypi)X`{=Nrvu&3tNp_8!_v`jT!(se zYCG4y@)h&NL~yIZux--mgY|_v84?zzX5_5Kob-^tbE$6Z}AFq8I|Ig#Jcl8CXVh((h=UY(% z7>~H|(|W%eJJXMDXP#UO&)?vkmvBy`pZk^lMv-H%(e>#0+B?=H@eTG5 zw~8F?r@P#^#@^DO_AwtDZ)G1-mYq#yh5v>$#ysthV7~$PZa!`kkGS#Rw@zYwFW1&? zdG)We|9A-Of8z48l|#pGjWu$PTYtIljkPii++S@ul#>rVTk*49TrOv~Jnd#RxT&;v zZ&}f^jWfS1-TKRUXJ0i0%r>u{)V|e+SSvS_!`UsX?LIZGK7Ma(wP#wcbJ^gg5$m13 z-jTGOk1EW6FFL2iBJ2?=^pz7C=f8`WJG+_jPuFpQ;1x(L`N>*MoZaziceqc9 zG`*8=V`G2GrNt!A9Eq^{P2liIr1#4#uy z|K3U1e|->dCyjhR=KINUL3ou;)3rYB!g%K7aPNHL_hjC=qS740^fCX=>&DY(&eU}5 z-%eRyQr~45W+l@(Q@nt^t<}1jGVG%tB6#5u02w3o43Pk75o8Pqq_s^@rj~C( zojhgH`e(U4X1C zfP>ZC;HiVo`?j6s&&gihH!xn!skHA_>z*>)f(<{X9DB;D58eOJF2TB^bPuEKa~5yg zF@5WK7UN3``qvWn`q|nxPUQ*9)!%2*mr{IH$v=7%b@BxqV*87bUs>t498Noa4Ew|$6T3K?_n&RdUB3S{Ilv_LTNT)IwSL2R z#7zf#9rw#ljm+j5GM58QQnC!Bdj{UDt#BU$JM< Yy~m(5l`Z*DD!ETg+boCh|K}F?5930{wg3PC literal 0 HcmV?d00001 diff --git a/public_html/img/avatar.jpg b/public_html/img/avatar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..82ff3ca24a8102508431de2a386c72d201610b22 GIT binary patch literal 71783 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 literal 0 HcmV?d00001 diff --git a/public_html/img/avatar.png b/public_html/img/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..c3fe2ccaafd6128e47bf61297963b492900aa513 GIT binary patch literal 16277 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 T@mn`Z6VXu7QZD_^GW`DlMZW%v literal 0 HcmV?d00001 diff --git a/public_html/img/logo-blue.png b/public_html/img/logo-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..b628a034c4e3afa980d72b29ac0db73d4fcb7d96 GIT binary patch literal 10697 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