diff --git a/.editorconfig b/.editorconfig index 8f0de65..ba33c52 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,7 +3,7 @@ root = true [*] charset = utf-8 end_of_line = lf -indent_size = 4 +indent_size = 2 indent_style = space insert_final_newline = true trim_trailing_whitespace = true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..2b00208 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,30 @@ +name: Build Laravel and NPM Packages + +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev" ] + +jobs: + biblio-build: + + runs-on: ubuntu-latest + + steps: + - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e + with: + php-version: '8.1' + - uses: actions/checkout@v3 + - name: Copy .env + run: php -r "file_exists('.env') || copy('.env.example', '.env');" + working-directory: "./src/" + - name: Install Dependencies + run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + working-directory: "./src/" + - name: Install NPM Packages + run: npm install + working-directory: "./src/" + - name: Build NPM + run: npm run build + working-directory: "./src/" diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..a72a71c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0a77011 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.tabSize": 2 +} \ No newline at end of file diff --git a/docs/ERD_V-1_2.svg b/docs/ERD_V-1_2.svg new file mode 100644 index 0000000..dc8c015 --- /dev/null +++ b/docs/ERD_V-1_2.svg @@ -0,0 +1,12 @@ +11*111111111111*1*11111111111111111111111111useridintegerfirst_namevarcharlast_namevarcharemailvarcharresidencevarcharzip_codevarcharhouse_numbervarcharmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstamplibrary_passidintegeruser_idintegerbarcodestringactivebooleanmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstampitemidintegeridentifiervarchartypevarcharnamevarchardescriptiontextauthor_idintegercategoryintegerisbnvarcharratingintegerborrowing_timedatetimemodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstampitem_typeidintegertypevarcharmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstampitem_categoryidintegercategorystringmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimestampitem_age_ratingidintegerratingvarcharmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimestampitem_imageidintegeritem_idintegerfilenamevarcharpathvarcharmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimestampgrantsidintegeruser_idintegeritem_idintegerborrow_datetimestamphand_in_datetimestampmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstampreservationsidintegeruser_idintegeritem_idintegerexpire_datetimestampmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstampfineidintegergrant_idintegeramountdoublemodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstamppayment_transactionidintegerfine_idintegerpaiddoublemodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstampauthoridintegernamestringmodified_kindvarchar(1)modified_userintegercreated_attimestampupdated_attimstamp \ No newline at end of file diff --git a/docs/class_diagram_V-1_1.svg b/docs/class_diagram_V-1_1.svg new file mode 100644 index 0000000..f878621 --- /dev/null +++ b/docs/class_diagram_V-1_1.svg @@ -0,0 +1,4 @@ + + + +
User : Model
User : Model
+ id : integer
+ id : integer
+ first_name : varchar
+ first_name : varchar
+ last_name : varchar
+ last_name : varchar
+ emai : varchar
+ emai : varchar
+ residence : varchar
+ residence : varchar
+ zipcode : varchar
+ zipcode : varchar
+ house_number : varchar
+ house_number : varchar
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Grants : Model
Grants : Model
+ id : integer
+ id : integer
+ user_id : integer
+ user_id : integer
+ item_id : integer
+ item_id : integer
+ borrow_date : timestamp
+ borrow_date : timestamp
+ hand_in_date : timestamp
+ hand_in_date : timestamp
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Library_Pass : Model
Library_Pass : Model
+ id : integer
+ id : integer
+ user_id : integer
+ user_id : integer
+ barcode : varchar
+ barcode : varchar
+ active : boolean
+ active : boolean
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Item : Model
Item : Model
+ id : integer
+ id : integer
+ identifier : varchar
+ identifier : varchar
+ type : integer
+ type : integer
+ name : varchar
+ name : varchar
+ description : longtext
+ description : longtext
+ category : integer
+ category : integer
+ isbn : varchar
+ isbn : varchar
+ rating : integer
+ rating : integer
+ borrowing_time : datetime
+ borrowing_time : dateti...
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Item_Type : Model
Item_Type : Model
+ id : integer
+ id : integer
+ type : varchar
+ type : varchar
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Item_Category : Model
Item_Category : Model
+ id : integer
+ id : integer
+ category : varchar
+ category : varchar
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Item_Image : Model
Item_Image : Model
+ id : integer
+ id : integer
+ item_id : integer
+ item_id : integer
+ file_name : varchar
+ file_name : varchar
+ path : varchar
+ path : varchar
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Reservations : Model
Reservations : Model
+ id : integer
+ id : integer
+ user_id : integer
+ user_id : integer
+ item_id : integer
+ item_id : integer
+ expire_date: timestamp
+ expire_date: timestamp
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Item_Age_Rating : Model
Item_Age_Rating : Model
+ id : integer
+ id : integer
+ rating : varchar
+ rating : varchar
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Payment_Transaction : Model
Payment_Transaction : Model
+ id : integer
+ id : integer
+ fine_id : integer
+ fine_id : integer
+ paid : double
+ paid : double
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
Fine : Model
Fine : Model
+ id : integer
+ id : integer
+ grant_id : integer
+ grant_id : integer
+ amount : double
+ amount : double
+ modified_kind : varchar
+ modified_kind : varchar
+ modified_user : integer
+ modified_user : integer
+ created_at : timestamp
+ created_at : timestamp
+ updated_at : timstamp
+ updated_at : timstamp
ItemTypeController
ItemTypeController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
ItemCategoryController
ItemCategoryController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
ItemImageController
ItemImageController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
ItemController
ItemController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
ReservationController
ReservationController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
FineController
FineController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
LibraryPassController
LibraryPassController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaRespon...
PaymentTransactionController
PaymentTransactionController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaResponse
GrantsController
GrantsController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaResponse
UserController
UserController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaResponse
ItemAgeRatingController
ItemAgeRatingController
+ index() : InertiaResponse
+ index() : InertiaResponse
+ create() : InertiaResponse
+ create() : InertiaResponse
+ store() : InertiaResponse
+ store() : InertiaResponse
+ show() : InertiaResponse
+ show() : InertiaResponse
+ update() : InertiaResponse
+ update() : InertiaResponse
+ destroy() : InertiaResponse
+ destroy() : InertiaResponse
Index : View
Index : View
+ Redirect()
+ Redirect()
Manage : View
Manage : View
+ -
+ -
Terminal : View
Terminal : View
+ Items : ItemStore
+ Items : ItemStore
Payment : View
Payment : View
+ Payments: PaymentStore
+ Payments: PaymentStore
PowerButton : Component
PowerButton : Component
+ Logout
+ Logout
ManageLayout : Layout
ManageLayout : Layout
+ toDo
+ toDo
Layout : Layout
Layout : Layout
+ blockInput()
+ blockInput()
ItemInput : Component
ItemInput : Component
+ SearchInput : String
+ SearchInput : String
+ SearchOrScan()
+ SearchOrScan()
Notification : Component
Notification : Component
+ Show(type, message)
+ Show(type, message)
ItemPanel : Component
ItemPanel : Component
PanelTab : Component
PanelTab : Component
+ SwitchTab(tab)
+ SwitchTab(tab)
Item : Component
Item : Component
+ Show(itemId)
+ Show(itemId)
SearchResult : Component
SearchResult : Component
+ Show(itemId)
+ Show(itemId)
ItemModal : Component
ItemModal : Component
+ Show()
+ Show()
+ Close()
+ Close()
Text is not SVG - cannot display
\ No newline at end of file diff --git a/docs/designs/design0-0.svg b/docs/designs/design0-0.svg new file mode 100644 index 0000000..5fdf261 --- /dev/null +++ b/docs/designs/design0-0.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/designs/design1-0.svg b/docs/designs/design1-0.svg new file mode 100644 index 0000000..de40d78 --- /dev/null +++ b/docs/designs/design1-0.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/designs/design1-1.svg b/docs/designs/design1-1.svg new file mode 100644 index 0000000..dc769b2 --- /dev/null +++ b/docs/designs/design1-1.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/docs/designs/design1-2.svg b/docs/designs/design1-2.svg new file mode 100644 index 0000000..76e3f98 --- /dev/null +++ b/docs/designs/design1-2.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/designs/design1-3.svg b/docs/designs/design1-3.svg new file mode 100644 index 0000000..47ab177 --- /dev/null +++ b/docs/designs/design1-3.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design2-0.svg b/docs/designs/design2-0.svg new file mode 100644 index 0000000..349a72f --- /dev/null +++ b/docs/designs/design2-0.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design2-1.svg b/docs/designs/design2-1.svg new file mode 100644 index 0000000..c0edd13 --- /dev/null +++ b/docs/designs/design2-1.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design2-2.svg b/docs/designs/design2-2.svg new file mode 100644 index 0000000..062c20c --- /dev/null +++ b/docs/designs/design2-2.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design2-3.svg b/docs/designs/design2-3.svg new file mode 100644 index 0000000..bd52930 --- /dev/null +++ b/docs/designs/design2-3.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design3-0.svg b/docs/designs/design3-0.svg new file mode 100644 index 0000000..a82e003 --- /dev/null +++ b/docs/designs/design3-0.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design3-1.svg b/docs/designs/design3-1.svg new file mode 100644 index 0000000..59fdf36 --- /dev/null +++ b/docs/designs/design3-1.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design3-2.svg b/docs/designs/design3-2.svg new file mode 100644 index 0000000..f1c878d --- /dev/null +++ b/docs/designs/design3-2.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/designs/design4-0.svg b/docs/designs/design4-0.svg new file mode 100644 index 0000000..90299f6 --- /dev/null +++ b/docs/designs/design4-0.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/toast_notification.md b/docs/toast_notification.md new file mode 100644 index 0000000..94915b8 --- /dev/null +++ b/docs/toast_notification.md @@ -0,0 +1,25 @@ +# Create a toast notification + +we're using [vue-toastification](https://github.com/Maronato/vue-toastification) to create toast notifications. + +``component.vue`` +```html + + + + +``` diff --git a/docs/usecase_diagram_V-1_0.svg b/docs/usecase_diagram_V-1_0.svg new file mode 100644 index 0000000..ed5b1dc --- /dev/null +++ b/docs/usecase_diagram_V-1_0.svg @@ -0,0 +1,4 @@ + + + +
Unauthorized user
Unauth...
Request librarypass
Request librarypass
colleague
colle...
Manage user account
Manage user account
See history of granted items.
See history of grant...
Authorized user
Autho...
Grant item
Grant item
See fines
See fines
See all open granted items
See all open granted...
return items
return items
Extend granted items
Extend granted items
Get receipt
Get receipt
Pay fines
Pay fines
See all requested items
See all requested it...
remove requested item(s)
remove requested ite...
Play secret game
Play secret game
Manage librarypass
Manage librarypass
Manage requested items
Manage requested ite...
Manage items
Manage items
Manage grants
Manage grants
SuperAdmin
Super...
Manage colleages
Manage colleages
extends
extends
Manage payment transactions
Manage payment trans...
Manage fines
Manage fines
Extends
Extends
Text is not SVG - cannot display
\ No newline at end of file diff --git a/src/.env.example b/src/.env.example index bf78dae..8f3e2af 100644 --- a/src/.env.example +++ b/src/.env.example @@ -1,4 +1,4 @@ -APP_NAME=Laravel +APP_NAME=Biblio APP_ENV=local APP_KEY= APP_DEBUG=true @@ -18,7 +18,7 @@ DB_PASSWORD= BROADCAST_DRIVER=log CACHE_DRIVER=file FILESYSTEM_DISK=local -QUEUE_CONNECTION=sync +QUEUE_CONNECTION=database SESSION_DRIVER=file SESSION_LIFETIME=120 @@ -57,3 +57,5 @@ VITE_PUSHER_HOST="${PUSHER_HOST}" VITE_PUSHER_PORT="${PUSHER_PORT}" VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +BARCODE_COMPANY_PREFIX=069420 diff --git a/src/app/Enums/Imports/ImportSources.php b/src/app/Enums/Imports/ImportSources.php new file mode 100644 index 0000000..f8a38e5 --- /dev/null +++ b/src/app/Enums/Imports/ImportSources.php @@ -0,0 +1,8 @@ + 'Book', + static::movie => 'Movie', + static::game => 'Game', + static::music => 'Music', + static::ebook => 'Ebook', + static::audiobook => 'Audiobook', + static::magazine => 'Magazine', + }; + } + + public function internal(): string + { + $match = match ($this) { + static::book => 'book', + static::movie => 'movie', + static::game => 'game', + static::music => 'music', + static::ebook => 'ebook', + static::audiobook => 'audiobook', + static::magazine => 'magazine', + }; + + return strtoupper($match); + } +} diff --git a/src/app/Enums/ModifiedEnum.php b/src/app/Enums/ModifiedEnum.php new file mode 100644 index 0000000..a886364 --- /dev/null +++ b/src/app/Enums/ModifiedEnum.php @@ -0,0 +1,10 @@ + 'Borrow', + static::RESERVE => 'Reserve', + static::RETURN => 'Return', + static::LOGIN_MANAGE => 'Login Manage', + + static::VIEW_LIBRARY_PASS => 'View Library Pass', + static::CREATE_LIBRARY_PASS => 'Create Library Pass', + static::EDIT_LIBRARY_PASS => 'Edit Library Pass', + static::DELETE_LIBRARY_PASS => 'Delete Library Pass', + + static::VIEW_ITEM => 'View Item', + static::CREATE_ITEM => 'Create Item', + static::EDIT_ITEM => 'Edit Item', + static::DELETE_ITEM => 'Delete Item', + + static::VIEW_USER => 'View User', + static::CREATE_USER => 'Create User', + static::DELETE_USER => 'Delete User', + + static::VIEW_GRANT => 'View Grant', + static::CREATE_GRANT => 'Create Grant', + static::EDIT_GRANT => 'Edit Grant', + static::DELETE_GRANT => 'Delete Grant', + + static::VIEW_RESERVATION => 'View Reservation', + static::CREATE_RESERVATION => 'Create Reservation', + static::EDIT_RESERVATION => 'Edit Reservation', + static::DELETE_RESERVATION => 'Delete Reservation', + + static::VIEW_PAYMENT => 'View Payment', + static::CREATE_PAYMENT => 'Create Payment', + static::EDIT_PAYMENT => 'Edit Payment', + + static::VIEW_FINE => 'View Fine', + static::EDIT_FINE => 'Manage Fine', + }; + } +} diff --git a/src/app/Enums/ResponseStatus.php b/src/app/Enums/ResponseStatus.php new file mode 100644 index 0000000..ee8cdd4 --- /dev/null +++ b/src/app/Enums/ResponseStatus.php @@ -0,0 +1,43 @@ + 200, + static::created => 201, + static::error => 400, + static::unauthorized => 401, + static::forbidden => 403, + static::notFound => 404, + static::validationError => 422, + static::internalServerError => 500, + }; + } + + public function label(): string + { + return match ($this) { + static::success => 'Success', + static::error => 'Error', + static::created => 'Created', + static::unauthorized => 'Unauthorized', + static::forbidden => 'Forbidden', + static::notFound => 'Not Found', + static::validationError => 'Validation Error', + static::internalServerError => 'Internal Server Error', + }; + } +} diff --git a/src/app/Enums/Roles.php b/src/app/Enums/Roles.php new file mode 100644 index 0000000..6b04e86 --- /dev/null +++ b/src/app/Enums/Roles.php @@ -0,0 +1,19 @@ + 'Super Admin', + static::COLLEAGUE => 'Colleague', + static::CUSTOMER => 'Customer', + }; + } +} diff --git a/src/app/Http/Controllers/AdminController.php b/src/app/Http/Controllers/AdminController.php new file mode 100644 index 0000000..18f1380 --- /dev/null +++ b/src/app/Http/Controllers/AdminController.php @@ -0,0 +1,68 @@ +user(); + + if (!$userData) { + return redirect('/'); + } + + // Get the Statistics + $items = Item::count(); + $customers = User::count(); + $reservations = Reservation::count(); + $invoices = Fine::count(); + + return Inertia::render('admin/index', [ + 'userData' => $userData, + 'count' => [ + 'items' => $items, + 'customers' => $customers, + 'reservations' => $reservations, + 'invoices' => $invoices, + ], + 'chart1' => [ + 'labels' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'], + 'series' => [1, 2, 3, 4, 5, 6, 7, 8] + ], + 'chart2' => [ + 'labels' => ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug'], + 'series' => [0, 1, 2, 3, 4, 5, 6, 7] + ], + ]); + } + + public function items() { + + $items = Item::where('modified_kind', '!=', ModifiedEnum::deleted)->paginate(10)->through(function ($item) { + return [ + 'id' => $item->id, + 'name' => $item->name, + 'description' => $item->description, + 'author' => $item->author->name, + 'category' => $item->category->category, + 'age_rating' => $item->ageRating->rating, + 'ISBN' => $item->ISBN, + 'modified_kind' => $item->modified_kind, + 'modified_user' => $item->modified_user, + 'modified_at' => $item->modified_at, + ]; + }); + + return Inertia::render('admin/items/index', [ + 'items' => $items, + ]); + } +} diff --git a/src/app/Http/Controllers/AppController.php b/src/app/Http/Controllers/AppController.php new file mode 100644 index 0000000..4424bfc --- /dev/null +++ b/src/app/Http/Controllers/AppController.php @@ -0,0 +1,13 @@ +validated(); + $fine = Fine::create([ + 'grant_id' => $validated['grant_id'], + 'amount' => $validated['amount'], + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => Auth()->id(), + ]); + + return $this->CommonResponse( + ResponseStatus::created, + 'Fine created successfully', + ['fine' => $fine], + ); + } + + /** + * Display the specified resource. + */ + public function show(Fine $fine) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(Fine $fine) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, Fine $fine) + { + $validated = $request->validated(); + + //TODO: Check: do we want to update the grant_id? + $fine->update([ + 'amount' => $validated['amount'], + 'modified_kind' => ModifiedEnum::modified, + 'modified_user' => Auth()->id(), + ]); + + return $this->CommonResponse( + ResponseStatus::success, + 'Fine updated successfully', + ['fine' => $fine], + ); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Fine $fine) + { + $fine->delete(); + + return $this->CommonResponse( + ResponseStatus::success, + 'Fine deleted successfully', + null, + ); + } +} diff --git a/src/app/Http/Controllers/GrantController.php b/src/app/Http/Controllers/GrantController.php new file mode 100644 index 0000000..e6bb3eb --- /dev/null +++ b/src/app/Http/Controllers/GrantController.php @@ -0,0 +1,157 @@ +validated(); + $grant = Grant::create([ + 'user_id' => $validated['user_id'], + 'item_id' => $validated['item_id'], + 'borrowed_date' => $validated['borrowed_date'], + 'return_date' => $validated['return_date'], + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => Auth()->id(), + ]); + return $this->CommonResponse( + ResponseStatus::created, + 'Grant created successfully', + $grant); + } + + /** + * Display the specified resource. + */ + public function show(Grant $grant) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(Grant $grant) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(GrantRequest $request, Grant $grant) + { + $validated = $request->validated(); + + $grant->update([ + 'user_id' => $validated['user_id'], + 'item_id' => $validated['item_id'], + 'borrowed_date' => $validated['borrowed_date'], + 'return_date' => $validated['return_date'], + 'modified_kind' => ModifiedEnum::modified, + 'modified_user' => Auth()->id(), + ]); + + return $this->CommonResponse( + ResponseStatus::success, + 'Grant updated successfully', + ['grant' => $grant]); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Grant $grant) + { + $grant->delete(); + return $this->CommonResponse( + ResponseStatus::success, + 'Grant deleted successfully', + null); + } + + public function GrantItem(GrantItemRequest $request) { + $validated = $request->validated(); + + $item = Item::where('identifier', $validated['identifier'])->first(); + $library_pass = LibraryPass::where('barcode', $request->bearerToken())->first(); + $user = User::where('id', $library_pass->user_id)->first(); + + if (!isset($user)) { + return $this->CommonResponse( + ResponseStatus::notFound, 'User not found', null + ); + } + + if (!$user->can(Permissions::CREATE_GRANT->value) && Env::get('APP_ENV') != 'local') { + return $this->CommonResponse( + ResponseStatus::unauthorized, 'Unauthorized', null + ); + } + + $grant = Grant::where('user_id', $user->id) + ->where('item_id', $item->id) + ->where('modified_kind', '!=', ModifiedEnum::deleted) + ->where('return_date', null) + ->first(); + + if (isset($grant)) { + + $grant->return_date = now(); + $grant->modified_kind = ModifiedEnum::modified; + $grant->modified_user = $user->id; + $grant->save(); + + $message = 'Item returned successfully'; + } else { + $grant = Grant::create([ + 'user_id' => $user->id, + 'item_id' => $item->id, + 'borrowed_date' => now(), + 'return_date' => null, + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => $user->id, + ]); + + $message = 'Item granted successfully'; + } + + return $this->CommonResponse( + ResponseStatus::success, $message, $grant + ); + } +} diff --git a/src/app/Http/Controllers/IndexController.php b/src/app/Http/Controllers/IndexController.php index ae5532f..812d47b 100644 --- a/src/app/Http/Controllers/IndexController.php +++ b/src/app/Http/Controllers/IndexController.php @@ -2,12 +2,11 @@ namespace App\Http\Controllers; -use Illuminate\Http\Request; use Inertia\Inertia; class IndexController extends Controller { public function index() { - return Inertia::render('index'); + return Inertia::render('index'); } } diff --git a/src/app/Http/Controllers/ItemAgeRatingController.php b/src/app/Http/Controllers/ItemAgeRatingController.php new file mode 100644 index 0000000..2849926 --- /dev/null +++ b/src/app/Http/Controllers/ItemAgeRatingController.php @@ -0,0 +1,65 @@ +validated(); + + $item = Item::create([ + 'Identifier' => '', //TODO: Use trait to generate valid identifier + 'type' => $validated['type'], + 'name' => $validated['name'], + 'description' => $validated['description'], + 'category_id' => $validated['category_id'], + 'ISBN' => $validated['ISBN'], + 'rating' => $validated['rating'], + 'borrowing_time' => $validated['borrowing_time'], + 'modified_kind' => 'I', + 'modified_user' => auth()->user()->id, + ]); + } + + /** + * Display the specified resource. + */ + public function show(Item $item) + { + // render page + } + + /** + * Update the specified resource in storage. + */ + public function update(ItemRequest $request, Item $item) + { + $validated = $request->validated(); + + // update the items with the new data + $item->update([ + 'type' => $validated['type'], + 'name' => $validated['name'], + 'description' => $validated['description'], + 'category_id' => $validated['category_id'], + 'ISBN' => $validated['ISBN'], + 'rating' => $validated['rating'], + 'borrowing_time' => $validated['borrowing_time'], + 'modified_kind' => ModifiedEnum::modified, + 'modified_user' => auth()->id(), + ]); + + return $this->CommonResponse( + ResponseStatus::success, + 'Item updated', + $item + ); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Item $item) + { + $item->delete(); + return $this->CommonResponse( + ResponseStatus::success, + 'Item deleted', + null, + ); + } + + public function search(SearchItemRequest $request) { + $validated = $request->validated(); + $search = $validated['search']; + + $library_pass = LibraryPass::where('barcode', $request->bearerToken())->first(); + $user = User::where('id', $library_pass->user_id)->first(); + + if (!$user->can(Permissions::VIEW_ITEM->value) && Env::get('APP_ENV') != 'local') { + return $this->CommonResponse( + ResponseStatus::unauthorized, + 'Permission denied', + null + ); + } + + $items = Item::where('name', 'like', "%{$search}%") + ->orWhere('description', 'like', "%{$search}%") + ->orWhere('ISBN', 'like', "%{$search}%") + ->get(); + + $authors = Author::where('name', 'like', "%{$search}%")->get(); + + if (count($authors) >= 1) { + foreach ($authors as $author) { + + $author_items = $author->items; + foreach ($author_items as $author_item) { + + $item_exists = false; + foreach ($items as $item) { + if ($item->id == $author_item->id) { + $item_exists = true; + } + } + + if (!$item_exists) { + $items[] = $author_item; + } + + } + } + } + + foreach ($items as $item) { + $item->grants = Grant::where('item_id', $item->id) + ->where('modified_kind', '!=', ModifiedEnum::deleted) + ->where('return_date', null) + ->get(); + } + + return $this->CommonResponse( + ResponseStatus::success, + 'Search results', + $this->ReturnMultipleFullItems($items) + ); + } + + public function ApiStore(ApiStoreItemRequest $request) { + $validated = $request->validated(); + $library_pass = LibraryPass::where('barcode', $request->bearerToken())->first(); + $user = User::where('id', $library_pass->user_id)->first(); + + $title = $validated['title']; + $description = $validated['description']; + $ISBN = $validated['ISBN']; + $images = $validated['images']; + + $item = Item::create([ + 'name' => $title, + 'description' => $description, + 'ISBN' => $ISBN, + 'author_id' => 1, + 'identifier' => $this->generateItemIdentifier(), + 'type' => ItemTypes::book, + 'modified_user' => $user->id, + 'modified_kind' => ModifiedEnum::inserted, + ]); + + foreach ($images as $image) { + // store image in storage + $what = $image->storeAs('public/images/', $image->getClientOriginalName()); + + ItemImage::create([ + 'item_id' => $item->id, + 'filename' => $image->getClientOriginalName(), + 'path' => $what, + 'modified_user' => $user->id, + 'modified_kind' => ModifiedEnum::inserted, + ]); + } + + return $this->CommonResponse( + ResponseStatus::success, + 'Item created', + $this->ReturnFullItem($item) + ); + } +} diff --git a/src/app/Http/Controllers/ItemImageController.php b/src/app/Http/Controllers/ItemImageController.php new file mode 100644 index 0000000..418fd71 --- /dev/null +++ b/src/app/Http/Controllers/ItemImageController.php @@ -0,0 +1,65 @@ +validated(); + + $libraryPass = LibraryPass::create([ + 'user_id' => $validated['user_id'], + 'barcode' => $validated['barcode'], + 'is_active' => $validated['is_active'], + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => auth()->id(), + ]); + + return $this->CommonResponse(ResponseStatus::created, + 'Library pass created successfully', + $libraryPass, + ); + } + + /** + * Display the specified resource. + */ + public function show(LibraryPass $libraryPass) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(LibraryPass $libraryPass) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(LibraryPassRequest $request, LibraryPass $libraryPass) + { + $validated = $request->validated(); + + $libraryPass->update([ + 'user_id' => $validated['user_id'], + 'barcode' => $validated['barcode'], + 'is_active' => $validated['is_active'], + 'modified_kind' => ModifiedEnum::modified, + 'modified_user' => auth()->user()->id, + ]); + + return $this->CommonResponse(ResponseStatus::success, + 'Library pass updated successfully', + null, + ); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(LibraryPass $libraryPass) + { + $libraryPass->delete(); + return $this->CommonResponse(ResponseStatus::success, + 'Library pass deleted successfully', + null, + ); + } +} diff --git a/src/app/Http/Controllers/PaymentTransactionController.php b/src/app/Http/Controllers/PaymentTransactionController.php new file mode 100644 index 0000000..6c90dc1 --- /dev/null +++ b/src/app/Http/Controllers/PaymentTransactionController.php @@ -0,0 +1,98 @@ +validated(); + $paymentTransaction = PaymentTransaction::create([ + 'fine_id' => $validated['fine_id'], + 'amount' => $validated['amount'], + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => Auth()->id(), + ]); + + return $this->CommonResponse( + ResponseStatus::created, + 'Payment transaction created successfully', + ['paymentTransaction' => $paymentTransaction], + ); + } + + /** + * Display the specified resource. + */ + public function show(PaymentTransaction $paymentTransaction) + { + + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(PaymentTransaction $paymentTransaction) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(PaymentTransactionRequest $request, PaymentTransaction $paymentTransaction) + { + $validated = $request->validated(); + $paymentTransaction->update([ + 'amount' => $validated['amount'], + 'modified_kind' => ModifiedEnum::modified, + 'modified_user' => Auth()->id(), + ]); + + return $this->CommonResponse( + ResponseStatus::success, + 'Payment transaction updated successfully', + ['paymentTransaction' => $paymentTransaction], + ); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(PaymentTransaction $paymentTransaction) + { + $paymentTransaction->delete(); + return $this->CommonResponse( + ResponseStatus::success, + 'Payment transaction deleted successfully', + null, + ); + } +} diff --git a/src/app/Http/Controllers/ReservationController.php b/src/app/Http/Controllers/ReservationController.php new file mode 100644 index 0000000..17e8c23 --- /dev/null +++ b/src/app/Http/Controllers/ReservationController.php @@ -0,0 +1,121 @@ +validated(); + + $reservation = Reservation::create([ + 'user_id' => $validated['user_id'], + 'item_id' => $validated['item_id'], + 'status' => $validated['status'], + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => auth()->id(), + ]); + + return $this->CommonResponse(ResponseStatus::created, + 'Reservation created successfully', + $reservation, + ); + } + + /** + * Display the specified resource. + */ + public function show(Reservation $reservation) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(Reservation $reservation) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(ReserveRequest $request, Reservation $reservation) + { + $validated = $request->validated(); + + $reservation->update([ + 'user_id' => $validated['user_id'], + 'item_id' => $validated['item_id'], + 'status' => $validated['status'], + 'modified_kind' => ModifiedEnum::modified, + 'modified_user' => auth()->id(), + ]); + + return $this->CommonResponse(ResponseStatus::success, + 'Reservation updated successfully', + ["reservation" => $reservation], + ); + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(Reservation $reservation) + { + $reservation->delete(); + + return $this->CommonResponse(ResponseStatus::success, + 'Reservation deleted successfully', + null, + ); + } + + public function search(SearchReservationRequest $request) + { + $validated = $request->validated(); + $search = $validated['search']; + + $item = Item::where('name', 'like', "%{$search}%")->orWhere('ISBN', 'like', "%{$search}%")->first(); + $user = User::where('last_name', 'like', "%{$search}%")->orWhere('email', 'like', "%{$search}%")->orWhere('zip_code', 'like', "%{$search}%")->first(); + + $reservations = Reservation::where('item_id', $item->id)->orWhere('user_id', $user->id)->get(); + + return $this->CommonResponse(ResponseStatus::success, + 'Reservation found', + ["reservations" => $reservations], + ); + } +} diff --git a/src/app/Http/Controllers/SessionController.php b/src/app/Http/Controllers/SessionController.php new file mode 100644 index 0000000..ab9532d --- /dev/null +++ b/src/app/Http/Controllers/SessionController.php @@ -0,0 +1,54 @@ +validated()['code']; + + if (!isset($code)) { + return $this->CommonResponse( + ResponseStatus::validationError, + 'Code is required', + null, + ); + } + + $pass = LibraryPass::where('barcode', $code)->first(); + + if (!isset($pass)) { + return $this->CommonResponse( + ResponseStatus::unauthorized, + 'Incorrect code', + null, + ); + } + + $user = User::find($pass->user_id); + + if (!isset($user)) { + return $this->CommonResponse( + ResponseStatus::unauthorized, + 'Incorrect code', + null, + ); + } + + Auth()->login($user); + + return $this->CommonResponse( + ResponseStatus::success, + 'User logged in current session', + ['user' => $user], + ); + } +} diff --git a/src/app/Http/Controllers/UserController.php b/src/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..c11b1c0 --- /dev/null +++ b/src/app/Http/Controllers/UserController.php @@ -0,0 +1,86 @@ +validated(); + $search = $validated['search']; + + $users = User::where('last_name', 'like', "%{$search}%") + ->orWhere('first_name', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%") + ->orWhere('id', 'like', "%{$search}%") + ->orWhereHas('libraryPasses', function($query) use ($search) { + $query->where('barcode', 'like', "%{$search}%"); + }) + ->get(); + + return $this->CommonResponse( + ResponseStatus::success, + 'Search results', + $users + ); + } +} diff --git a/src/app/Http/Kernel.php b/src/app/Http/Kernel.php index fd469a6..1d442e4 100644 --- a/src/app/Http/Kernel.php +++ b/src/app/Http/Kernel.php @@ -54,16 +54,17 @@ class Kernel extends HttpKernel * @var array */ protected $middlewareAliases = [ - 'auth' => \App\Http\Middleware\Authenticate::class, - 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, - 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, - 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, - 'can' => \Illuminate\Auth\Middleware\Authorize::class, - 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, - 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, - 'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, - 'signed' => \App\Http\Middleware\ValidateSignature::class, - 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, - 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, + 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, + 'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, + 'signed' => \App\Http\Middleware\ValidateSignature::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'api.auth' => \App\Http\Middleware\ApiAuthorize::class, ]; } diff --git a/src/app/Http/Middleware/ApiAuthorize.php b/src/app/Http/Middleware/ApiAuthorize.php new file mode 100644 index 0000000..3b76198 --- /dev/null +++ b/src/app/Http/Middleware/ApiAuthorize.php @@ -0,0 +1,46 @@ +bearerToken(); + + if (!isset($pass)) { + return $this->CommonResponse(ResponseStatus::unauthorized, 'Unauthorized. Missing library pass.', null); + } + + $lib_pass = LibraryPass::where('barcode', $pass) + ->where('modified_kind', '!=', ModifiedEnum::deleted)->first(); + + if (!isset($lib_pass)) { + return $this->CommonResponse(ResponseStatus::unauthorized, 'Unauthorized. Invalid library pass.', null); + } + + $user = $lib_pass->user; + + if (!isset($user)) { + return $this->CommonResponse(ResponseStatus::unauthorized, 'Unauthorized. Invalid library pass.', null); + } + + return $next($request); + } +} diff --git a/src/app/Http/Middleware/HandleInertiaRequests.php b/src/app/Http/Middleware/HandleInertiaRequests.php index 8c85cd2..87d3740 100644 --- a/src/app/Http/Middleware/HandleInertiaRequests.php +++ b/src/app/Http/Middleware/HandleInertiaRequests.php @@ -3,41 +3,42 @@ namespace App\Http\Middleware; use Illuminate\Http\Request; +use Inertia\Inertia; use Inertia\Middleware; class HandleInertiaRequests extends Middleware { - /** - * The root template that's loaded on the first page visit. - * - * @see https://inertiajs.com/server-side-setup#root-template - * @var string - */ - protected $rootView = 'app'; + /** + * The root template that's loaded on the first page visit. + * + * @see https://inertiajs.com/server-side-setup#root-template + * @var string + */ + protected $rootView = 'app'; - /** - * Determines the current asset version. - * - * @see https://inertiajs.com/asset-versioning - * @param \Illuminate\Http\Request $request - * @return string|null - */ - public function version(Request $request): ?string - { - return parent::version($request); - } + /** + * Determines the current asset version. + * + * @see https://inertiajs.com/asset-versioning + * @param \Illuminate\Http\Request $request + * @return string|null + */ + public function version(Request $request): ?string + { + return parent::version($request); + } - /** - * Defines the props that are shared by default. - * - * @see https://inertiajs.com/shared-data - * @param \Illuminate\Http\Request $request - * @return array - */ - public function share(Request $request): array - { - return array_merge(parent::share($request), [ - // - ]); - } + /** + * Defines the props that are shared by default. + * + * @see https://inertiajs.com/shared-data + * @param \Illuminate\Http\Request $request + * @return array + */ + public function share(Request $request): array + { + return array_merge(parent::share($request), [ + // + ]); + } } diff --git a/src/app/Http/Requests/ApiStoreItemRequest.php b/src/app/Http/Requests/ApiStoreItemRequest.php new file mode 100644 index 0000000..865ae1e --- /dev/null +++ b/src/app/Http/Requests/ApiStoreItemRequest.php @@ -0,0 +1,32 @@ +|string> + */ + public function rules(): array + { + return [ + 'title' => 'required|string', + 'description' => 'required|string', + 'ISBN' => 'required|string', + 'images' => 'required|array', + ]; + } +} diff --git a/src/app/Http/Requests/AuthorizePassRequest.php b/src/app/Http/Requests/AuthorizePassRequest.php new file mode 100644 index 0000000..521bb70 --- /dev/null +++ b/src/app/Http/Requests/AuthorizePassRequest.php @@ -0,0 +1,29 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + return [ + 'code' => ['required', 'string', 'max:255'] + ]; + } +} diff --git a/src/app/Http/Requests/FineRequest.php b/src/app/Http/Requests/FineRequest.php new file mode 100644 index 0000000..6875b34 --- /dev/null +++ b/src/app/Http/Requests/FineRequest.php @@ -0,0 +1,29 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'grant_id' => 'required|integer|exists:grants,id', + 'amount' => 'required|decimal:1,2', + ]; + } +} diff --git a/src/app/Http/Requests/GrantItemRequest.php b/src/app/Http/Requests/GrantItemRequest.php new file mode 100644 index 0000000..3a9a267 --- /dev/null +++ b/src/app/Http/Requests/GrantItemRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + 'identifier' => 'required|string|max:255', + ]; + } +} diff --git a/src/app/Http/Requests/GrantRequest.php b/src/app/Http/Requests/GrantRequest.php new file mode 100644 index 0000000..28115d3 --- /dev/null +++ b/src/app/Http/Requests/GrantRequest.php @@ -0,0 +1,31 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'user_id' => 'required|integer|exists:users,id', + 'item_id' => 'required|integer|exists:items,id', + 'borrowed_date' => 'required|date', + 'return_date' => 'nullable|date', + ]; + } +} diff --git a/src/app/Http/Requests/ItemRequest.php b/src/app/Http/Requests/ItemRequest.php new file mode 100644 index 0000000..79ee120 --- /dev/null +++ b/src/app/Http/Requests/ItemRequest.php @@ -0,0 +1,35 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'type' => 'required|string', + 'name' => 'required|string', + 'description' => 'required|string', + 'category' => 'required|integer|exists:item_categories,id', + 'rating' => 'required|integer|exists:item_age_ratings,id', + 'borrowing_time' => 'nullable|integer', + 'ISBN' => 'nullable|string|unique:items,ISBN', + ]; + } +} diff --git a/src/app/Http/Requests/LibraryPassRequest.php b/src/app/Http/Requests/LibraryPassRequest.php new file mode 100644 index 0000000..4b816da --- /dev/null +++ b/src/app/Http/Requests/LibraryPassRequest.php @@ -0,0 +1,31 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + return [ + 'user_id' => 'integer|exists:users,id', + 'barcode' => 'required|string|max:255', + 'is_active' => 'required|boolean', + ]; + } +} diff --git a/src/app/Http/Requests/PaymentTransactionRequest.php b/src/app/Http/Requests/PaymentTransactionRequest.php new file mode 100644 index 0000000..ab85bc4 --- /dev/null +++ b/src/app/Http/Requests/PaymentTransactionRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + // + ]; + } +} diff --git a/src/app/Http/Requests/ReserveRequest.php b/src/app/Http/Requests/ReserveRequest.php new file mode 100644 index 0000000..d8289cd --- /dev/null +++ b/src/app/Http/Requests/ReserveRequest.php @@ -0,0 +1,31 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'user_id' => 'required|integer|exists:users,id', + 'item_id' => 'required|integer|exists:items,id', + 'expired_at' => 'required|date', + 'status' => 'required|integer|exists:reservation_statuses,id', + ]; + } +} diff --git a/src/app/Http/Requests/SearchItemRequest.php b/src/app/Http/Requests/SearchItemRequest.php new file mode 100644 index 0000000..25b45a5 --- /dev/null +++ b/src/app/Http/Requests/SearchItemRequest.php @@ -0,0 +1,30 @@ +|string> + */ + public function rules(): array + { + return [ + 'search' => 'required|string|max:255' + ]; + } +} diff --git a/src/app/Http/Requests/SearchReservationRequest.php b/src/app/Http/Requests/SearchReservationRequest.php new file mode 100644 index 0000000..678afc2 --- /dev/null +++ b/src/app/Http/Requests/SearchReservationRequest.php @@ -0,0 +1,30 @@ +user(); + return $user->can('search', Reservation::class); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'search' => 'required|string|min:3|max:255', + ]; + } +} diff --git a/src/app/Http/Requests/SearchUsersRequest.php b/src/app/Http/Requests/SearchUsersRequest.php new file mode 100644 index 0000000..e684f31 --- /dev/null +++ b/src/app/Http/Requests/SearchUsersRequest.php @@ -0,0 +1,30 @@ +user(); + return $user->can('search', User::class); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'search' => 'required|string|max:255' + ]; + } +} diff --git a/src/app/Jobs/ImportFromApiJob.php b/src/app/Jobs/ImportFromApiJob.php new file mode 100644 index 0000000..4a60bc4 --- /dev/null +++ b/src/app/Jobs/ImportFromApiJob.php @@ -0,0 +1,47 @@ +query as $key => $value) { + if (is_string($key)) { + throw new Exception('Query array must not be key-value pair'); + } + } + + // replace with switch statement once more sources are added + if ($this->source == ImportSources::OPEN_LIBRARY) { + $this->importOpenLibrary(); + } + } +} diff --git a/src/app/Models/Author.php b/src/app/Models/Author.php new file mode 100644 index 0000000..d988ba2 --- /dev/null +++ b/src/app/Models/Author.php @@ -0,0 +1,16 @@ +hasMany(Item::class); + } +} diff --git a/src/app/Models/Fine.php b/src/app/Models/Fine.php new file mode 100644 index 0000000..a02e8bb --- /dev/null +++ b/src/app/Models/Fine.php @@ -0,0 +1,12 @@ +belongsTo(Author::class); + } + + public function category(): BelongsTo { + return $this->BelongsTo(ItemCategory::class, 'category_id'); + } + + public function ageRating(): BelongsTo { + return $this->belongsTo(ItemAgeRating::class, 'rating_id'); + } + + public function images(): HasMany { + return $this->hasMany(ItemImage::class); + } +} diff --git a/src/app/Models/ItemAgeRating.php b/src/app/Models/ItemAgeRating.php new file mode 100644 index 0000000..254a636 --- /dev/null +++ b/src/app/Models/ItemAgeRating.php @@ -0,0 +1,11 @@ +belongsTo(User::class); + $user = $belongsTo->first(); + if ($user->modified_kind == ModifiedEnum::deleted) { + return null; + } + return $belongsTo; + } +} diff --git a/src/app/Models/PaymentTransaction.php b/src/app/Models/PaymentTransaction.php new file mode 100644 index 0000000..828f7bf --- /dev/null +++ b/src/app/Models/PaymentTransaction.php @@ -0,0 +1,12 @@ + - */ - protected $fillable = [ - 'name', - 'email', - 'password', - ]; - - /** - * The attributes that should be hidden for serialization. - * - * @var array - */ - protected $hidden = [ - 'password', - 'remember_token', - ]; - - /** - * The attributes that should be cast. - * - * @var array - */ - protected $casts = [ - 'email_verified_at' => 'datetime', - 'password' => 'hashed', - ]; + public function libraryPasses(): HasOne + { + return $this->hasOne(LibraryPass::class); + } } diff --git a/src/app/Providers/AuthServiceProvider.php b/src/app/Providers/AuthServiceProvider.php index 54756cd..eae4d98 100644 --- a/src/app/Providers/AuthServiceProvider.php +++ b/src/app/Providers/AuthServiceProvider.php @@ -2,8 +2,9 @@ namespace App\Providers; -// use Illuminate\Support\Facades\Gate; +use App\Enums\Roles; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\Gate; class AuthServiceProvider extends ServiceProvider { @@ -21,6 +22,9 @@ class AuthServiceProvider extends ServiceProvider */ public function boot(): void { - // + // Implicitly grant "Super Admin" role all permissions + Gate::before(function ($user, $ability) { + return $user->hasRole(Roles::SUPERADMIN) ? true : null; + }); } } diff --git a/src/app/Traits/CommonLibraryTrait.php b/src/app/Traits/CommonLibraryTrait.php new file mode 100644 index 0000000..92cd569 --- /dev/null +++ b/src/app/Traits/CommonLibraryTrait.php @@ -0,0 +1,75 @@ +generateLibraryPassBarCode(); + while($this->isLibraryPassBarCodeAlreadyInUse($barcode)) { + $barcode = $this->generateLibraryPassBarCode(); + } + return $barcode; + } + + /** + * @return string A random library pass barcode + */ + private function generateLibraryPassBarCode(): string + { + $prefix = Env::get('BARCODE_COMPANY_PREFIX'); + return $prefix . $this->generateRandomNumber(9); + } + + /** + * @param $length + * @return string A random number with the given length + */ + public function generateRandomNumber($length): string + { + $result = ''; + for($i = 0; $i < $length; $i++) { + $result .= mt_rand(0, 9); + } + return $result; + } + + /** + * @param $barcode + * @return bool True if the barcode is already in use, false otherwise + */ + private function isLibraryPassBarCodeAlreadyInUse($barcode): bool + { + return LibraryPass::where('barcode', $barcode)->exists(); + } + + + public function generateValidItemIdentifier(): string + { + $identifier = $this->generateItemIdentifier(); + while($this->isItemIdentifierAlreadyInUse($identifier)) { + $identifier = $this->generateItemIdentifier(); + } + return $identifier; + } + + private function generateItemIdentifier(): string + { + $prefix = "ITM"; + return $prefix . $this->generateRandomNumber(16); + } + + private function isItemIdentifierAlreadyInUse($identifier): bool + { + return Item::where('identifier', $identifier)->exists(); + } +} + diff --git a/src/app/Traits/CommonTrait.php b/src/app/Traits/CommonTrait.php new file mode 100644 index 0000000..acc47d1 --- /dev/null +++ b/src/app/Traits/CommonTrait.php @@ -0,0 +1,56 @@ +json([ + 'status' => $status->label(), + 'message' => $message, + 'data' => $data + ], $status->getStatusCode()); + } + + public function ReturnFullItem(Item $item) + { + $author = $item->author; + $category = $item->category; + $age_rating = $item->ageRating; + $images = $item->images; + + $item->author = $author; + $item->category = $category; + $item->age_rating = $age_rating; + $item->images = $images; + + + return $item; + } + + public function ReturnMultipleFullItems($items) { + $fullItems = []; + + foreach ($items as $item) { + $fullItems[] = $this->ReturnFullItem($item); + } + + return $fullItems; + } +} diff --git a/src/app/Traits/Imports/OpenLibraryTrait.php b/src/app/Traits/Imports/OpenLibraryTrait.php new file mode 100644 index 0000000..89da67e --- /dev/null +++ b/src/app/Traits/Imports/OpenLibraryTrait.php @@ -0,0 +1,87 @@ +import($offset); + if ($offset >= $maxOffset) { + break; + } + $offset += 100; + }; + } + + private function import($offset) { + $books = $this->getData($offset); + + foreach ($books as $book) { + $this->importBook($book); + } + } + + private function importBook($book) { + $authorName = !isset($book['author_name'][0]) ? $book['publisher'][0] : $book['author_name'][0]; + + if (!Author::where('name', $authorName)->exists()) { + $author = Author::create([ + 'name' => $authorName, + 'modified_kind' => 'I', + 'modified_user' => User::where('email', 'superadmin@biblio.nl')->first()->id, + ]); + } else { + $author = Author::where('name', $authorName)->first(); + } + + Item::create([ + 'identifier' => $this->generateValidItemIdentifier(), + 'type' => 'book', + 'name' => $book['title'], + 'author_id' => $author->id, + 'description' => "Dit boek is geschreven door {$authorName} en is uitgegeven in {$book['first_publish_year']}.", + 'category_id' => 1, + 'ISBN' => $book['isbn'][0] ?? "N/A", + 'rating_id' => 1, + 'borrowing_time' => 30, + 'modified_kind' => 'I', + 'modified_user' => User::where('email', 'superadmin@biblio.nl')->first()->id, + ]); + } + + private function getData($offset) + { + $baseUrl = "https://openlibrary.org/search.json?q=language%3Adut&sort=new&lang=nl&offset=" . $offset; + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $baseUrl); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + + $response = curl_exec($curl); + + curl_close($curl); + + $response = json_decode($response, true); + + return $response['docs']; + } +} diff --git a/src/composer.json b/src/composer.json index 00efa1d..e6412d3 100644 --- a/src/composer.json +++ b/src/composer.json @@ -11,7 +11,9 @@ "laravel/framework": "^10.10", "laravel/sanctum": "^3.3", "laravel/tinker": "^2.8", - "spatie/laravel-permission": "^6.1" + "mxl/laravel-job": "^1.5", + "spatie/laravel-permission": "^6.1", + "ext-curl": "*" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/src/composer.lock b/src/composer.lock index 32b7ec2..2460bf8 100644 --- a/src/composer.lock +++ b/src/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": "36be957dfb2dce7ea88a43f3afa7aa37", + "content-hash": "c5094f626e3457f76f8e319d44869e29", "packages": [ { "name": "brick/math", @@ -1044,16 +1044,16 @@ }, { "name": "laravel/framework", - "version": "v10.32.1", + "version": "v10.34.2", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "b30e44f20d244f7ba125283e14a8bbac167f4e5b" + "reference": "c581caa233e380610b34cc491490bfa147a3b62b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/b30e44f20d244f7ba125283e14a8bbac167f4e5b", - "reference": "b30e44f20d244f7ba125283e14a8bbac167f4e5b", + "url": "https://api.github.com/repos/laravel/framework/zipball/c581caa233e380610b34cc491490bfa147a3b62b", + "reference": "c581caa233e380610b34cc491490bfa147a3b62b", "shasum": "" }, "require": { @@ -1242,7 +1242,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2023-11-14T22:57:08+00:00" + "time": "2023-11-28T19:06:27+00:00" }, { "name": "laravel/prompts", @@ -1991,6 +1991,65 @@ ], "time": "2023-10-27T15:32:31+00:00" }, + { + "name": "mxl/laravel-job", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/mxl/laravel-job.git", + "reference": "fbead0adb6c420396473a08582cbc1959d981ae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mxl/laravel-job/zipball/fbead0adb6c420396473a08582cbc1959d981ae7", + "reference": "fbead0adb6c420396473a08582cbc1959d981ae7", + "shasum": "" + }, + "require": { + "laravel/framework": "5.5.*|5.6.*|5.7.*|5.8.*|^6.0|^7.0|^8.0|^9.0|^10.0", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "MichaelLedin\\LaravelJob\\LaravelJobServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "MichaelLedin\\LaravelJob\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Ledin", + "email": "mledin89@gmail.com" + } + ], + "description": "Laravel job tools", + "homepage": "https://github.com/mxl/laravel-job", + "keywords": [ + "command", + "dispatch", + "job", + "laravel", + "tools" + ], + "support": { + "issues": "https://github.com/mxl/laravel-job/issues", + "source": "https://github.com/mxl/laravel-job" + }, + "time": "2023-09-27T08:19:29+00:00" + }, { "name": "nesbot/carbon", "version": "2.71.0", @@ -3263,16 +3322,16 @@ }, { "name": "symfony/console", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92" + "reference": "cd9864b47c367450e14ab32f78fdbf98c44c26b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d14a9f6d04d4ac38a8cea1171f4554e325dae92", - "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92", + "url": "https://api.github.com/repos/symfony/console/zipball/cd9864b47c367450e14ab32f78fdbf98c44c26b6", + "reference": "cd9864b47c367450e14ab32f78fdbf98c44c26b6", "shasum": "" }, "require": { @@ -3280,7 +3339,7 @@ "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0" + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { "symfony/dependency-injection": "<5.4", @@ -3294,12 +3353,16 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -3333,7 +3396,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.8" + "source": "https://github.com/symfony/console/tree/v6.4.0" }, "funding": [ { @@ -3349,20 +3412,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T08:09:35+00:00" + "time": "2023-11-20T16:41:16+00:00" }, { "name": "symfony/css-selector", - "version": "v6.3.2", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "883d961421ab1709877c10ac99451632a3d6fa57" + "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/883d961421ab1709877c10ac99451632a3d6fa57", - "reference": "883d961421ab1709877c10ac99451632a3d6fa57", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/d036c6c0d0b09e24a14a35f8292146a658f986e4", + "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4", "shasum": "" }, "require": { @@ -3398,7 +3461,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.3.2" + "source": "https://github.com/symfony/css-selector/tree/v6.4.0" }, "funding": [ { @@ -3414,7 +3477,7 @@ "type": "tidelift" } ], - "time": "2023-07-12T16:00:22+00:00" + "time": "2023-10-31T08:40:20+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3485,30 +3548,31 @@ }, { "name": "symfony/error-handler", - "version": "v6.3.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "1f69476b64fb47105c06beef757766c376b548c4" + "reference": "c873490a1c97b3a0a4838afc36ff36c112d02788" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/1f69476b64fb47105c06beef757766c376b548c4", - "reference": "1f69476b64fb47105c06beef757766c376b548c4", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c873490a1c97b3a0a4838afc36ff36c112d02788", + "reference": "c873490a1c97b3a0a4838afc36ff36c112d02788", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "conflict": { - "symfony/deprecation-contracts": "<2.5" + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, "require-dev": { "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -3539,7 +3603,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.3.5" + "source": "https://github.com/symfony/error-handler/tree/v6.4.0" }, "funding": [ { @@ -3555,20 +3619,20 @@ "type": "tidelift" } ], - "time": "2023-09-12T06:57:20+00:00" + "time": "2023-10-18T09:43:34+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.3.2", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", - "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d76d2632cfc2206eecb5ad2b26cd5934082941b6", + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6", "shasum": "" }, "require": { @@ -3585,13 +3649,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0" + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -3619,7 +3683,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.0" }, "funding": [ { @@ -3635,7 +3699,7 @@ "type": "tidelift" } ], - "time": "2023-07-06T06:56:43+00:00" + "time": "2023-07-27T06:52:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3715,23 +3779,23 @@ }, { "name": "symfony/finder", - "version": "v6.3.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", - "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", + "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", "shasum": "" }, "require": { "php": ">=8.1" }, "require-dev": { - "symfony/filesystem": "^6.0" + "symfony/filesystem": "^6.0|^7.0" }, "type": "library", "autoload": { @@ -3759,7 +3823,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.3.5" + "source": "https://github.com/symfony/finder/tree/v6.4.0" }, "funding": [ { @@ -3775,20 +3839,20 @@ "type": "tidelift" } ], - "time": "2023-09-26T12:56:25+00:00" + "time": "2023-10-31T17:30:12+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ce332676de1912c4389222987193c3ef38033df6" + "reference": "44a6d39a9cc11e154547d882d5aac1e014440771" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ce332676de1912c4389222987193c3ef38033df6", - "reference": "ce332676de1912c4389222987193c3ef38033df6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/44a6d39a9cc11e154547d882d5aac1e014440771", + "reference": "44a6d39a9cc11e154547d882d5aac1e014440771", "shasum": "" }, "require": { @@ -3803,12 +3867,12 @@ "require-dev": { "doctrine/dbal": "^2.13.1|^3|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.3", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^5.4|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -3836,7 +3900,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.3.8" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.0" }, "funding": [ { @@ -3852,29 +3916,29 @@ "type": "tidelift" } ], - "time": "2023-11-07T10:17:15+00:00" + "time": "2023-11-20T16:41:16+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "929202375ccf44a309c34aeca8305408442ebcc1" + "reference": "16a29c453966f29466ad34444ce97970a336f3c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/929202375ccf44a309c34aeca8305408442ebcc1", - "reference": "929202375ccf44a309c34aeca8305408442ebcc1", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/16a29c453966f29466ad34444ce97970a336f3c8", + "reference": "16a29c453966f29466ad34444ce97970a336f3c8", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.3", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-foundation": "^6.3.4", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -3882,7 +3946,7 @@ "symfony/cache": "<5.4", "symfony/config": "<6.1", "symfony/console": "<5.4", - "symfony/dependency-injection": "<6.3.4", + "symfony/dependency-injection": "<6.4", "symfony/doctrine-bridge": "<5.4", "symfony/form": "<5.4", "symfony/http-client": "<5.4", @@ -3892,7 +3956,7 @@ "symfony/translation": "<5.4", "symfony/translation-contracts": "<2.5", "symfony/twig-bridge": "<5.4", - "symfony/validator": "<5.4", + "symfony/validator": "<6.4", "symfony/var-dumper": "<6.3", "twig/twig": "<2.13" }, @@ -3901,26 +3965,26 @@ }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/clock": "^6.2", - "symfony/config": "^6.1", - "symfony/console": "^5.4|^6.0", - "symfony/css-selector": "^5.4|^6.0", - "symfony/dependency-injection": "^6.3.4", - "symfony/dom-crawler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^5.4|^6.0", - "symfony/property-access": "^5.4.5|^6.0.5", - "symfony/routing": "^5.4|^6.0", - "symfony/serializer": "^6.3", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4.5|^6.0.5|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^6.3", - "symfony/var-exporter": "^6.2", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-exporter": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" }, "type": "library", @@ -3949,7 +4013,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.3.8" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.0" }, "funding": [ { @@ -3965,20 +4029,20 @@ "type": "tidelift" } ], - "time": "2023-11-10T13:47:32+00:00" + "time": "2023-11-29T10:40:15+00:00" }, { "name": "symfony/mailer", - "version": "v6.3.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "d89611a7830d51b5e118bca38e390dea92f9ea06" + "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/d89611a7830d51b5e118bca38e390dea92f9ea06", - "reference": "d89611a7830d51b5e118bca38e390dea92f9ea06", + "url": "https://api.github.com/repos/symfony/mailer/zipball/ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", + "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", "shasum": "" }, "require": { @@ -3986,8 +4050,8 @@ "php": ">=8.1", "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/mime": "^6.2", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -3998,10 +4062,10 @@ "symfony/twig-bridge": "<6.2.1" }, "require-dev": { - "symfony/console": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/messenger": "^6.2", - "symfony/twig-bridge": "^6.2" + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" }, "type": "library", "autoload": { @@ -4029,7 +4093,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.3.5" + "source": "https://github.com/symfony/mailer/tree/v6.4.0" }, "funding": [ { @@ -4045,20 +4109,20 @@ "type": "tidelift" } ], - "time": "2023-09-06T09:47:15+00:00" + "time": "2023-11-12T18:02:22+00:00" }, { "name": "symfony/mime", - "version": "v6.3.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "d5179eedf1cb2946dbd760475ebf05c251ef6a6e" + "reference": "ca4f58b2ef4baa8f6cecbeca2573f88cd577d205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/d5179eedf1cb2946dbd760475ebf05c251ef6a6e", - "reference": "d5179eedf1cb2946dbd760475ebf05c251ef6a6e", + "url": "https://api.github.com/repos/symfony/mime/zipball/ca4f58b2ef4baa8f6cecbeca2573f88cd577d205", + "reference": "ca4f58b2ef4baa8f6cecbeca2573f88cd577d205", "shasum": "" }, "require": { @@ -4072,16 +4136,16 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/mailer": "<5.4", - "symfony/serializer": "<6.2.13|>=6.3,<6.3.2" + "symfony/serializer": "<6.3.2" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/serializer": "~6.2.13|^6.3.2" + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3.2|^7.0" }, "type": "library", "autoload": { @@ -4113,7 +4177,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.3.5" + "source": "https://github.com/symfony/mime/tree/v6.4.0" }, "funding": [ { @@ -4129,7 +4193,7 @@ "type": "tidelift" } ], - "time": "2023-09-29T06:59:36+00:00" + "time": "2023-10-17T11:49:05+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4871,16 +4935,16 @@ }, { "name": "symfony/process", - "version": "v6.3.4", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" + "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", - "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", + "url": "https://api.github.com/repos/symfony/process/zipball/191703b1566d97a5425dc969e4350d32b8ef17aa", + "reference": "191703b1566d97a5425dc969e4350d32b8ef17aa", "shasum": "" }, "require": { @@ -4912,7 +4976,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.3.4" + "source": "https://github.com/symfony/process/tree/v6.4.0" }, "funding": [ { @@ -4928,20 +4992,20 @@ "type": "tidelift" } ], - "time": "2023-08-07T10:39:22+00:00" + "time": "2023-11-17T21:06:49+00:00" }, { "name": "symfony/routing", - "version": "v6.3.5", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "82616e59acd3e3d9c916bba798326cb7796d7d31" + "reference": "ae014d60d7c8e80be5c3b644a286e91249a3e8f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/82616e59acd3e3d9c916bba798326cb7796d7d31", - "reference": "82616e59acd3e3d9c916bba798326cb7796d7d31", + "url": "https://api.github.com/repos/symfony/routing/zipball/ae014d60d7c8e80be5c3b644a286e91249a3e8f4", + "reference": "ae014d60d7c8e80be5c3b644a286e91249a3e8f4", "shasum": "" }, "require": { @@ -4957,11 +5021,11 @@ "require-dev": { "doctrine/annotations": "^1.12|^2", "psr/log": "^1|^2|^3", - "symfony/config": "^6.2", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" + "symfony/config": "^6.2|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -4995,7 +5059,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.3.5" + "source": "https://github.com/symfony/routing/tree/v6.4.0" }, "funding": [ { @@ -5011,7 +5075,7 @@ "type": "tidelift" } ], - "time": "2023-09-20T16:05:51+00:00" + "time": "2023-11-29T08:04:54+00:00" }, { "name": "symfony/service-contracts", @@ -5097,16 +5161,16 @@ }, { "name": "symfony/string", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "13880a87790c76ef994c91e87efb96134522577a" + "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/13880a87790c76ef994c91e87efb96134522577a", - "reference": "13880a87790c76ef994c91e87efb96134522577a", + "url": "https://api.github.com/repos/symfony/string/zipball/b45fcf399ea9c3af543a92edf7172ba21174d809", + "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809", "shasum": "" }, "require": { @@ -5120,11 +5184,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -5163,7 +5227,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.8" + "source": "https://github.com/symfony/string/tree/v6.4.0" }, "funding": [ { @@ -5179,20 +5243,20 @@ "type": "tidelift" } ], - "time": "2023-11-09T08:28:21+00:00" + "time": "2023-11-28T20:41:49+00:00" }, { "name": "symfony/translation", - "version": "v6.3.7", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "30212e7c87dcb79c83f6362b00bde0e0b1213499" + "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/30212e7c87dcb79c83f6362b00bde0e0b1213499", - "reference": "30212e7c87dcb79c83f6362b00bde0e0b1213499", + "url": "https://api.github.com/repos/symfony/translation/zipball/b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", + "reference": "b1035dbc2a344b21f8fa8ac451c7ecec4ea45f37", "shasum": "" }, "require": { @@ -5217,17 +5281,17 @@ "require-dev": { "nikic/php-parser": "^4.13", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0" + "symfony/yaml": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -5258,7 +5322,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.3.7" + "source": "https://github.com/symfony/translation/tree/v6.4.0" }, "funding": [ { @@ -5274,7 +5338,7 @@ "type": "tidelift" } ], - "time": "2023-10-28T23:11:45+00:00" + "time": "2023-11-29T08:14:36+00:00" }, { "name": "symfony/translation-contracts", @@ -5356,16 +5420,16 @@ }, { "name": "symfony/uid", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "819fa5ac210fb7ddda4752b91a82f50be7493dd9" + "reference": "8092dd1b1a41372110d06374f99ee62f7f0b9a92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/819fa5ac210fb7ddda4752b91a82f50be7493dd9", - "reference": "819fa5ac210fb7ddda4752b91a82f50be7493dd9", + "url": "https://api.github.com/repos/symfony/uid/zipball/8092dd1b1a41372110d06374f99ee62f7f0b9a92", + "reference": "8092dd1b1a41372110d06374f99ee62f7f0b9a92", "shasum": "" }, "require": { @@ -5373,7 +5437,7 @@ "symfony/polyfill-uuid": "^1.15" }, "require-dev": { - "symfony/console": "^5.4|^6.0" + "symfony/console": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -5410,7 +5474,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v6.3.8" + "source": "https://github.com/symfony/uid/tree/v6.4.0" }, "funding": [ { @@ -5426,20 +5490,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T08:07:48+00:00" + "time": "2023-10-31T08:18:17+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "81acabba9046550e89634876ca64bfcd3c06aa0a" + "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/81acabba9046550e89634876ca64bfcd3c06aa0a", - "reference": "81acabba9046550e89634876ca64bfcd3c06aa0a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c40f7d17e91d8b407582ed51a2bbf83c52c367f6", + "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6", "shasum": "" }, "require": { @@ -5452,10 +5516,11 @@ }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", "twig/twig": "^2.13|^3.0.4" }, "bin": [ @@ -5494,7 +5559,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.3.8" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.0" }, "funding": [ { @@ -5510,7 +5575,7 @@ "type": "tidelift" } ], - "time": "2023-11-08T10:42:36+00:00" + "time": "2023-11-09T08:28:32+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -6041,16 +6106,16 @@ }, { "name": "laravel/sail", - "version": "v1.26.0", + "version": "v1.26.2", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "c60fe037004e272efd0d81f416ed2bfc623d70b4" + "reference": "c0177786b1cd05b687b0fa11364aeeecb42cd3d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/c60fe037004e272efd0d81f416ed2bfc623d70b4", - "reference": "c60fe037004e272efd0d81f416ed2bfc623d70b4", + "url": "https://api.github.com/repos/laravel/sail/zipball/c0177786b1cd05b687b0fa11364aeeecb42cd3d8", + "reference": "c0177786b1cd05b687b0fa11364aeeecb42cd3d8", "shasum": "" }, "require": { @@ -6102,7 +6167,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2023-10-18T13:57:15+00:00" + "time": "2023-11-27T14:46:06+00:00" }, { "name": "mockery/mockery", @@ -6457,16 +6522,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.8", + "version": "10.1.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "84838eed9ded511f61dc3e8b5944a52d9017b297" + "reference": "a56a9ab2f680246adcf3db43f38ddf1765774735" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/84838eed9ded511f61dc3e8b5944a52d9017b297", - "reference": "84838eed9ded511f61dc3e8b5944a52d9017b297", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/a56a9ab2f680246adcf3db43f38ddf1765774735", + "reference": "a56a9ab2f680246adcf3db43f38ddf1765774735", "shasum": "" }, "require": { @@ -6523,7 +6588,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.8" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.9" }, "funding": [ { @@ -6531,7 +6596,7 @@ "type": "github" } ], - "time": "2023-11-15T13:31:15+00:00" + "time": "2023-11-23T12:23:20+00:00" }, { "name": "phpunit/php-file-iterator", @@ -8101,16 +8166,16 @@ }, { "name": "symfony/yaml", - "version": "v6.3.8", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92" + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/3493af8a8dad7fa91c77fa473ba23ecd95334a92", - "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", "shasum": "" }, "require": { @@ -8122,7 +8187,7 @@ "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0" + "symfony/console": "^5.4|^6.0|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -8153,7 +8218,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.3.8" + "source": "https://github.com/symfony/yaml/tree/v6.4.0" }, "funding": [ { @@ -8169,7 +8234,7 @@ "type": "tidelift" } ], - "time": "2023-11-06T10:58:05+00:00" + "time": "2023-11-06T11:00:25+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/database/migrations/2014_10_12_000000_create_users_table.php b/src/database/migrations/2014_10_12_000000_create_users_table.php index 444fafb..0b060a0 100644 --- a/src/database/migrations/2014_10_12_000000_create_users_table.php +++ b/src/database/migrations/2014_10_12_000000_create_users_table.php @@ -13,11 +13,16 @@ public function up(): void { Schema::create('users', function (Blueprint $table) { $table->id(); - $table->string('name'); - $table->string('email')->unique(); - $table->timestamp('email_verified_at')->nullable(); - $table->string('password'); - $table->rememberToken(); + $table->string('first_name' ); + $table->string('last_name' ); + $table->string('email' )->unique(); + $table->string('residence'); + $table->string('street'); + $table->string('zip_code'); + $table->string('house_number'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); $table->timestamps(); }); } diff --git a/src/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/src/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php deleted file mode 100644 index e828ad8..0000000 --- a/src/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ /dev/null @@ -1,33 +0,0 @@ -id(); - $table->morphs('tokenable'); - $table->string('name'); - $table->string('token', 64)->unique(); - $table->text('abilities')->nullable(); - $table->timestamp('last_used_at')->nullable(); - $table->timestamp('expires_at')->nullable(); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('personal_access_tokens'); - } -}; diff --git a/src/database/migrations/2023_12_04_105123_create_item_age_ratings_table.php b/src/database/migrations/2023_12_04_105123_create_item_age_ratings_table.php new file mode 100644 index 0000000..ae438a5 --- /dev/null +++ b/src/database/migrations/2023_12_04_105123_create_item_age_ratings_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('rating'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('item_age_ratings'); + } +}; diff --git a/src/database/migrations/2023_12_04_105135_create_item_categories_table.php b/src/database/migrations/2023_12_04_105135_create_item_categories_table.php new file mode 100644 index 0000000..2759412 --- /dev/null +++ b/src/database/migrations/2023_12_04_105135_create_item_categories_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('category'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('item_categories'); + } +}; diff --git a/src/database/migrations/2023_12_04_125021_create_library_passes_table.php b/src/database/migrations/2023_12_04_125021_create_library_passes_table.php new file mode 100644 index 0000000..d0be0ce --- /dev/null +++ b/src/database/migrations/2023_12_04_125021_create_library_passes_table.php @@ -0,0 +1,34 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->foreign('user_id')->references('id')->on('users')->onDelete("cascade"); + $table->string('barcode'); + $table->boolean('is_active')->default(true); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('library_passes'); + } +}; diff --git a/src/database/migrations/2023_12_04_125045_create_items_table.php b/src/database/migrations/2023_12_04_125045_create_items_table.php new file mode 100644 index 0000000..2e9e448 --- /dev/null +++ b/src/database/migrations/2023_12_04_125045_create_items_table.php @@ -0,0 +1,40 @@ +id(); + $table->string('identifier')->unique(); + $table->string('type'); + $table->string('name'); + $table->text('description'); + $table->unsignedBigInteger('category'); + $table->foreign('category')->references('id')->on('item_categories'); + $table->string('ISBN')->nullable(); + $table->unsignedBigInteger('rating'); + $table->foreign('rating')->references('id')->on('item_age_ratings'); + $table->bigInteger('borrowing_time')->nullable(); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('items'); + } +}; diff --git a/src/database/migrations/2023_12_04_125051_create_grants_table.php b/src/database/migrations/2023_12_04_125051_create_grants_table.php new file mode 100644 index 0000000..b2d02c9 --- /dev/null +++ b/src/database/migrations/2023_12_04_125051_create_grants_table.php @@ -0,0 +1,36 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->foreign('user_id')->references('id')->on('users')->onDelete("cascade"); + $table->unsignedBigInteger('item_id'); + $table->foreign('item_id')->references('id')->on('items')->onDelete("cascade"); + $table->dateTime('borrowed_date'); + $table->dateTime('return_date')->nullable(); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('grants'); + } +}; diff --git a/src/database/migrations/2023_12_04_125056_create_fines_table.php b/src/database/migrations/2023_12_04_125056_create_fines_table.php new file mode 100644 index 0000000..fd73bb4 --- /dev/null +++ b/src/database/migrations/2023_12_04_125056_create_fines_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('grant_id'); + $table->foreign('grant_id')->references('id')->on('grants')->onDelete("cascade"); + $table->double('amount'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('fines'); + } +}; diff --git a/src/database/migrations/2023_12_04_125105_create_payment_transactions_table.php b/src/database/migrations/2023_12_04_125105_create_payment_transactions_table.php new file mode 100644 index 0000000..26f3a41 --- /dev/null +++ b/src/database/migrations/2023_12_04_125105_create_payment_transactions_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('fine_id'); + $table->foreign('fine_id')->references('id')->on('fines')->onDelete("cascade"); + $table->double('paid'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('payment_transactions'); + } +}; diff --git a/src/database/migrations/2023_12_04_125113_create_reservations_table.php b/src/database/migrations/2023_12_04_125113_create_reservations_table.php new file mode 100644 index 0000000..dd0715d --- /dev/null +++ b/src/database/migrations/2023_12_04_125113_create_reservations_table.php @@ -0,0 +1,35 @@ +id(); + $table->unsignedBigInteger('user_id'); + $table->foreign('user_id')->references('id')->on('users')->onDelete("cascade"); + $table->unsignedBigInteger('item_id'); + $table->foreign('item_id')->references('id')->on('items')->onDelete("cascade"); + $table->dateTime('expire_at'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('reservations'); + } +}; diff --git a/src/database/migrations/2023_12_04_125144_create_item_images_table.php b/src/database/migrations/2023_12_04_125144_create_item_images_table.php new file mode 100644 index 0000000..72bbd9a --- /dev/null +++ b/src/database/migrations/2023_12_04_125144_create_item_images_table.php @@ -0,0 +1,34 @@ +id(); + $table->unsignedBigInteger('item_id'); + $table->foreign('item_id')->references('id')->on('items')->onDelete("cascade"); + $table->string('filename'); + $table->string('path'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('item_images'); + } +}; diff --git a/src/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/src/database/migrations/2023_12_20_101128_create_jobs_table.php similarity index 50% rename from src/database/migrations/2019_08_19_000000_create_failed_jobs_table.php rename to src/database/migrations/2023_12_20_101128_create_jobs_table.php index 249da81..6098d9b 100644 --- a/src/database/migrations/2019_08_19_000000_create_failed_jobs_table.php +++ b/src/database/migrations/2023_12_20_101128_create_jobs_table.php @@ -11,14 +11,14 @@ */ public function up(): void { - Schema::create('failed_jobs', function (Blueprint $table) { - $table->id(); - $table->string('uuid')->unique(); - $table->text('connection'); - $table->text('queue'); + Schema::create('jobs', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('queue')->index(); $table->longText('payload'); - $table->longText('exception'); - $table->timestamp('failed_at')->useCurrent(); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); }); } @@ -27,6 +27,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('failed_jobs'); + Schema::dropIfExists('jobs'); } }; diff --git a/src/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php b/src/database/migrations/2023_12_21_105625_add_author_to_items.php similarity index 56% rename from src/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php rename to src/database/migrations/2023_12_21_105625_add_author_to_items.php index 81a7229..3b63a54 100644 --- a/src/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php +++ b/src/database/migrations/2023_12_21_105625_add_author_to_items.php @@ -11,10 +11,9 @@ */ public function up(): void { - Schema::create('password_reset_tokens', function (Blueprint $table) { - $table->string('email')->primary(); - $table->string('token'); - $table->timestamp('created_at')->nullable(); + Schema::table('items', function (Blueprint $table) { + $table->string('author')->nullable()->after('name'); + $table->string('publisher')->nullable()->after('author'); }); } @@ -23,6 +22,8 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('password_reset_tokens'); + Schema::table('items', function (Blueprint $table) { + // + }); } }; diff --git a/src/database/migrations/2024_01_17_101551_create_authors_table.php b/src/database/migrations/2024_01_17_101551_create_authors_table.php new file mode 100644 index 0000000..545fa55 --- /dev/null +++ b/src/database/migrations/2024_01_17_101551_create_authors_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('name'); + $table->char('modified_kind' ,1)->default('I'); + $table->unsignedBigInteger('modified_user'); + $table->foreign('modified_user')->references('id')->on('users')->onDelete("cascade"); + $table->timestamps(); + }); + + Schema::table('items', function (Blueprint $table) { + $table->unsignedBigInteger('author_id')->nullable()->after('name'); + $table->foreign('author_id')->references('id')->on('authors'); + $table->dropColumn('author'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('authors'); + } +}; diff --git a/src/database/migrations/2024_01_19_102803_rename_category_on_items.php b/src/database/migrations/2024_01_19_102803_rename_category_on_items.php new file mode 100644 index 0000000..5bb4923 --- /dev/null +++ b/src/database/migrations/2024_01_19_102803_rename_category_on_items.php @@ -0,0 +1,42 @@ +dropForeign(['category']); + $table->dropColumn('category'); + + // remove rating column + $table->dropForeign(['rating']); + $table->dropColumn('rating'); + + // add category_id column + $table->unsignedBigInteger('category_id')->nullable()->after('description'); + $table->foreign('category_id')->references('id')->on('item_categories'); + + // add rating_id column + $table->unsignedBigInteger('rating_id')->nullable()->after('ISBN'); + $table->foreign('rating_id')->references('id')->on('item_age_ratings'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('items', function (Blueprint $table) { + $table->renameColumn('category_id', 'category'); + }); + } +}; diff --git a/src/database/migrations/2024_01_22_120757_failed_jobs.php b/src/database/migrations/2024_01_22_120757_failed_jobs.php new file mode 100644 index 0000000..0285366 --- /dev/null +++ b/src/database/migrations/2024_01_22_120757_failed_jobs.php @@ -0,0 +1,32 @@ +id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/src/database/seeders/DatabaseSeeder.php b/src/database/seeders/DatabaseSeeder.php index a9f4519..79c5fde 100644 --- a/src/database/seeders/DatabaseSeeder.php +++ b/src/database/seeders/DatabaseSeeder.php @@ -3,20 +3,73 @@ namespace Database\Seeders; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; +use App\Enums\ModifiedEnum; +use App\Models\Author; +use App\Models\LibraryPass; +use App\Models\User; use Illuminate\Database\Seeder; +use App\Traits\CommonLibraryTrait; class DatabaseSeeder extends Seeder { + use CommonLibraryTrait; /** * Seed the application's database. + * Run this seeder with the following command: php artisan db:seed --class=DatabaseSeeder */ public function run(): void { - // \App\Models\User::factory(10)->create(); + //create super admin + $superAdmin = User::create([ + 'first_name' => 'Super', + 'last_name' => 'Admin', + 'email' => 'superadmin@biblio.nl', + 'residence' => 'Zwolle', + 'street' => 'Straat', + 'zip_code' => '1234AB', + 'house_number' => '1', + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => 1, + 'created_at' => now(), + 'updated_at' => now(), + ]); - // \App\Models\User::factory()->create([ - // 'name' => 'Test User', - // 'email' => 'test@example.com', - // ]); + LibraryPass::create([ + 'user_id' => $superAdmin->id, + 'barcode' => $this->generateValidLibraryPassBarCode(), + 'is_active' => true, + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => $superAdmin->id, + ]); + + //create admin, fill in your own details + $admin = User::create([ + 'first_name' => '', + 'last_name' => '', + 'email' => '', + 'residence' => '', + 'street' => '', + 'zip_code' => '', + 'house_number' => '', + 'modified_kind' => 'I', + 'modified_user' => $superAdmin->id, + 'created_at' => now(), + 'updated_at' => now(), + ]); + + LibraryPass::create([ + 'user_id' => $admin->id, + 'barcode' => $this->generateValidLibraryPassBarCode(), + 'is_active' => true, + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => $superAdmin->id, + ]); + + + Author::create([ + 'name' => 'Unknown', + 'modified_kind' => ModifiedEnum::inserted, + 'modified_user' => $superAdmin->id, + ]); } } diff --git a/src/database/seeders/ItemSeeder.php b/src/database/seeders/ItemSeeder.php new file mode 100644 index 0000000..5426f60 --- /dev/null +++ b/src/database/seeders/ItemSeeder.php @@ -0,0 +1,72 @@ + $rating, + 'modified_user' => User::where('email', 'superadmin@biblio.nl')->first()->id, + 'modified_kind' => 'I', + ]); + } + + // CATEGORIES + $categories = [ + "Action", + "Adventure", + "Animation", + "Biography", + "Comedy", + "Crime", + "Documentary", + "Drama", + "Family", + "Fantasy", + "Film-Noir", + "History", + "Horror", + "Music", + "Musical", + "Mystery", + "Romance", + "Sci-Fi", + "Sport", + "Thriller", + "War", + "Western", + ]; + + foreach ($categories as $category) { + ItemCategory::create([ + 'category' => $category, + 'modified_user' => User::where('email', 'superadmin@biblio.nl')->first()->id, + 'modified_kind' => 'I' + ]); + } + } +} diff --git a/src/database/seeders/PermissionSeeder.php b/src/database/seeders/PermissionSeeder.php new file mode 100644 index 0000000..5dc793a --- /dev/null +++ b/src/database/seeders/PermissionSeeder.php @@ -0,0 +1,104 @@ + Roles::SUPERADMIN]); + $colleague = Role::create(['name' => Roles::COLLEAGUE]); + $customer = Role::create(['name' => Roles::CUSTOMER]); + + // Create all permissions + + $borrow = Permission::create(['name' => Permissions::BORROW]); + $reserve = Permission::create(['name' => Permissions::RESERVE]); + $return = Permission::create(['name' => Permissions::RETURN]); + $loginManage = Permission::create(['name' => Permissions::LOGIN_MANAGE]); + + $viewLibraryPass = Permission::create(['name' => Permissions::VIEW_LIBRARY_PASS]); + $createLibraryPass = Permission::create(['name' => Permissions::CREATE_LIBRARY_PASS]); + $editLibraryPass = Permission::create(['name' => Permissions::EDIT_LIBRARY_PASS]); + $deleteLibraryPass = Permission::create(['name' => Permissions::DELETE_LIBRARY_PASS]); + + $viewItem = Permission::create(['name' => Permissions::VIEW_ITEM]); + $createItem = Permission::create(['name' => Permissions::CREATE_ITEM]); + $editItem = Permission::create(['name' => Permissions::EDIT_ITEM]); + $deleteItem = Permission::create(['name' => Permissions::DELETE_ITEM]); + + $viewUser = Permission::create(['name' => Permissions::VIEW_USER]); + $createUser = Permission::create(['name' => Permissions::CREATE_USER]); + $editUser = Permission::create(['name' => Permissions::EDIT_USER]); + $deleteUser = Permission::create(['name' => Permissions::DELETE_USER]); + + $viewGrant = Permission::create(['name' => Permissions::VIEW_GRANT]); + $createGrant = Permission::create(['name' => Permissions::CREATE_GRANT]); + $editGrant = Permission::create(['name' => Permissions::EDIT_GRANT]); + $deleteGrant = Permission::create(['name' => Permissions::DELETE_GRANT]); + + $viewReservation = Permission::create(['name' => Permissions::VIEW_RESERVATION]); + $createReservation = Permission::create(['name' => Permissions::CREATE_RESERVATION]); + $editReservation = Permission::create(['name' => Permissions::EDIT_RESERVATION]); + $deleteReservation = Permission::create(['name' => Permissions::DELETE_RESERVATION]); + + $viewPayment = Permission::create(['name' => Permissions::VIEW_PAYMENT]); + $createPayment = Permission::create(['name' => Permissions::CREATE_PAYMENT]); + $editPayment = Permission::create(['name' => Permissions::EDIT_PAYMENT]); + + $viewFine = Permission::create(['name' => Permissions::VIEW_FINE]); + $editFine = Permission::create(['name' => Permissions::EDIT_FINE]); + + + + // -- CUSTOMER + $customer->givePermissionTo($borrow); + $customer->givePermissionTo($reserve); + $customer->givePermissionTo($return); + + // -- COLLEAGUE + $colleague->givePermissionTo($borrow); + $colleague->givePermissionTo($reserve); + $colleague->givePermissionTo($return); + $colleague->givePermissionTo($loginManage); + + $colleague->givePermissionTo($viewLibraryPass); + $colleague->givePermissionTo($createLibraryPass); + $colleague->givePermissionTo($editLibraryPass); + $colleague->givePermissionTo($deleteLibraryPass); + + $colleague->givePermissionTo($viewItem); + $colleague->givePermissionTo($createItem); + $colleague->givePermissionTo($editItem); + $colleague->givePermissionTo($deleteItem); + + $colleague->givePermissionTo($viewUser); + $colleague->givePermissionTo($createUser); + $colleague->givePermissionTo($editUser); + $colleague->givePermissionTo($deleteUser); + + $colleague->givePermissionTo($viewGrant); + $colleague->givePermissionTo($createGrant); + $colleague->givePermissionTo($editGrant); + $colleague->givePermissionTo($deleteGrant); + + $colleague->givePermissionTo($viewReservation); + $colleague->givePermissionTo($createReservation); + $colleague->givePermissionTo($editReservation); + $colleague->givePermissionTo($deleteReservation); + + $colleague->givePermissionTo($viewPayment); + $colleague->givePermissionTo($viewFine); + } +} diff --git a/src/package-lock.json b/src/package-lock.json index 90ce54a..22468d6 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -7,11 +7,16 @@ "dependencies": { "@inertiajs/vue3": "^1.0.14", "@vitejs/plugin-vue": "^4.5.0", - "vue": "^3.3.8" + "apexcharts": "^3.45.1", + "pinia": "^2.1.7", + "vue": "^3.3.8", + "vue-toastification": "^2.0.0-rc.5", + "vue3-apexcharts": "^1.4.4" }, "devDependencies": { "axios": "^1.6.1", "laravel-vite-plugin": "^0.8.0", + "sass": "^1.69.5", "vite": "^4.0.0" } }, @@ -443,6 +448,11 @@ "@vue/shared": "3.3.8" } }, + "node_modules/@vue/devtools-api": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", + "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + }, "node_modules/@vue/reactivity": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.8.tgz", @@ -499,6 +509,38 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.8.tgz", "integrity": "sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==" }, + "node_modules/@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apexcharts": { + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.45.1.tgz", + "integrity": "sha512-pPjj/SA6dfPvR/IKRZF0STdfBGpBh3WRt7K0DFuW9P8erypYkX17EHu3/molPRfo2zSiQwTVpshHC5ncysqfkA==", + "dependencies": { + "@yr/monotone-cubic-spline": "^1.0.3", + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -514,6 +556,27 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "devOptional": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -527,6 +590,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -613,6 +703,18 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -680,6 +782,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -735,6 +849,54 @@ "node": ">= 0.4" } }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "devOptional": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/laravel-vite-plugin": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-0.8.1.tgz", @@ -808,6 +970,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nprogress": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", @@ -830,7 +1001,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8.6" }, @@ -838,6 +1009,56 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", + "dependencies": { + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.3.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", + "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -884,6 +1105,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/rollup": { "version": "3.29.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", @@ -899,6 +1132,23 @@ "fsevents": "~2.3.2" } }, + "node_modules/sass": { + "version": "1.69.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", + "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", + "devOptional": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/set-function-length": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", @@ -934,6 +1184,101 @@ "node": ">=0.10.0" } }, + "node_modules/svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/vite": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", @@ -1017,6 +1362,23 @@ "optional": true } } + }, + "node_modules/vue-toastification": { + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz", + "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==", + "peerDependencies": { + "vue": "^3.0.2" + } + }, + "node_modules/vue3-apexcharts": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/vue3-apexcharts/-/vue3-apexcharts-1.4.4.tgz", + "integrity": "sha512-TH89uZrxGjaDvkaYAISvj8+k6Bf1rUKFillc8oJirs5XZEPiwM1ELKZQ786wz0rfPqkSHHny2lqqUCK7Rw+LcQ==", + "peerDependencies": { + "apexcharts": "> 3.0.0", + "vue": "> 3.0.0" + } } } } diff --git a/src/package.json b/src/package.json index 6f83e1b..3dec16a 100644 --- a/src/package.json +++ b/src/package.json @@ -8,11 +8,16 @@ "devDependencies": { "axios": "^1.6.1", "laravel-vite-plugin": "^0.8.0", + "sass": "^1.69.5", "vite": "^4.0.0" }, "dependencies": { "@inertiajs/vue3": "^1.0.14", "@vitejs/plugin-vue": "^4.5.0", - "vue": "^3.3.8" + "apexcharts": "^3.45.1", + "pinia": "^2.1.7", + "vue": "^3.3.8", + "vue-toastification": "^2.0.0-rc.5", + "vue3-apexcharts": "^1.4.4" } } diff --git a/src/resources/js/app.js b/src/resources/js/app.js index d88f459..6f1f8b2 100644 --- a/src/resources/js/app.js +++ b/src/resources/js/app.js @@ -1,15 +1,24 @@ import './bootstrap'; import { createApp, h } from 'vue' -import { createInertiaApp } from '@inertiajs/vue3' +import { createPinia } from 'pinia' +import { createInertiaApp, Link } from '@inertiajs/vue3' +import ToastPlugin from "vue-toastification"; +import "vue-toastification/dist/index.css"; +import '@scss/global.scss'; +import VueApexCharts from "vue3-apexcharts"; createInertiaApp({ - resolve: name => { - const pages = import.meta.glob('../vue/pages/**/*.vue', { eager: true }) - return pages[`../vue/pages/${name}.vue`] - }, - setup({ el, App, props, plugin }) { - createApp({ render: () => h(App, props) }) - .use(plugin) - .mount(el) - }, + resolve: name => { + const pages = import.meta.glob('../vue/pages/**/*.vue', { eager: true }) + return pages[`../vue/pages/${name}.vue`] + }, + setup({ el, App, props, plugin }) { + createApp({ render: () => h(App, props) }) + .use(plugin) + .use(createPinia()) + .use(ToastPlugin) + .use(VueApexCharts) + .component('InertiaLink', Link) + .mount(el) + }, }) diff --git a/src/resources/stores/ExampleStore.js b/src/resources/stores/ExampleStore.js new file mode 100644 index 0000000..2f15c52 --- /dev/null +++ b/src/resources/stores/ExampleStore.js @@ -0,0 +1,22 @@ +/** + * This is an example store for pinia! + * Stores are used to store data and perform actions on that data. + * Use this as a template for creating new stores. + */ + +import { defineStore } from 'pinia' // Import the defineStore function from pinia. + + +export const useExampleStore = defineStore('example', { // The name of the store. Used in devtools and allows restoring state + state: () => ({ // State can be one or more objects that store data. + count: 0, + }), + actions: { // Actions are functions that can be called from anywhere in the app. Also known as methods/setters. + increment() { + this.count++ + }, + }, + getters: { // Getters are functions that can be called from anywhere in the app. + getCount: (state) => state.count + } +}) diff --git a/src/resources/stores/GrantStore.js b/src/resources/stores/GrantStore.js new file mode 100644 index 0000000..92f2a3a --- /dev/null +++ b/src/resources/stores/GrantStore.js @@ -0,0 +1,21 @@ +import { defineStore } from 'pinia' // Import the defineStore function from pinia. + +export const useGrantStore = defineStore('grant', { // The name of the store. Used in devtools and allows restoring state + state: () => ({ // State can be one or more objects that store data. + items: [], // Add an empty array to store multiple items + }), + actions: { + addItem(item) { + this.items.push(item); // Add the item to the items array + }, + removeItem(index) { + this.items.splice(index, 1); // Remove the item at the specified index from the items array + }, + clearItems() { + this.items = []; // Clear the items array + }, + }, + getters: { + getItems: (state) => state.items, // Return the items array + } +}) \ No newline at end of file diff --git a/src/resources/stores/ItemStore.js b/src/resources/stores/ItemStore.js new file mode 100644 index 0000000..14f4e0a --- /dev/null +++ b/src/resources/stores/ItemStore.js @@ -0,0 +1,21 @@ +import { defineStore } from 'pinia' // Import the defineStore function from pinia. + +export const useItemStore = defineStore('item', { // The name of the store. Used in devtools and allows restoring state + state: () => ({ // State can be one or more objects that store data. + items: [], // Add an empty array to store multiple items + }), + actions: { + addItem(item) { + this.items.push(item); // Add the item to the items array + }, + removeItem(index) { + this.items.splice(index, 1); // Remove the item at the specified index from the items array + }, + clearItems() { + this.items = []; // Clear the items array + }, + }, + getters: { + getItems: (state) => state.items, // Return the items array + } +}) \ No newline at end of file diff --git a/src/resources/stores/ReservationStore.js b/src/resources/stores/ReservationStore.js new file mode 100644 index 0000000..3630335 --- /dev/null +++ b/src/resources/stores/ReservationStore.js @@ -0,0 +1,21 @@ +import { defineStore } from 'pinia' // Import the defineStore function from pinia. + +export const useReservationStore = defineStore('reservation', { // The name of the store. Used in devtools and allows restoring state + state: () => ({ // State can be one or more objects that store data. + items: [], // Add an empty array to store multiple items + }), + actions: { + addItem(item) { + this.items.push(item); // Add the item to the items array + }, + removeItem(index) { + this.items.splice(index, 1); // Remove the item at the specified index from the items array + }, + clearItems() { + this.items = []; // Clear the items array + }, + }, + getters: { + getItems: (state) => state.items, // Return the items array + } +}) \ No newline at end of file diff --git a/src/resources/vue/Icons/scan-item.svg b/src/resources/vue/Icons/scan-item.svg new file mode 100644 index 0000000..d5480a8 --- /dev/null +++ b/src/resources/vue/Icons/scan-item.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/resources/vue/components/Box.vue b/src/resources/vue/components/Box.vue new file mode 100644 index 0000000..a54a1bc --- /dev/null +++ b/src/resources/vue/components/Box.vue @@ -0,0 +1,31 @@ + + + + \ No newline at end of file diff --git a/src/resources/vue/components/Button.vue b/src/resources/vue/components/Button.vue new file mode 100644 index 0000000..8ddbbbd --- /dev/null +++ b/src/resources/vue/components/Button.vue @@ -0,0 +1,57 @@ + + + + + \ No newline at end of file diff --git a/src/resources/vue/components/ExampleStore.vue b/src/resources/vue/components/ExampleStore.vue new file mode 100644 index 0000000..2b2da68 --- /dev/null +++ b/src/resources/vue/components/ExampleStore.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/src/resources/vue/components/Input.vue b/src/resources/vue/components/Input.vue new file mode 100644 index 0000000..257c8db --- /dev/null +++ b/src/resources/vue/components/Input.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/src/resources/vue/components/ItemCard.vue b/src/resources/vue/components/ItemCard.vue new file mode 100644 index 0000000..ed0ec31 --- /dev/null +++ b/src/resources/vue/components/ItemCard.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/src/resources/vue/components/Tabs.vue b/src/resources/vue/components/Tabs.vue new file mode 100644 index 0000000..bffdeba --- /dev/null +++ b/src/resources/vue/components/Tabs.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/src/resources/vue/components/admin/Siderbar.vue b/src/resources/vue/components/admin/Siderbar.vue new file mode 100644 index 0000000..14a1881 --- /dev/null +++ b/src/resources/vue/components/admin/Siderbar.vue @@ -0,0 +1,82 @@ + + + + diff --git a/src/resources/vue/components/admin/pagination.vue b/src/resources/vue/components/admin/pagination.vue new file mode 100644 index 0000000..2d139f3 --- /dev/null +++ b/src/resources/vue/components/admin/pagination.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/resources/vue/components/icon.vue b/src/resources/vue/components/icon.vue new file mode 100644 index 0000000..47e64d8 --- /dev/null +++ b/src/resources/vue/components/icon.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/src/resources/vue/components/modal.vue b/src/resources/vue/components/modal.vue new file mode 100644 index 0000000..f42109d --- /dev/null +++ b/src/resources/vue/components/modal.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/resources/vue/components/rating.vue b/src/resources/vue/components/rating.vue new file mode 100644 index 0000000..51db3d3 --- /dev/null +++ b/src/resources/vue/components/rating.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/resources/vue/components/terminal-scan.vue b/src/resources/vue/components/terminal-scan.vue new file mode 100644 index 0000000..751044b --- /dev/null +++ b/src/resources/vue/components/terminal-scan.vue @@ -0,0 +1,105 @@ + + + diff --git a/src/resources/vue/layouts/admin-layout.vue b/src/resources/vue/layouts/admin-layout.vue new file mode 100644 index 0000000..5b61bea --- /dev/null +++ b/src/resources/vue/layouts/admin-layout.vue @@ -0,0 +1,37 @@ + + + + + diff --git a/src/resources/vue/pages/admin/index.vue b/src/resources/vue/pages/admin/index.vue new file mode 100644 index 0000000..a7dd847 --- /dev/null +++ b/src/resources/vue/pages/admin/index.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/src/resources/vue/pages/admin/items/index.vue b/src/resources/vue/pages/admin/items/index.vue new file mode 100644 index 0000000..b5e9ae6 --- /dev/null +++ b/src/resources/vue/pages/admin/items/index.vue @@ -0,0 +1,97 @@ + + + + diff --git a/src/resources/vue/pages/index.vue b/src/resources/vue/pages/index.vue index c82f939..39f728a 100644 --- a/src/resources/vue/pages/index.vue +++ b/src/resources/vue/pages/index.vue @@ -1,11 +1,40 @@ - + diff --git a/src/resources/vue/pages/terminal/index.vue b/src/resources/vue/pages/terminal/index.vue new file mode 100644 index 0000000..c2a56c6 --- /dev/null +++ b/src/resources/vue/pages/terminal/index.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/src/resources/vue/scss/global.scss b/src/resources/vue/scss/global.scss new file mode 100644 index 0000000..7ff33c2 --- /dev/null +++ b/src/resources/vue/scss/global.scss @@ -0,0 +1,30 @@ +@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@100;200;300;400;500;600;700;800;900&display=swap'); +@import './variables.scss'; + +html, +body { + font-family: $font-main; + background-color: $color-dark-blue-100; + color: $color-white; + margin: 0; + padding: 0; +} + +#app { + height: 100vh; + width: 100vw; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: bold; + margin: 0; +} + +p { + margin: 0; +} \ No newline at end of file diff --git a/src/resources/vue/scss/variables.scss b/src/resources/vue/scss/variables.scss new file mode 100644 index 0000000..4fa007b --- /dev/null +++ b/src/resources/vue/scss/variables.scss @@ -0,0 +1,16 @@ +$font-main: 'Outfit', sans-serif; + +$color-white: #F7F4F3; +$color-black: #000; +$color-black-100: #343434; +$color-black-200: #424B54; + +$color-dark-blue-100: #1D243A; +$color-dark-blue-200: #445E93; + +$color-blue-100: #00BBF9; + +$color-green-100: #45CB85; +$color-green-200: #A7C957; + +$color-red-100: #FF8360; \ No newline at end of file diff --git a/src/routes/api.php b/src/routes/api.php index 889937e..7d42822 100644 --- a/src/routes/api.php +++ b/src/routes/api.php @@ -1,6 +1,8 @@ get('/user', function (Request $request) { - return $request->user(); -}); +Route::post('/item/search', [ItemController::class, 'search'])->middleware('api.auth'); +Route::post('/users/search', [UserController::class, 'search'])->middleware('api.auth'); + +Route::post('/item/store', [ItemController::class, 'ApiStore'])->middleware('api.auth'); +Route::post('/item/grant', [GrantController::class, 'GrantItem'])->middleware('api.auth'); diff --git a/src/routes/web.php b/src/routes/web.php index dcc5223..1bce344 100644 --- a/src/routes/web.php +++ b/src/routes/web.php @@ -1,6 +1,9 @@ name('auth'); diff --git a/src/vite.config.js b/src/vite.config.js index 178d8b0..2ca050c 100644 --- a/src/vite.config.js +++ b/src/vite.config.js @@ -10,4 +10,19 @@ export default defineConfig({ }), vue() ], + resolve: { + alias: { + '@': '../', + '@components': 'resources/vue/components', + '@layouts': 'resources/vue/layouts', + '@scss': './resources/vue/scss', + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: `@import "@scss/variables.scss";`, + }, + }, + }, }); diff --git a/src/webpack.config.js b/src/webpack.config.js new file mode 100644 index 0000000..ddc2864 --- /dev/null +++ b/src/webpack.config.js @@ -0,0 +1,15 @@ +module.exports = { + //... + module: { + rules: [ + { + test: /\.scss$/, + use: [ + 'vue-style-loader', + 'css-loader', + 'sass-loader' + ] + } + ] + } +} \ No newline at end of file diff --git a/src/yarn.lock b/src/yarn.lock new file mode 100644 index 0000000..8d39afe --- /dev/null +++ b/src/yarn.lock @@ -0,0 +1,635 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/parser@^7.23.0": + "integrity" "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==" + "resolved" "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz" + "version" "7.23.4" + +"@esbuild/darwin-arm64@0.18.20": + "integrity" "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==" + "resolved" "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz" + "version" "0.18.20" + +"@inertiajs/core@1.0.14": + "integrity" "sha512-S33PU6mWEYbn/s2Op+CJ6MN7ON354vWw8Y+UvtQzPt0r7pVgOuIArrqqsoulf9oQz9sbP1+vp/tCvyBzm4XmpA==" + "resolved" "https://registry.npmjs.org/@inertiajs/core/-/core-1.0.14.tgz" + "version" "1.0.14" + dependencies: + "axios" "^1.2.0" + "deepmerge" "^4.0.0" + "nprogress" "^0.2.0" + "qs" "^6.9.0" + +"@inertiajs/vue3@^1.0.14": + "integrity" "sha512-lKL3Bm9k95Gw1GAq4RxgjfwSMfklkeMbvEfzwmsEBsZ4BbbWwfpC/+KS+4O4faTjjijczvkDPhMKv4duzFxtGw==" + "resolved" "https://registry.npmjs.org/@inertiajs/vue3/-/vue3-1.0.14.tgz" + "version" "1.0.14" + dependencies: + "@inertiajs/core" "1.0.14" + "lodash.clonedeep" "^4.5.0" + "lodash.isequal" "^4.5.0" + +"@jridgewell/sourcemap-codec@^1.4.15": + "integrity" "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "resolved" "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + "version" "1.4.15" + +"@vitejs/plugin-vue@^4.5.0": + "integrity" "sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==" + "resolved" "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.5.0.tgz" + "version" "4.5.0" + +"@vue/compiler-core@3.3.8": + "integrity" "sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==" + "resolved" "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@babel/parser" "^7.23.0" + "@vue/shared" "3.3.8" + "estree-walker" "^2.0.2" + "source-map-js" "^1.0.2" + +"@vue/compiler-dom@3.3.8": + "integrity" "sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==" + "resolved" "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/compiler-core" "3.3.8" + "@vue/shared" "3.3.8" + +"@vue/compiler-sfc@3.3.8": + "integrity" "sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==" + "resolved" "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@babel/parser" "^7.23.0" + "@vue/compiler-core" "3.3.8" + "@vue/compiler-dom" "3.3.8" + "@vue/compiler-ssr" "3.3.8" + "@vue/reactivity-transform" "3.3.8" + "@vue/shared" "3.3.8" + "estree-walker" "^2.0.2" + "magic-string" "^0.30.5" + "postcss" "^8.4.31" + "source-map-js" "^1.0.2" + +"@vue/compiler-ssr@3.3.8": + "integrity" "sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==" + "resolved" "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/compiler-dom" "3.3.8" + "@vue/shared" "3.3.8" + +"@vue/devtools-api@^6.5.0": + "integrity" "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + "resolved" "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz" + "version" "6.5.1" + +"@vue/reactivity-transform@3.3.8": + "integrity" "sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==" + "resolved" "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@babel/parser" "^7.23.0" + "@vue/compiler-core" "3.3.8" + "@vue/shared" "3.3.8" + "estree-walker" "^2.0.2" + "magic-string" "^0.30.5" + +"@vue/reactivity@3.3.8": + "integrity" "sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==" + "resolved" "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/shared" "3.3.8" + +"@vue/runtime-core@3.3.8": + "integrity" "sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==" + "resolved" "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/reactivity" "3.3.8" + "@vue/shared" "3.3.8" + +"@vue/runtime-dom@3.3.8": + "integrity" "sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==" + "resolved" "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/runtime-core" "3.3.8" + "@vue/shared" "3.3.8" + "csstype" "^3.1.2" + +"@vue/server-renderer@3.3.8": + "integrity" "sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==" + "resolved" "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/compiler-ssr" "3.3.8" + "@vue/shared" "3.3.8" + +"@vue/shared@3.3.8": + "integrity" "sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==" + "resolved" "https://registry.npmjs.org/@vue/shared/-/shared-3.3.8.tgz" + "version" "3.3.8" + +"@yr/monotone-cubic-spline@^1.0.3": + "integrity" "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" + "resolved" "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz" + "version" "1.0.3" + +"anymatch@~3.1.2": + "integrity" "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==" + "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + "version" "3.1.3" + dependencies: + "normalize-path" "^3.0.0" + "picomatch" "^2.0.4" + +"apexcharts@^3.45.1", "apexcharts@> 3.0.0": + "integrity" "sha512-pPjj/SA6dfPvR/IKRZF0STdfBGpBh3WRt7K0DFuW9P8erypYkX17EHu3/molPRfo2zSiQwTVpshHC5ncysqfkA==" + "resolved" "https://registry.npmjs.org/apexcharts/-/apexcharts-3.45.1.tgz" + "version" "3.45.1" + dependencies: + "@yr/monotone-cubic-spline" "^1.0.3" + "svg.draggable.js" "^2.2.2" + "svg.easing.js" "^2.0.0" + "svg.filter.js" "^2.0.2" + "svg.pathmorphing.js" "^0.1.3" + "svg.resize.js" "^1.4.3" + "svg.select.js" "^3.0.1" + +"asynckit@^0.4.0": + "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + "version" "0.4.0" + +"axios@^1.2.0", "axios@^1.6.1": + "integrity" "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==" + "resolved" "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz" + "version" "1.6.2" + dependencies: + "follow-redirects" "^1.15.0" + "form-data" "^4.0.0" + "proxy-from-env" "^1.1.0" + +"binary-extensions@^2.0.0": + "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + "version" "2.2.0" + +"braces@~3.0.2": + "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "fill-range" "^7.0.1" + +"call-bind@^1.0.0": + "integrity" "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==" + "resolved" "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" + "version" "1.0.5" + dependencies: + "function-bind" "^1.1.2" + "get-intrinsic" "^1.2.1" + "set-function-length" "^1.1.1" + +"chokidar@>=3.0.0 <4.0.0": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"combined-stream@^1.0.8": + "integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==" + "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + "version" "1.0.8" + dependencies: + "delayed-stream" "~1.0.0" + +"csstype@^3.1.2": + "integrity" "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "resolved" "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" + "version" "3.1.2" + +"deepmerge@^4.0.0": + "integrity" "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + "resolved" "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + "version" "4.3.1" + +"define-data-property@^1.1.1": + "integrity" "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==" + "resolved" "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" + "version" "1.1.1" + dependencies: + "get-intrinsic" "^1.2.1" + "gopd" "^1.0.1" + "has-property-descriptors" "^1.0.0" + +"delayed-stream@~1.0.0": + "integrity" "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + "version" "1.0.0" + +"esbuild@^0.18.10": + "integrity" "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==" + "resolved" "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz" + "version" "0.18.20" + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +"estree-walker@^2.0.2": + "integrity" "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "resolved" "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" + "version" "2.0.2" + +"fill-range@^7.0.1": + "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "to-regex-range" "^5.0.1" + +"follow-redirects@^1.15.0": + "integrity" "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz" + "version" "1.15.3" + +"form-data@^4.0.0": + "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==" + "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "asynckit" "^0.4.0" + "combined-stream" "^1.0.8" + "mime-types" "^2.1.12" + +"fsevents@~2.3.2": + "integrity" "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + "version" "2.3.3" + +"function-bind@^1.1.2": + "integrity" "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + "version" "1.1.2" + +"get-intrinsic@^1.0.2", "get-intrinsic@^1.1.3", "get-intrinsic@^1.2.1", "get-intrinsic@^1.2.2": + "integrity" "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==" + "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" + "version" "1.2.2" + dependencies: + "function-bind" "^1.1.2" + "has-proto" "^1.0.1" + "has-symbols" "^1.0.3" + "hasown" "^2.0.0" + +"glob-parent@~5.1.2": + "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + "version" "5.1.2" + dependencies: + "is-glob" "^4.0.1" + +"gopd@^1.0.1": + "integrity" "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==" + "resolved" "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "get-intrinsic" "^1.1.3" + +"has-property-descriptors@^1.0.0": + "integrity" "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==" + "resolved" "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "get-intrinsic" "^1.2.2" + +"has-proto@^1.0.1": + "integrity" "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + "resolved" "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + "version" "1.0.1" + +"has-symbols@^1.0.3": + "integrity" "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + "version" "1.0.3" + +"hasown@^2.0.0": + "integrity" "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==" + "resolved" "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "function-bind" "^1.1.2" + +"immutable@^4.0.0": + "integrity" "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==" + "resolved" "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz" + "version" "4.3.4" + +"is-binary-path@~2.1.0": + "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" + "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "binary-extensions" "^2.0.0" + +"is-extglob@^2.1.1": + "integrity" "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + "version" "2.1.1" + +"is-glob@^4.0.1", "is-glob@~4.0.1": + "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "is-extglob" "^2.1.1" + +"is-number@^7.0.0": + "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + "version" "7.0.0" + +"laravel-vite-plugin@^0.8.0": + "integrity" "sha512-fxzUDjOA37kOsYq8dP+3oPIlw8/kJVXwu0hOXLun82R1LpV02shGeWGYKx2lbpKffL5I0sfPPjfqbYxuqBluAA==" + "resolved" "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-0.8.1.tgz" + "version" "0.8.1" + dependencies: + "picocolors" "^1.0.0" + "vite-plugin-full-reload" "^1.0.5" + +"lodash.clonedeep@^4.5.0": + "integrity" "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + "resolved" "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" + "version" "4.5.0" + +"lodash.isequal@^4.5.0": + "integrity" "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + "resolved" "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz" + "version" "4.5.0" + +"magic-string@^0.30.5": + "integrity" "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==" + "resolved" "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz" + "version" "0.30.5" + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + +"mime-db@1.52.0": + "integrity" "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + "version" "1.52.0" + +"mime-types@^2.1.12": + "integrity" "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==" + "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + "version" "2.1.35" + dependencies: + "mime-db" "1.52.0" + +"nanoid@^3.3.6": + "integrity" "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" + "version" "3.3.7" + +"normalize-path@^3.0.0", "normalize-path@~3.0.0": + "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + "version" "3.0.0" + +"nprogress@^0.2.0": + "integrity" "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + "resolved" "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz" + "version" "0.2.0" + +"object-inspect@^1.9.0": + "integrity" "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + "resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" + "version" "1.13.1" + +"picocolors@^1.0.0": + "integrity" "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "resolved" "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + "version" "1.0.0" + +"picomatch@^2.0.4", "picomatch@^2.2.1", "picomatch@^2.3.1": + "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + "version" "2.3.1" + +"pinia@^2.1.7": + "integrity" "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==" + "resolved" "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz" + "version" "2.1.7" + dependencies: + "@vue/devtools-api" "^6.5.0" + "vue-demi" ">=0.14.5" + +"postcss@^8.4.27", "postcss@^8.4.31": + "integrity" "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==" + "resolved" "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" + "version" "8.4.31" + dependencies: + "nanoid" "^3.3.6" + "picocolors" "^1.0.0" + "source-map-js" "^1.0.2" + +"proxy-from-env@^1.1.0": + "integrity" "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "resolved" "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + "version" "1.1.0" + +"qs@^6.9.0": + "integrity" "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==" + "resolved" "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" + "version" "6.11.2" + dependencies: + "side-channel" "^1.0.4" + +"readdirp@~3.6.0": + "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" + "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "picomatch" "^2.2.1" + +"rollup@^3.27.1": + "integrity" "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==" + "resolved" "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz" + "version" "3.29.4" + optionalDependencies: + "fsevents" "~2.3.2" + +"sass@*", "sass@^1.69.5": + "integrity" "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==" + "resolved" "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz" + "version" "1.69.5" + dependencies: + "chokidar" ">=3.0.0 <4.0.0" + "immutable" "^4.0.0" + "source-map-js" ">=0.6.2 <2.0.0" + +"set-function-length@^1.1.1": + "integrity" "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==" + "resolved" "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz" + "version" "1.1.1" + dependencies: + "define-data-property" "^1.1.1" + "get-intrinsic" "^1.2.1" + "gopd" "^1.0.1" + "has-property-descriptors" "^1.0.0" + +"side-channel@^1.0.4": + "integrity" "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==" + "resolved" "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + "version" "1.0.4" + dependencies: + "call-bind" "^1.0.0" + "get-intrinsic" "^1.0.2" + "object-inspect" "^1.9.0" + +"source-map-js@^1.0.2", "source-map-js@>=0.6.2 <2.0.0": + "integrity" "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "resolved" "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" + "version" "1.0.2" + +"svg.draggable.js@^2.2.2": + "integrity" "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==" + "resolved" "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz" + "version" "2.2.2" + dependencies: + "svg.js" "^2.0.1" + +"svg.easing.js@^2.0.0": + "integrity" "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==" + "resolved" "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "svg.js" ">=2.3.x" + +"svg.filter.js@^2.0.2": + "integrity" "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==" + "resolved" "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "svg.js" "^2.2.5" + +"svg.js@^2.0.1", "svg.js@^2.2.5", "svg.js@^2.4.0", "svg.js@^2.6.5", "svg.js@>=2.3.x": + "integrity" "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + "resolved" "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz" + "version" "2.7.1" + +"svg.pathmorphing.js@^0.1.3": + "integrity" "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==" + "resolved" "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz" + "version" "0.1.3" + dependencies: + "svg.js" "^2.4.0" + +"svg.resize.js@^1.4.3": + "integrity" "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==" + "resolved" "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz" + "version" "1.4.3" + dependencies: + "svg.js" "^2.6.5" + "svg.select.js" "^2.1.2" + +"svg.select.js@^2.1.2": + "integrity" "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==" + "resolved" "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "svg.js" "^2.2.5" + +"svg.select.js@^3.0.1": + "integrity" "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==" + "resolved" "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "svg.js" "^2.6.5" + +"to-regex-range@^5.0.1": + "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "is-number" "^7.0.0" + +"vite-plugin-full-reload@^1.0.5": + "integrity" "sha512-3cObNDzX6DdfhD9E7kf6w2mNunFpD7drxyNgHLw+XwIYAgb+Xt16SEXo0Up4VH+TMf3n+DSVJZtW2POBGcBYAA==" + "resolved" "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "picocolors" "^1.0.0" + "picomatch" "^2.3.1" + +"vite@^3.0.0 || ^4.0.0", "vite@^4.0.0", "vite@^4.0.0 || ^5.0.0": + "integrity" "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==" + "resolved" "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz" + "version" "4.5.0" + dependencies: + "esbuild" "^0.18.10" + "postcss" "^8.4.27" + "rollup" "^3.27.1" + optionalDependencies: + "fsevents" "~2.3.2" + +"vue-demi@>=0.14.5": + "integrity" "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==" + "resolved" "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz" + "version" "0.14.6" + +"vue-toastification@^2.0.0-rc.5": + "integrity" "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==" + "resolved" "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz" + "version" "2.0.0-rc.5" + +"vue@^2.6.14 || ^3.3.0", "vue@^3.0.0", "vue@^3.0.0-0 || ^2.6.0", "vue@^3.0.2", "vue@^3.2.25", "vue@^3.3.8", "vue@> 3.0.0", "vue@3.3.8": + "integrity" "sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==" + "resolved" "https://registry.npmjs.org/vue/-/vue-3.3.8.tgz" + "version" "3.3.8" + dependencies: + "@vue/compiler-dom" "3.3.8" + "@vue/compiler-sfc" "3.3.8" + "@vue/runtime-dom" "3.3.8" + "@vue/server-renderer" "3.3.8" + "@vue/shared" "3.3.8" + +"vue3-apexcharts@^1.4.4": + "integrity" "sha512-TH89uZrxGjaDvkaYAISvj8+k6Bf1rUKFillc8oJirs5XZEPiwM1ELKZQ786wz0rfPqkSHHny2lqqUCK7Rw+LcQ==" + "resolved" "https://registry.npmjs.org/vue3-apexcharts/-/vue3-apexcharts-1.4.4.tgz" + "version" "1.4.4"