├── LICENSE
├── README.md
├── composer.json
├── config
└── root.php
├── database
├── factories
│ ├── AuthCodeFactory.php
│ ├── EventFactory.php
│ ├── MediumFactory.php
│ ├── MetaFactory.php
│ ├── NotificationFactory.php
│ ├── SettingFactory.php
│ └── TranslationFactory.php
├── migrations
│ ├── 2020_01_01_000100_create_root_media_table.php
│ ├── 2020_07_01_000000_create_root_meta_data_table.php
│ ├── 2023_08_15_101934_create_root_notifications_table.php
│ ├── 2024_03_21_175513_create_root_events_table.php
│ ├── 2024_05_14_091321_create_root_auth_codes_table.php
│ ├── 2024_09_02_111321_create_root_settings_table.php
│ └── 2024_11_07_195330_create_root_translations_table.php
└── seeders
│ └── RootTestDataSeeder.php
├── package.json
├── public
├── build
│ ├── assets
│ │ ├── app-BhI0qz-j.css
│ │ ├── app-C0jciRh8.js
│ │ ├── app-CAFfX1PR.js
│ │ ├── chart-C0jciRh8.js
│ │ ├── dropdown-C0jciRh8.js
│ │ ├── editor-C0jciRh8.js
│ │ ├── media-manager-C0jciRh8.js
│ │ ├── repeater-C0jciRh8.js
│ │ └── table-C0jciRh8.js
│ └── manifest.json
├── favicon.ico
├── favicon.png
├── fonts
│ ├── manrope-v14-latin-500.woff2
│ ├── manrope-v14-latin-600.woff2
│ ├── manrope-v14-latin-700.woff2
│ ├── manrope-v14-latin-800.woff2
│ ├── manrope-v14-latin-regular.woff2
│ ├── open-sans-v35-latin-700.woff2
│ └── open-sans-v35-latin-regular.woff2
├── image-loading-placeholder.svg
├── img
│ ├── auth-background.png
│ ├── favicon.svg
│ └── root-logo.svg
└── root-logo-dark.svg
├── resources
├── js
│ ├── Item.js
│ ├── app.js
│ ├── chart.js
│ ├── dropdown.js
│ ├── editor.js
│ ├── helpers.js
│ ├── media-manager.js
│ ├── notifications.js
│ ├── repeater.js
│ ├── table.js
│ └── theme.js
├── sass
│ ├── app.scss
│ ├── component
│ │ ├── _alert.scss
│ │ ├── _auth-form.scss
│ │ ├── _block-navigation.scss
│ │ ├── _breadcrumb-list.scss
│ │ ├── _card.scss
│ │ ├── _context-menu.scss
│ │ ├── _data-group.scss
│ │ ├── _data-table.scss
│ │ ├── _index.scss
│ │ ├── _media-uploader.scss
│ │ ├── _modal.scss
│ │ ├── _notification-dot.scss
│ │ ├── _notification.scss
│ │ ├── _open-search.scss
│ │ ├── _or-separator.scss
│ │ ├── _pagination.scss
│ │ ├── _preloader.scss
│ │ ├── _prism.scss
│ │ ├── _range-group.scss
│ │ ├── _search-modal.scss
│ │ ├── _skip-link.scss
│ │ ├── _theme-switcher.scss
│ │ ├── _user-menu.scss
│ │ ├── _welcome-card.scss
│ │ ├── _widget.scss
│ │ ├── badge
│ │ │ ├── _index.scss
│ │ │ ├── _status.scss
│ │ │ └── _trending.scss
│ │ └── form
│ │ │ ├── _btn-dropdown.scss
│ │ │ ├── _combobox.scss
│ │ │ ├── _editor.scss
│ │ │ ├── _file-group.scss
│ │ │ ├── _file-list.scss
│ │ │ ├── _index.scss
│ │ │ ├── _repeater.scss
│ │ │ └── _search-form.scss
│ ├── config
│ │ ├── _config.scss
│ │ ├── _dark-colors.scss
│ │ ├── _dark-mode.scss
│ │ ├── _font.scss
│ │ ├── _index.scss
│ │ └── _styles.scss
│ ├── extend
│ │ ├── _btn.scss
│ │ ├── _chart.scss
│ │ ├── _form.scss
│ │ ├── _index.scss
│ │ └── _progress.scss
│ ├── helper
│ │ ├── _display.scss
│ │ ├── _index.scss
│ │ ├── _margin.scss
│ │ └── _vertical-align.scss
│ ├── layout
│ │ ├── _auth.scss
│ │ ├── _container.scss
│ │ ├── _index.scss
│ │ ├── _main.scss
│ │ └── _row.scss
│ └── section
│ │ ├── _actions.scss
│ │ ├── _body.scss
│ │ ├── _footer.scss
│ │ ├── _header.scss
│ │ ├── _heading.scss
│ │ ├── _index.scss
│ │ └── _sidebar.scss
└── views
│ ├── actions
│ ├── action.blade.php
│ └── actions.blade.php
│ ├── app.blade.php
│ ├── auth
│ ├── forgot-password.blade.php
│ ├── layout.blade.php
│ ├── login.blade.php
│ ├── reset-password.blade.php
│ └── two-factor.blade.php
│ ├── components
│ ├── alert.blade.php
│ ├── chart.blade.php
│ ├── icon.blade.php
│ ├── layout
│ │ ├── breadcrumbs.blade.php
│ │ ├── footer.blade.php
│ │ ├── header.blade.php
│ │ ├── notifications.blade.php
│ │ ├── sidebar-group.blade.php
│ │ ├── sidebar.blade.php
│ │ └── theme.blade.php
│ └── modal.blade.php
│ ├── dashboard.blade.php
│ ├── fields
│ ├── boolean.blade.php
│ ├── checkbox-option.blade.php
│ ├── checkbox.blade.php
│ ├── date.blade.php
│ ├── dropdown-option.blade.php
│ ├── dropdown.blade.php
│ ├── editor.blade.php
│ ├── editor
│ │ ├── align.blade.php
│ │ ├── blocks.blade.php
│ │ ├── format.blade.php
│ │ ├── heading.blade.php
│ │ ├── history.blade.php
│ │ ├── link.blade.php
│ │ ├── list.blade.php
│ │ └── media.blade.php
│ ├── fieldset.blade.php
│ ├── file-option.blade.php
│ ├── file.blade.php
│ ├── hidden.blade.php
│ ├── image.blade.php
│ ├── input.blade.php
│ ├── media.blade.php
│ ├── morph-to.blade.php
│ ├── panel.blade.php
│ ├── range.blade.php
│ ├── repeater-option.blade.php
│ ├── repeater-table.blade.php
│ ├── repeater.blade.php
│ ├── select.blade.php
│ ├── slug.blade.php
│ └── textarea.blade.php
│ ├── filters
│ └── search.blade.php
│ ├── icons
│ ├── archive.blade.php
│ ├── arrow-outward.blade.php
│ ├── bar-chart.blade.php
│ ├── bazar-emblem.blade.php
│ ├── check.blade.php
│ ├── chevron-down.blade.php
│ ├── chevron-left.blade.php
│ ├── chevron-right.blade.php
│ ├── chevron-up-down.blade.php
│ ├── chevron-up.blade.php
│ ├── close.blade.php
│ ├── cone-emblem.blade.php
│ ├── dark-mode.blade.php
│ ├── document.blade.php
│ ├── download.blade.php
│ ├── edit.blade.php
│ ├── eye.blade.php
│ ├── filter.blade.php
│ ├── format-align-center.blade.php
│ ├── format-align-justify.blade.php
│ ├── format-align-left.blade.php
│ ├── format-align-right.blade.php
│ ├── format-bold.blade.php
│ ├── format-bullet-list.blade.php
│ ├── format-clear.blade.php
│ ├── format-highlight.blade.php
│ ├── format-italic.blade.php
│ ├── format-line.blade.php
│ ├── format-link.blade.php
│ ├── format-ordered-list.blade.php
│ ├── format-strike.blade.php
│ ├── format-underline.blade.php
│ ├── format-unlink.blade.php
│ ├── history-do.blade.php
│ ├── history-undo.blade.php
│ ├── home.blade.php
│ ├── image.blade.php
│ ├── light-mode.blade.php
│ ├── menu-open.blade.php
│ ├── menu.blade.php
│ ├── minus.blade.php
│ ├── notifications.blade.php
│ ├── pie-chart.blade.php
│ ├── plus.blade.php
│ ├── root-emblem.blade.php
│ ├── search.blade.php
│ ├── shopping-bag.blade.php
│ ├── shopping-cart.blade.php
│ ├── spruce-emblem.blade.php
│ ├── star.blade.php
│ ├── system-mode.blade.php
│ ├── trash.blade.php
│ ├── trending-down.blade.php
│ ├── trending-up.blade.php
│ └── users.blade.php
│ ├── media
│ ├── filters.blade.php
│ ├── manager.blade.php
│ ├── medium.blade.php
│ └── queued-medium.blade.php
│ ├── resources
│ ├── form.blade.php
│ ├── index.blade.php
│ ├── relation.blade.php
│ └── show.blade.php
│ ├── table
│ ├── actions.blade.php
│ ├── body.blade.php
│ ├── cell.blade.php
│ ├── column.blade.php
│ ├── filters.blade.php
│ ├── pagination.blade.php
│ └── table.blade.php
│ └── widgets
│ ├── trend.blade.php
│ ├── value.blade.php
│ └── welcome.blade.php
├── routes
├── api.php
├── auth.php
└── web.php
├── src
├── Actions
│ ├── Action.php
│ ├── Actions.php
│ ├── SendPasswordResetNotification.php
│ └── SendVerificationNotification.php
├── Breadcrumbs
│ └── Registry.php
├── Casts
│ └── MetaValue.php
├── Console
│ └── Commands
│ │ ├── ActionMake.php
│ │ ├── ClearChunks.php
│ │ ├── ClearMedia.php
│ │ ├── FieldMake.php
│ │ ├── FilterMake.php
│ │ ├── Install.php
│ │ ├── Publish.php
│ │ ├── ResourceMake.php
│ │ ├── TrendMake.php
│ │ ├── ValueMake.php
│ │ └── WidgetMake.php
├── Conversion
│ ├── Driver.php
│ ├── GdDriver.php
│ ├── Image.php
│ └── Manager.php
├── Exceptions
│ ├── QueryResolutionException.php
│ ├── ResourceResolutionException.php
│ └── SaveFormDataException.php
├── Fields
│ ├── BelongsTo.php
│ ├── BelongsToMany.php
│ ├── Boolean.php
│ ├── Checkbox.php
│ ├── Color.php
│ ├── Date.php
│ ├── Dropdown.php
│ ├── Editor.php
│ ├── Email.php
│ ├── Events.php
│ ├── Field.php
│ ├── Fields.php
│ ├── Fieldset.php
│ ├── File.php
│ ├── HasMany.php
│ ├── HasOne.php
│ ├── HasOneOrMany.php
│ ├── Hidden.php
│ ├── ID.php
│ ├── Media.php
│ ├── Meta.php
│ ├── MorphMany.php
│ ├── MorphOne.php
│ ├── MorphOneOrMany.php
│ ├── MorphTo.php
│ ├── MorphToMany.php
│ ├── Number.php
│ ├── Option.php
│ ├── Radio.php
│ ├── Range.php
│ ├── Relation.php
│ ├── Repeater.php
│ ├── Select.php
│ ├── Slug.php
│ ├── Text.php
│ ├── Textarea.php
│ ├── Translations.php
│ └── URL.php
├── Filters
│ ├── Filter.php
│ ├── Filters.php
│ ├── MediaSearch.php
│ ├── RenderableFilter.php
│ ├── Search.php
│ ├── SearchField.php
│ ├── Select.php
│ ├── Sort.php
│ └── TrashStatus.php
├── Http
│ ├── Controllers
│ │ ├── ActionController.php
│ │ ├── Auth
│ │ │ ├── ForgotPasswordController.php
│ │ │ ├── LoginController.php
│ │ │ ├── ResetPasswordController.php
│ │ │ └── TwoFactorController.php
│ │ ├── BelongsToManyController.php
│ │ ├── Controller.php
│ │ ├── DashboardController.php
│ │ ├── DownloadController.php
│ │ ├── MediaController.php
│ │ ├── MorphToController.php
│ │ ├── NotificationController.php
│ │ ├── RelationController.php
│ │ ├── RepeaterController.php
│ │ ├── ResourceController.php
│ │ └── WidgetController.php
│ └── Middleware
│ │ ├── Authenticate.php
│ │ ├── Authorize.php
│ │ └── TwoFactorAuthenticate.php
├── Interfaces
│ ├── Breadcrumbs
│ │ └── Registry.php
│ ├── Conversion
│ │ └── Manager.php
│ ├── Form.php
│ ├── Models
│ │ ├── AuthCode.php
│ │ ├── Event.php
│ │ ├── Medium.php
│ │ ├── Meta.php
│ │ ├── Notification.php
│ │ ├── Setting.php
│ │ ├── Translation.php
│ │ └── User.php
│ ├── Navigation
│ │ └── Registry.php
│ └── Settings
│ │ ├── Registry.php
│ │ └── Repository.php
├── Jobs
│ ├── MoveFile.php
│ └── PerformConversions.php
├── Listeners
│ └── FormatRootStubs.php
├── Models
│ ├── Attachment.php
│ ├── AuthCode.php
│ ├── Event.php
│ ├── Medium.php
│ ├── Meta.php
│ ├── Notification.php
│ ├── Setting.php
│ ├── Translation.php
│ └── User.php
├── Navigation
│ ├── HasItems.php
│ ├── Item.php
│ ├── Location.php
│ └── Registry.php
├── Notifications
│ ├── AuthCodeNotification.php
│ ├── ResetPassword.php
│ ├── RootChannel.php
│ ├── RootMessage.php
│ └── RootNotification.php
├── Policies
│ └── MediumPolicy.php
├── Resources
│ ├── Resource.php
│ └── Resources.php
├── Root.php
├── RootServiceProvider.php
├── Settings
│ ├── Registry.php
│ └── Repository.php
├── Support
│ ├── Alert.php
│ ├── ClassList.php
│ └── Facades
│ │ └── Conversion.php
├── Traits
│ ├── AsForm.php
│ ├── Authorizable.php
│ ├── Filterable.php
│ ├── HasAttributes.php
│ ├── HasMedia.php
│ ├── HasMetaData.php
│ ├── HasRootEvents.php
│ ├── InteractsWithProxy.php
│ ├── Makeable.php
│ ├── RegistersRoutes.php
│ ├── ResolvesActions.php
│ ├── ResolvesFields.php
│ ├── ResolvesFilters.php
│ ├── ResolvesVisibility.php
│ ├── ResolvesWidgets.php
│ └── Translatable.php
├── View
│ └── Components
│ │ ├── Alert.php
│ │ ├── Chart.php
│ │ ├── Icon.php
│ │ ├── Layout
│ │ ├── Breadcrumbs.php
│ │ ├── Footer.php
│ │ ├── Header.php
│ │ ├── Notifications.php
│ │ ├── Sidebar.php
│ │ ├── SidebarGroup.php
│ │ └── Theme.php
│ │ └── Modal.php
└── Widgets
│ ├── Metric.php
│ ├── Trend.php
│ ├── Value.php
│ ├── Welcome.php
│ ├── Widget.php
│ └── Widgets.php
└── stubs
├── Action.stub
├── Field.stub
├── Resource.stub
├── RootServiceProvider.stub
├── SelectFilter.stub
├── Trend.stub
├── UserResource.stub
├── Value.stub
├── Widget.stub
└── placeholder.png
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Cone Development
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/database/factories/AuthCodeFactory.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | protected $model = AuthCode::class;
17 |
18 | /**
19 | * Define the model's default state.
20 | */
21 | public function definition(): array
22 | {
23 | return [
24 | 'code' => mt_rand(100000, 999999),
25 | 'expires_at' => Date::now()->addMinutes(5),
26 | ];
27 | }
28 |
29 | /**
30 | * Indicate that the model should be expired.
31 | */
32 | public function expired(): static
33 | {
34 | return $this->state(fn (array $attributes) => [
35 | 'expires_at' => Date::now()->subMinute(),
36 | ]);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/factories/EventFactory.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | protected $model = Event::class;
16 |
17 | /**
18 | * Define the model's default state.
19 | */
20 | public function definition(): array
21 | {
22 | return [
23 | 'action' => 'Create',
24 | 'payload' => [],
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/database/factories/MediumFactory.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | protected $model = Medium::class;
18 |
19 | /**
20 | * Define the model's default state.
21 | */
22 | public function definition(): array
23 | {
24 | return [
25 | 'disk' => 'public',
26 | 'name' => $name = Str::random(5),
27 | 'file_name' => "{$name}.{$this->faker->fileExtension()}",
28 | 'mime_type' => Arr::random(['image/jpg', 'application/pdf']),
29 | 'size' => mt_rand(100, 2000),
30 | 'width' => 1600,
31 | 'height' => 1200,
32 | ];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/factories/MetaFactory.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | protected $model = Meta::class;
17 |
18 | /**
19 | * Define the model's default state.
20 | */
21 | public function definition(): array
22 | {
23 | return [
24 | 'key' => Str::random(5),
25 | 'value' => Str::random(5),
26 | ];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/database/factories/NotificationFactory.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | protected $model = Notification::class;
17 |
18 | /**
19 | * Define the model's default state.
20 | */
21 | public function definition(): array
22 | {
23 | return [
24 | 'type' => 'App\\Notifications\\CustomNotification',
25 | 'subject' => $this->faker->jobTitle(),
26 | 'message' => $this->faker->paragraph(),
27 | 'data' => [],
28 | 'read_at' => Date::now(),
29 | ];
30 | }
31 |
32 | /**
33 | * Indicate that the model should be unread.
34 | */
35 | public function unread(): static
36 | {
37 | return $this->state(fn (array $attributes): array => [
38 | 'read_at' => null,
39 | ]);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/database/factories/SettingFactory.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | protected $model = Setting::class;
16 |
17 | /**
18 | * Define the model's default state.
19 | */
20 | public function definition(): array
21 | {
22 | return [
23 | 'key' => $this->faker->slug(1),
24 | 'value' => mt_rand(10, 1000),
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/database/factories/TranslationFactory.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | protected $model = Translation::class;
16 |
17 | /**
18 | * Define the model's default state.
19 | */
20 | public function definition(): array
21 | {
22 | return [
23 | 'locale' => $this->faker->locale(),
24 | ];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/database/migrations/2020_07_01_000000_create_root_meta_data_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->uuidMorphs('metable');
17 | $table->string('key')->index();
18 | $table->text('value')->nullable();
19 | $table->timestamps();
20 |
21 | $table->unique(['metable_id', 'metable_type', 'key']);
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('root_meta_data');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/migrations/2023_08_15_101934_create_root_notifications_table.php:
--------------------------------------------------------------------------------
1 | uuid('id')->primary();
16 | $table->string('type');
17 | $table->morphs('notifiable');
18 | $table->string('subject')->index();
19 | $table->text('message')->nullable();
20 | $table->json('data')->nullable();
21 | $table->timestamp('read_at')->nullable();
22 | $table->timestamps();
23 | });
24 | }
25 |
26 | /**
27 | * Reverse the migrations.
28 | */
29 | public function down(): void
30 | {
31 | Schema::dropIfExists('root_notifications');
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/database/migrations/2024_03_21_175513_create_root_events_table.php:
--------------------------------------------------------------------------------
1 | id();
17 | $table->foreignIdFor(User::getProxiedClass())->nullable()->constrained()->nullOnDelete();
18 | $table->uuidMorphs('target');
19 | $table->string('action');
20 | $table->json('payload')->nullable();
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::drop('root_events');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/migrations/2024_05_14_091321_create_root_auth_codes_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
17 | $table->integer('code')->unsigned();
18 | $table->timestamp('expires_at');
19 | $table->timestamps();
20 | });
21 | }
22 |
23 | /**
24 | * Reverse the migrations.
25 | */
26 | public function down(): void
27 | {
28 | Schema::dropIfExists('root_auth_codes');
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/database/migrations/2024_09_02_111321_create_root_settings_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('key')->unique();
17 | $table->text('value')->nullable();
18 | $table->timestamps();
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | */
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('root_settings');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/database/migrations/2024_11_07_195330_create_root_translations_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->morphs('translatable');
17 | $table->string('locale', 8);
18 | $table->json('values')->nullable();
19 | $table->timestamps();
20 |
21 | $table->unique(['translatable_id', 'translatable_type', 'locale'], 'root_translatable_locale');
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('root_translations');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/database/seeders/RootTestDataSeeder.php:
--------------------------------------------------------------------------------
1 | seedUsers();
17 | }
18 |
19 | /**
20 | * Seed the user models.
21 | */
22 | protected function seedUsers(): void
23 | {
24 | User::proxy()->newQuery()->create([
25 | 'name' => 'Root Admin',
26 | 'email' => 'admin@root.local',
27 | 'password' => Hash::make('password'),
28 | ]);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/public/build/assets/app-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/build/assets/chart-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/build/assets/dropdown-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/build/assets/editor-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/build/assets/media-manager-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/build/assets/repeater-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/build/assets/table-C0jciRh8.js:
--------------------------------------------------------------------------------
1 | import"./app-CAFfX1PR.js";
2 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/favicon.ico
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/favicon.png
--------------------------------------------------------------------------------
/public/fonts/manrope-v14-latin-500.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/manrope-v14-latin-500.woff2
--------------------------------------------------------------------------------
/public/fonts/manrope-v14-latin-600.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/manrope-v14-latin-600.woff2
--------------------------------------------------------------------------------
/public/fonts/manrope-v14-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/manrope-v14-latin-700.woff2
--------------------------------------------------------------------------------
/public/fonts/manrope-v14-latin-800.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/manrope-v14-latin-800.woff2
--------------------------------------------------------------------------------
/public/fonts/manrope-v14-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/manrope-v14-latin-regular.woff2
--------------------------------------------------------------------------------
/public/fonts/open-sans-v35-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/open-sans-v35-latin-700.woff2
--------------------------------------------------------------------------------
/public/fonts/open-sans-v35-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/fonts/open-sans-v35-latin-regular.woff2
--------------------------------------------------------------------------------
/public/img/auth-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conedevelopment/root/705facdcae1f77e1a6b99555b5129f7cb8362424/public/img/auth-background.png
--------------------------------------------------------------------------------
/resources/js/app.js:
--------------------------------------------------------------------------------
1 | import Alpine from 'alpinejs';
2 | import Axios from 'axios';
3 | import focus from '@alpinejs/focus';
4 | import Cookie from '@conedevelopment/qkie';
5 | import './notifications';
6 | import './theme';
7 | import * as Turbo from '@hotwired/turbo';
8 |
9 | // Turbo
10 | window.Turbo = Turbo;
11 |
12 | // Alpine
13 | Alpine.plugin(focus);
14 | window.Alpine = Alpine;
15 |
16 | // Axios
17 | window.$http = Axios.create({
18 | headers: {
19 | 'Accept': 'application/json',
20 | 'Content-Type': 'application/json',
21 | 'X-Requested-With': 'XMLHttpRequest',
22 | 'X-Root-Request': 'true',
23 | },
24 | });
25 |
26 | // Cookie
27 | window.$cookie = new Cookie('__root_');
28 |
29 | // Handle the relation frame load event
30 | document.addEventListener('relation-frame-loaded', (event) => {
31 | if (window.location.href !== event.detail.url) {
32 | window.history.replaceState(window.history.state, document.title, event.detail.url);
33 | }
34 | });
35 |
36 | // Handle the turbo:frame-missing
37 | document.addEventListener('turbo:frame-missing', (event) => {
38 | event.preventDefault();
39 | });
40 |
--------------------------------------------------------------------------------
/resources/js/chart.js:
--------------------------------------------------------------------------------
1 | import ApexCharts from 'apexcharts';
2 |
3 | Alpine.data('chart', (config) => {
4 | return {
5 | init() {
6 | const chart = new ApexCharts(this.$el, config);
7 |
8 | chart.render();
9 | },
10 | };
11 | });
12 |
--------------------------------------------------------------------------------
/resources/js/helpers.js:
--------------------------------------------------------------------------------
1 | const debounce = (callback, delay = 300) => {
2 | let timeoutID = null;
3 |
4 | return function () {
5 | clearTimeout(timeoutID);
6 |
7 | const args = arguments;
8 | const context = this;
9 |
10 | timeoutID = setTimeout(function () {
11 | callback.apply(context, args);
12 | }, delay);
13 | };
14 | };
15 |
16 | const throttle = (callback, wait = 300) => {
17 | let timeoutID, lastTick;
18 |
19 | return function () {
20 | const args = arguments;
21 | const context = this;
22 |
23 | if (! lastTick) {
24 | callback.apply(context, args);
25 | lastTick = Date.now();
26 | } else {
27 | clearTimeout(timeoutID);
28 | timeoutID = setTimeout(function () {
29 | if ((Date.now() - lastTick) >= wait) {
30 | callback.apply(context, args);
31 | lastTick = Date.now();
32 | }
33 | }, wait - (Date.now() - lastTick));
34 | }
35 | };
36 | };
37 |
38 | export { debounce, throttle };
39 |
--------------------------------------------------------------------------------
/resources/js/repeater.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('alpine:init', () => {
2 | window.Alpine.data('repeater', (url, options = []) => {
3 | return {
4 | processing: false,
5 | options: options,
6 | add() {
7 | this.processing = true;
8 |
9 | window.$http.post(url).then((response) => {
10 | this.options.push(response.data);
11 | }).catch((error) => {
12 | //
13 | }).finally(() => {
14 | this.processing = false;
15 | });
16 | },
17 | remove(index) {
18 | this.options.splice(index, 1);
19 | },
20 | swap(from, to) {
21 | const tmp = this.options[to];
22 |
23 | this.options[to] = this.options[from];
24 |
25 | this.options[from] = tmp;
26 | },
27 | };
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/resources/js/table.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('alpine:init', () => {
2 | window.Alpine.data('table', (config) => {
3 | return {
4 | models: config.models,
5 | selection: [],
6 | selectedAllMatchingQuery: false,
7 | selectedAllModels: false,
8 | init() {
9 | this.$watch('selection', () => {
10 | this.$refs.selectCheckbox.indeterminate = this.selection.length > 0 && this.selection.length < this.models.length;
11 |
12 | this.selectedAllModels = this.selection.length > 0 && this.selection.length === this.models.length;
13 | });
14 | },
15 | };
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/resources/sass/app.scss:
--------------------------------------------------------------------------------
1 | @forward 'config';
2 | @forward 'layout';
3 | @forward 'component';
4 | @forward 'section';
5 | @forward 'extend';
6 | @forward 'helper';
7 |
8 | @use 'sprucecss/scss/spruce' as *;
9 |
10 | :root {
11 | @include set-css-variable((
12 | --sidebar-inline-size: 20rem,
13 | --header-block-size: 4.5rem,
14 | --container-gap: spacer-clamp('m', 'l')
15 | ));
16 | }
17 |
18 | body {
19 | overflow-x: hidden;
20 | }
21 |
22 | [x-cloak] {
23 | visibility: hidden !important;
24 | }
25 |
26 | img {
27 | border-radius: config('border-radius-sm', $display);
28 | }
29 |
--------------------------------------------------------------------------------
/resources/sass/component/_auth-form.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .auth-form {
4 | @include layout-stack('s');
5 | margin-block: auto;
6 |
7 | &__title {
8 | font-weight: 700;
9 | }
10 |
11 | .or-separator {
12 | margin-block-start: spacer('m');
13 | }
14 | }
15 |
16 | .form-group-stacked,
17 | .social-logins {
18 | @include layout-stack('s');
19 | }
20 |
21 | .form-label {
22 | &--space-between {
23 | display: flex;
24 | justify-content: space-between;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resources/sass/component/_breadcrumb-list.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .breadcrumb-list {
4 | @include clear-list;
5 | align-items: center;
6 | display: flex;
7 | max-inline-size: 100%;
8 | overflow-x: auto;
9 | white-space: nowrap;
10 |
11 | > li {
12 | align-items: center;
13 | display: inline-flex;
14 | margin-block: 0;
15 |
16 | + li::before {
17 | block-size: 0.4em;
18 | border-block-end: 2px solid color('separator', 'breadcrumb');
19 | border-inline-end: 2px solid color('separator', 'breadcrumb');
20 | content: '';
21 | display: inline-flex;
22 | inline-size: 0.4em;
23 | margin-inline: 0.75em;
24 | transform: rotate(-45deg);
25 |
26 | @at-root {
27 | /* stylelint-disable-next-line selector-max-compound-selectors */
28 | [dir='rtl'] & {
29 | transform: rotate(45deg);
30 | }
31 | }
32 | }
33 | }
34 |
35 | a {
36 | text-decoration: none;
37 | }
38 |
39 | [aria-current='page'] {
40 | @include text-ellipsis(1);
41 | display: inline-block;
42 | max-inline-size: 20ch;
43 | text-align: start;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/resources/sass/component/_data-group.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .data-group {
4 | @include layout-stack('xxs');
5 |
6 | &__content {
7 | @include text-ellipsis(2);
8 | color: color('heading');
9 | font-family: config('font-family-heading', $typography);
10 | font-weight: 600;
11 | line-height: config('line-height-heading', $typography);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/resources/sass/component/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'alert';
2 | @forward 'auth-form';
3 | @forward 'badge';
4 | @forward 'block-navigation';
5 | @forward 'breadcrumb-list';
6 | @forward 'card';
7 | @forward 'context-menu';
8 | @forward 'data-group';
9 | @forward 'data-table';
10 | @forward 'form';
11 | @forward 'media-uploader';
12 | @forward 'modal';
13 | @forward 'notification-dot';
14 | @forward 'notification';
15 | @forward 'open-search';
16 | @forward 'or-separator';
17 | @forward 'pagination';
18 | @forward 'preloader';
19 | @forward 'prism';
20 | @forward 'range-group';
21 | @forward 'search-modal';
22 | @forward 'skip-link';
23 | @forward 'theme-switcher';
24 | @forward 'user-menu';
25 | @forward 'welcome-card';
26 | @forward 'widget';
27 |
--------------------------------------------------------------------------------
/resources/sass/component/_notification-dot.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .notification-dot {
4 | --size: 1em;
5 | background-color: color('success', 'alert');
6 | block-size: calc(var(--size) / 2);
7 | border-radius: 50%;
8 | display: inline-flex;
9 | inline-size: calc(var(--size) / 2);
10 | margin-left: 10px;
11 | position: relative;
12 |
13 | &::before {
14 | block-size: var(--size);
15 | border: 3px solid color('success', 'alert');
16 | border-radius: 50%;
17 | content: '';
18 | inline-size: var(--size);
19 | inset: calc(var(--size) / 4 * -1) auto auto calc(var(--size) / 4 * -1);
20 | opacity: 0;
21 | position: absolute;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/resources/sass/component/_open-search.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .open-search {
4 | @include a11y-card-link('.open-search__btn', true);
5 | align-items: center;
6 | display: flex;
7 | gap: spacer('xs');
8 |
9 | &__icon {
10 | --size: 1rem;
11 | block-size: var(--size);
12 | color: color('icon', 'search');
13 | inline-size: var(--size);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/resources/sass/component/_or-separator.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .or-separator {
4 | align-items: center;
5 | display: flex;
6 | font-size: config('font-size-sm', $typography);
7 | gap: spacer('s');
8 | text-transform: uppercase;
9 |
10 | &::before,
11 | &::after {
12 | background-color: color('border');
13 | block-size: 1px;
14 | content: '';
15 | display: flex;
16 | inline-size: 100%;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/resources/sass/component/_pagination.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .pagination {
4 | &__links {
5 | @include clear-list;
6 | display: flex;
7 | flex-wrap: wrap;
8 | gap: spacer('xs');
9 |
10 | > * + * {
11 | margin-block-start: 0;
12 | }
13 | }
14 |
15 | [aria-current='page'] {
16 | background-color: color('primary-background', 'btn');
17 | color: color('primary-foreground', 'btn');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/sass/component/_preloader.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .preloader--circle {
4 | --color: currentColor;
5 | --border-width: 0.25em;
6 | --size: 1.5rem;
7 | --animation-duration: 1s;
8 |
9 | block-size: var(--size);
10 | inline-size: var(--size);
11 |
12 | &::after {
13 | animation: rotation var(--animation-duration) linear infinite;
14 | block-size: var(--size);
15 | border: var(--border-width) solid var(--color);
16 | border-color: var(--color) transparent var(--color) transparent;
17 | border-radius: 50%;
18 | content: '';
19 | display: flex;
20 | inline-size: var(--size);
21 | }
22 | }
23 |
24 | @keyframes rotation {
25 | 0% { transform: rotate(0deg); }
26 | 100% { transform: rotate(360deg); }
27 | }
28 |
--------------------------------------------------------------------------------
/resources/sass/component/_range-group.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .range-group {
4 | display: flex;
5 | flex-direction: column;
6 | gap: spacer('xxs');
7 |
8 | .form-label {
9 | align-items: center;
10 | display: flex;
11 | flex-wrap: wrap;
12 | gap: spacer('xs');
13 | justify-content: center;
14 | }
15 |
16 | &__inner {
17 | align-items: center;
18 | display: flex;
19 | gap: spacer('xs');
20 |
21 | .form-range {
22 | flex-grow: 1;
23 | margin-block-start: 0;
24 | }
25 |
26 | .form-range-control {
27 | flex-shrink: 0;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/resources/sass/component/_search-modal.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .search-modal {
4 | display: flex;
5 | flex-direction: column;
6 | gap: spacer('s');
7 | }
8 |
9 | .search-results {
10 | @include scrollbar;
11 | @include clear-list;
12 | max-block-size: 20rem;
13 | overflow-y: auto;
14 | padding-inline-end: spacer('s');
15 |
16 | > li + li {
17 | border-block-start: 1px dashed color('border');
18 | margin-block-start: spacer('xs');
19 | padding-block-start: spacer('xs');
20 | }
21 | }
22 |
23 | .search-result-item {
24 | align-items: center;
25 | color: color('text');
26 | display: flex;
27 | flex-wrap: wrap;
28 | gap: spacer('xs');
29 | text-decoration: none;
30 |
31 | &__icon {
32 | --size: 1em;
33 | block-size: var(--size);
34 | color: color('primary');
35 | inline-size: var(--size);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/resources/sass/component/_skip-link.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .skip-link {
4 | inset: -50vh auto auto spacer('m');
5 | position: fixed;
6 |
7 | &:focus {
8 | inset-block-start: spacer('m');
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/resources/sass/component/_theme-switcher.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .no-transition {
4 | * {
5 | transition: none !important;
6 | }
7 | }
8 |
9 | .theme-switcher {
10 | color: color('text');
11 | display: inline-flex;
12 | position: relative;
13 |
14 | &[data-theme-mode='system'] &__system-mode { display: flex; }
15 | &[data-theme-mode='light'] &__light-mode { display: flex; }
16 | &[data-theme-mode='dark'] &__dark-mode { display: flex; }
17 |
18 | button {
19 | display: none;
20 |
21 | > * {
22 | pointer-events: none;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/resources/sass/component/_user-menu.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .user-menu {
4 | @include a11y-card-link('.user-menu__toggle', true);
5 | align-items: center;
6 | display: flex;
7 | gap: spacer-clamp('xs', 's', '1vw');
8 | position: relative;
9 |
10 | &__avatar {
11 | --size: 2.1rem;
12 | block-size: var(--size);
13 | border-radius: 50%;
14 | inline-size: var(--size);
15 | }
16 |
17 | &__caption {
18 | display: none;
19 | flex-direction: column;
20 | font-size: config('font-size-base', $typography);
21 | gap: spacer('xxs');
22 | line-height: 1;
23 |
24 | @include breakpoint('md') {
25 | display: flex;
26 | }
27 | }
28 |
29 | &__role {
30 | font-size: config('font-size-sm', $typography);
31 | }
32 |
33 | &__display-name {
34 | color: color('heading');
35 | font-weight: 700;
36 | }
37 |
38 | &__toggle {
39 | background: none;
40 | border: 0;
41 | cursor: pointer;
42 | display: flex;
43 | padding: 0;
44 |
45 | svg {
46 | --size: 1em;
47 | block-size: var(--size);
48 | inline-size: var(--size);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/resources/sass/component/_welcome-card.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .welcome-card {
4 | @include a11y-card-link('.welcome-card__link', true);
5 | $this: &;
6 | display: flex;
7 | gap: spacer('m');
8 | padding: spacer-clamp('m', 2rem);
9 |
10 | &__icon {
11 | --size: 3rem;
12 | align-items: center;
13 | background-color: color('icon-background', 'widget');
14 | block-size: var(--size);
15 | border-radius: config('border-radius-sm', $display);
16 | color: color('primary');
17 | display: flex;
18 | flex-shrink: 0;
19 | inline-size: var(--size);
20 | justify-content: center;
21 |
22 | svg {
23 | --size: 1.4rem;
24 | block-size: var(--size);
25 | inline-size: var(--size);
26 | }
27 | }
28 |
29 | &__title {
30 | font-size: font-size('h4');
31 | font-weight: 600;
32 | margin-block: 0;
33 | }
34 |
35 | &__link {
36 | color: color('heading');
37 | text-decoration: none;
38 |
39 | &:hover,
40 | &:focus {
41 | color: color('heading');
42 | }
43 | }
44 |
45 | &__body {
46 | @include layout-stack('xs');
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/resources/sass/component/badge/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'trending';
2 | @forward 'status';
3 |
--------------------------------------------------------------------------------
/resources/sass/component/badge/_status.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use 'sass:map';
3 | @use 'sprucecss/scss/spruce' as *;
4 |
5 | .status {
6 | align-items: center;
7 | display: inline-flex;
8 | gap: spacer('xs');
9 | line-height: 1;
10 | position: relative;
11 | white-space: nowrap;
12 |
13 | @each $name, $value in map.get($colors, 'alert') {
14 | &--#{$name}::before {
15 | background-color: color($name, 'alert');
16 | }
17 | }
18 |
19 | &::before {
20 | --size: 0.55em;
21 | block-size: var(--size);
22 | border-radius: 50%;
23 | content: '';
24 | flex-shrink: 0;
25 | inline-size: var(--size);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/resources/sass/component/badge/_trending.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use 'sprucecss/scss/spruce' as *;
3 |
4 | .trending {
5 | align-items: center;
6 | border-radius: 2rem;
7 | display: inline-flex;
8 | font-family: config('font-family-heading', $typography);
9 | font-size: config('font-size-sm', $typography);
10 | font-weight: 600;
11 | gap: spacer('xxs');
12 | line-height: 1;
13 | padding: 0.35em 0.55em;
14 |
15 | &--up {
16 | background: color.adjust(color('success', 'alert', $only-color: true), $lightness: 60%);
17 | color: color.adjust(color('success', 'alert', $only-color: true), $lightness: -7.5%);
18 | }
19 |
20 | &--down {
21 | background: color.adjust(color('danger', 'alert', $only-color: true), $lightness: 45%);
22 | color: color.adjust(color('danger', 'alert', $only-color: true), $lightness: -5%);
23 | }
24 |
25 | &__icon {
26 | --size: 0.95em;
27 | block-size: var(--size);
28 | inline-size: var(--size);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/resources/sass/component/form/_btn-dropdown.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .btn-dropdown {
4 | display: inline-flex;
5 | position: relative;
6 | z-index: 10;
7 | }
8 |
--------------------------------------------------------------------------------
/resources/sass/component/form/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'btn-dropdown';
2 | @forward 'combobox';
3 | @forward 'editor';
4 | @forward 'file-group';
5 | @forward 'file-list';
6 | @forward 'repeater';
7 | @forward 'search-form';
8 |
--------------------------------------------------------------------------------
/resources/sass/component/form/_repeater.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .repeater-container {
4 | @include layout-stack('s');
5 | }
6 |
7 | .repeater {
8 | @include generate-variables($form-control, $include: ('border-width', 'border-radius'));
9 | border: config('border-width', $form-control) solid color('border', 'form');
10 | border-radius: config('border-radius', $form-control);
11 | padding: spacer('s');
12 |
13 | &__heading {
14 | align-items: center;
15 | display: flex;
16 | flex-wrap: wrap;
17 | gap: spacer('s');
18 | justify-content: space-between;
19 | }
20 |
21 | &__body {
22 | border-block-start: 1px solid color('border');
23 | margin-block-start: spacer('s');
24 | padding-block-start: spacer('s');
25 | }
26 |
27 | &__column {
28 | align-items: center;
29 | display: flex;
30 | gap: spacer('s');
31 | }
32 |
33 | &__title {
34 | @include text-ellipsis(1);
35 | font-size: config('font-size-base', $typography);
36 | margin-block: 0;
37 | max-inline-size: 20ch;
38 | }
39 |
40 | &__actions {
41 | align-items: center;
42 | display: flex;
43 | gap: spacer('xxs');
44 | }
45 |
46 | &__toggle {
47 | &[aria-expanded='true'] {
48 | .vertical-line {
49 | display: none;
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/resources/sass/config/_dark-mode.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | @include generate-color-variables(
4 | $dark-colors,
5 | ':root[data-theme-mode="dark"]'
6 | );
7 |
8 | [data-theme-mode='dark'] {
9 | color-scheme: dark;
10 |
11 | /* stylelint-disable selector-no-qualifying-type,selector-class-pattern */
12 | select.form-control:not([multiple]):not([size]),
13 | .combobox__control {
14 | @include field-icon(
15 | config('select', $form-icon, false),
16 | color('select-foreground', 'form', true, $dark-colors)
17 | );
18 | }
19 | /* stylelint-enable */
20 | }
21 |
--------------------------------------------------------------------------------
/resources/sass/config/_font.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | @include font-face(
4 | 'Manrope',
5 | '/vendor/root/fonts/manrope-v14-latin-regular.woff2'
6 | );
7 |
8 | @include font-face(
9 | 'Manrope',
10 | '/vendor/root/fonts/manrope-v14-latin-500.woff2',
11 | 500
12 | );
13 |
14 | @include font-face(
15 | 'Manrope',
16 | '/vendor/root/fonts/manrope-v14-latin-600.woff2',
17 | 600
18 | );
19 |
20 | @include font-face(
21 | 'Manrope',
22 | '/vendor/root/fonts/manrope-v14-latin-800.woff2',
23 | 700
24 | );
25 |
26 | @include font-face(
27 | 'Open Sans',
28 | '/vendor/root/fonts/open-sans-v35-latin-regular.woff2'
29 | );
30 |
31 | @include font-face(
32 | 'Open Sans',
33 | '/vendor/root/fonts/open-sans-v35-latin-700.woff2',
34 | 700
35 | );
36 |
--------------------------------------------------------------------------------
/resources/sass/config/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'config';
2 | @forward 'font';
3 | @forward 'styles';
4 | @forward 'dark-mode';
5 |
--------------------------------------------------------------------------------
/resources/sass/config/_styles.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | @include generate-styles;
4 |
--------------------------------------------------------------------------------
/resources/sass/extend/_btn.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:color';
2 | @use 'sprucecss/scss/spruce' as *;
3 |
4 | .btn--light {
5 | @include btn-variant('light');
6 |
7 | &.btn--active {
8 | background-color: color('light-background-hover', 'btn');
9 | border-color: color('light-background-hover', 'btn');
10 | color: color('light-foreground-hover', 'btn');
11 | }
12 | }
13 |
14 | .btn--delete {
15 | @include btn-variant('delete');
16 | }
17 |
18 | .btn--dark {
19 | @include btn-variant('dark');
20 | }
21 |
22 | .btn--outline-dark {
23 | @include btn-variant-outline('dark');
24 | }
25 |
26 | .btn {
27 | &--counter {
28 | position: relative;
29 | }
30 |
31 | &__counter {
32 | background-color: color('danger', 'alert');
33 | border-radius: config('border-radius-sm', $display);
34 | color: color('primary-foreground', 'btn');
35 | font-size: 0.6375rem;
36 | inset: -0.5em -0.5em auto auto;
37 | min-inline-size: 1.25rem;
38 | padding: 0.45em;
39 | position: absolute;
40 | text-align: center;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/resources/sass/extend/_chart.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .apexcharts-legend-series {
4 | align-items: center;
5 | display: flex !important;
6 | gap: spacer('xxs');
7 | }
8 |
9 | .apexcharts-legend {
10 | display: flex;
11 | gap: spacer('s');
12 |
13 | > * {
14 | margin: 0 !important;
15 | }
16 | }
17 |
18 | .apexcharts-text,
19 | .apexcharts-legend-text {
20 | color: color('text') !important;
21 | fill: color('text');
22 | }
23 |
24 | .apexcharts-tooltip,
25 | .apexcharts-tooltip-title {
26 | background: color('background') !important;
27 | border-color: color('border') !important;
28 | }
29 |
30 | .apexcharts-tooltip-title {
31 | line-height: 1;
32 | padding-block: 0.75em !important;
33 | }
34 |
35 | .apexcharts-xaxis-tick,
36 | .apexcharts-gridline,
37 | .apexcharts-grid-borders line:last-child {
38 | stroke: color('border');
39 | }
40 |
--------------------------------------------------------------------------------
/resources/sass/extend/_form.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .form-group-stack {
4 | @include layout-stack('s');
5 |
6 | &--bordered {
7 | > * + * {
8 | border-block-start: 1px solid color('border');
9 | padding-block-start: spacer('s');
10 | }
11 | }
12 | }
13 |
14 | legend {
15 | font-family: config('font-family-heading', $typography);
16 | }
17 |
18 | .form-control[type=color] {
19 | @include set-css-variable((
20 | --border-radius: spacer-clamp('m', 'l')
21 | ));
22 | }
23 |
24 | .required-marker {
25 | color: color('danger', 'alert');
26 | }
27 |
--------------------------------------------------------------------------------
/resources/sass/extend/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'btn';
2 | @forward 'chart';
3 | @forward 'form';
4 | @forward 'progress';
5 |
--------------------------------------------------------------------------------
/resources/sass/extend/_progress.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .progressbar {
4 | display: flex;
5 | flex-direction: column;
6 | gap: spacer('xs');
7 | inline-size: 100%;
8 |
9 | &__inner {
10 | background-color: color('background', 'form');
11 | block-size: 0.5rem;
12 | border-radius: config('border-radius-sm', $display);
13 | box-shadow: inset 0 0 0 1px color('border', 'form');
14 | position: relative;
15 | }
16 |
17 | &__indicator {
18 | background-color: color('primary');
19 | block-size: 100%;
20 | border-radius: config('border-radius-sm', $display);
21 | inset: 0 auto 0 0;
22 | position: absolute;
23 |
24 | &:not([style*='inline-size']) {
25 | animation: 1s progress infinite linear alternate;
26 | inline-size: 20%;
27 | }
28 | }
29 |
30 | &__caption {
31 | text-align: center;
32 | }
33 | }
34 |
35 | @keyframes progress {
36 | 0% {
37 | inset-inline-start: 0%;
38 | }
39 |
40 | 100% {
41 | inset-inline-start: 80%;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/resources/sass/helper/_display.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .display {
4 | @each $name, $breakpoint in $breakpoints {
5 | @include breakpoint($name) {
6 | &--flex\:#{$name} {
7 | display: flex !important;
8 | }
9 | }
10 | }
11 |
12 | @each $name, $breakpoint in $breakpoints {
13 | @include breakpoint($name) {
14 | &--none\:#{$name} {
15 | display: none !important;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/sass/helper/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'display';
2 | @forward 'margin';
3 | @forward 'vertical-align';
4 |
--------------------------------------------------------------------------------
/resources/sass/helper/_margin.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .m-block\:0 {
4 | margin-block: 0 !important;
5 | }
6 |
--------------------------------------------------------------------------------
/resources/sass/helper/_vertical-align.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .vertical-align\:top {
4 | vertical-align: top !important;
5 | }
6 |
--------------------------------------------------------------------------------
/resources/sass/layout/_container.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .container {
4 | --inline-size: #{config('container-inline-size', $layout)};
5 | --gap: #{get-css-variable(--container-gap)};
6 |
7 | @include layout-center(
8 | var(--gap),
9 | var(--inline-size)
10 | );
11 |
12 | &--wide {
13 | --inline-size: 100%;
14 | }
15 |
16 | &--narrow {
17 | --inline-size: 50rem;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/sass/layout/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'container';
2 | @forward 'row';
3 | @forward 'main';
4 | @forward 'auth';
5 |
--------------------------------------------------------------------------------
/resources/sass/layout/_main.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .l-main {
4 | display: flex;
5 | position: relative;
6 |
7 | &__sidebar {
8 | background-color: color('background');
9 | display: none;
10 | inline-size: get-css-variable(--sidebar-inline-size);
11 | inset-block: 0;
12 | inset-inline: 0 auto;
13 | position: fixed;
14 | z-index: 20;
15 |
16 | @include breakpoint('md') {
17 | display: block;
18 | }
19 |
20 | &--open {
21 | display: block;
22 | }
23 | }
24 |
25 | &__body {
26 | background-color: color('background', 'main');
27 | inline-size: 100%;
28 | min-block-size: calc(100lvh + 1rem);
29 |
30 | @include breakpoint('md') {
31 | inline-size: calc(100% - #{get-css-variable(--sidebar-inline-size)});
32 | margin-inline-start: get-css-variable(--sidebar-inline-size);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/resources/sass/layout/_row.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .l-row {
4 | align-items: start;
5 | display: grid;
6 | gap: spacer('m');
7 | grid-template-columns: minmax(0, 1fr);
8 |
9 | &--stretch {
10 | align-items: stretch;
11 | }
12 |
13 | @each $name, $breakpoint in $breakpoints {
14 | @for $i from 1 through 4 {
15 | @include breakpoint($name) {
16 | &--column\:#{$name}\:#{$i} {
17 | grid-template-columns: repeat(#{$i}, minmax(0, 1fr));
18 | }
19 | }
20 | }
21 | }
22 |
23 | &--sidebar {
24 | @include breakpoint('lg') {
25 | grid-template-columns: minmax(0, 1fr) minmax(0, 20rem);
26 | }
27 | }
28 |
29 | &__column {
30 | display: grid;
31 | gap: spacer('m');
32 | grid-template-columns: minmax(0, 1fr);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/resources/sass/section/_actions.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .app-actions {
4 | justify-content: space-between;
5 |
6 | &--sidebar {
7 | @include breakpoint('lg') {
8 | margin-inline-end: calc(20rem + #{spacer('m')});
9 | }
10 | }
11 |
12 | &,
13 | &__column {
14 | display: flex;
15 | flex-wrap: wrap;
16 | gap: spacer('m');
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/resources/sass/section/_body.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .app-body {
4 | display: flex;
5 | flex-direction: column;
6 | gap: spacer('m');
7 | }
8 |
--------------------------------------------------------------------------------
/resources/sass/section/_footer.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .app-footer {
4 | padding-block: spacer-clamp('m', 'l');
5 | text-align: center;
6 |
7 | &__created-with {
8 | margin-block: 0;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/resources/sass/section/_header.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .app-header {
4 | backdrop-filter: saturate(180%) blur(0.25rem);
5 | background-color: color('background', 'header');
6 | border-block-end: 1px solid color('border');
7 | inset-block-start: 0;
8 | inset-block-start: 0;
9 | position: sticky;
10 | position: sticky;
11 | z-index: 15;
12 |
13 | &__inner {
14 | align-items: center;
15 | block-size: get-css-variable(--header-block-size);
16 | display: flex;
17 | flex-wrap: wrap;
18 | gap: spacer-clamp('s', 'l');
19 | justify-content: space-between;
20 | margin-inline: get-css-variable(--container-gap);
21 | }
22 |
23 | &__column {
24 | align-items: center;
25 | display: flex;
26 | flex-grow: 1;
27 | gap: spacer-clamp('s', 'm');
28 | }
29 |
30 | &__actions {
31 | align-items: center;
32 | display: flex;
33 | gap: spacer-clamp('s', 'm');
34 |
35 | &--secondary {
36 | gap: spacer('s');
37 | }
38 | }
39 |
40 | &__logo {
41 | block-size: 1.25rem;
42 | display: inline-flex;
43 |
44 | @include breakpoint('md') {
45 | display: none;
46 | }
47 | }
48 |
49 | &__breadcrumb {
50 | display: none;
51 |
52 | @include breakpoint('md') {
53 | display: flex;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/resources/sass/section/_heading.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .app-heading {
4 | padding-block: spacer-clamp('m', 'l');
5 |
6 | &__inner {
7 | display: flex;
8 | flex-wrap: wrap;
9 | gap: spacer('s') spacer('m');
10 | justify-content: space-between;
11 |
12 | &--column {
13 | flex-direction: column;
14 | }
15 | }
16 |
17 | &__caption {
18 | @include layout-stack('xs');
19 | }
20 |
21 | &__title {
22 | font-weight: 700;
23 | }
24 |
25 | &__description {
26 | @include layout-stack('xxs');
27 | align-items: center;
28 | display: flex;
29 | flex-wrap: wrap;
30 | font-size: 1rem;
31 | gap: spacer('xs') spacer('m');
32 | }
33 |
34 | &__actions {
35 | align-items: center;
36 | display: flex;
37 | flex-wrap: wrap;
38 | gap: spacer('xs')spacer('s');
39 | justify-content: end;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/resources/sass/section/_index.scss:
--------------------------------------------------------------------------------
1 | @forward 'sidebar';
2 | @forward 'header';
3 | @forward 'heading';
4 | @forward 'body';
5 | @forward 'actions';
6 | @forward 'footer';
7 |
--------------------------------------------------------------------------------
/resources/sass/section/_sidebar.scss:
--------------------------------------------------------------------------------
1 | @use 'sprucecss/scss/spruce' as *;
2 |
3 | .app-sidebar {
4 | block-size: 100%;
5 | border-inline-end: 1px solid color('border');
6 | display: flex;
7 | flex-direction: column;
8 | gap: spacer('m');
9 | padding-block: 0 spacer('m');
10 |
11 | &__logo {
12 | block-size: 1.25rem;
13 | display: inline-flex;
14 | }
15 |
16 | &__search {
17 | display: none;
18 |
19 | @include breakpoint('md') {
20 | display: flex;
21 | }
22 | }
23 |
24 | &__header {
25 | align-items: center;
26 | block-size: get-css-variable(--header-block-size);
27 | border-block-end: 1px solid color('border');
28 | display: flex;
29 | flex-shrink: 0;
30 | justify-content: space-between;
31 | margin-inline: spacer('m');
32 | }
33 |
34 | &__body {
35 | @include scrollbar(
36 | $border-radius: 0.15em
37 | );
38 | flex-grow: 1;
39 | margin-inline: calc(#{spacer('m')} / 2);
40 | overflow-y: auto;
41 | padding-inline: calc(#{spacer('m')} / 2);
42 |
43 | > * + * {
44 | border-block-start: 1px solid color('border');
45 | margin-block-start: spacer('s');
46 | padding-block-start: spacer('s');
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/resources/views/actions/action.blade.php:
--------------------------------------------------------------------------------
1 |
{!! $field['label'] !!} | 7 | @endforeach 8 |
---|
{!! $field['formattedValue'] !!} | 15 | @endforeach 16 |