diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 16d84de6..fb8a8af8 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -3,28 +3,41 @@ name: Check # Run this workflow every time a new commit pushed to your repository on: push: - paths-ignore: - - '.github/**/*' - - '**/*.md' - - 'public/build/*.js' - - 'public/build/**/*.js' - - 'docker/**/*' - - 'resources/scripts/**/*' tags-ignore: - "*" branches-ignore: - 'translations' pull_request: - paths-ignore: - - '**/*.md' - - 'public/build/*.js' - - 'public/build/**/*.js' branches-ignore: - 'translations' # Allow manually triggering the workflow. workflow_dispatch: jobs: + changes: + name: 🔍 Detect changes + runs-on: ubuntu-latest + outputs: + php: ${{ steps.filter.outputs.php }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Check for file changes + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + php: + - 'app/**' + - 'config/**' + - 'database/**' + - 'routes/**' + - 'tests/**' + - 'composer.json' + - 'composer.lock' + - 'phpunit.xml' + kill_previous: name: 0️⃣ Kill previous runs runs-on: ubuntu-latest @@ -41,6 +54,8 @@ jobs: runs-on: ubuntu-latest needs: - kill_previous + - changes + if: needs.changes.outputs.php == 'true' steps: - name: Set up PHP uses: shivammathur/setup-php@v2 @@ -60,6 +75,8 @@ jobs: name: 2️⃣ PHP ${{ matrix.php-version }} Tests needs: - php_syntax_errors + - changes + if: needs.changes.outputs.php == 'true' runs-on: ubuntu-latest strategy: matrix: diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..6ba2a11e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,80 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +InvoiceShelf is an open-source invoicing and expense tracking application built with Laravel 13 (PHP 8.4) and Vue 3. It supports multi-company tenancy, customer portals, recurring invoices, and PDF generation. + +## Common Commands + +### Development +```bash +composer run dev # Starts PHP server, queue listener, log tail, and Vite dev server concurrently +npm run dev # Vite dev server only +npm run build # Production frontend build +``` + +### Testing +```bash +php artisan test --compact # Run all tests +php artisan test --compact --filter=testName # Run specific test +./vendor/bin/pest --stop-on-failure # Run via Pest directly +make test # Makefile shortcut +``` + +Tests use SQLite in-memory DB, configured in `phpunit.xml`. Tests seed via `DatabaseSeeder` + `DemoSeeder` in `beforeEach`. Authenticate with `Sanctum::actingAs()` and set the `company` header. + +### Code Style +```bash +vendor/bin/pint --dirty --format agent # Fix style on modified PHP files +vendor/bin/pint --test # Check style without fixing (CI uses this) +``` + +### Artisan Generators +Always use `php artisan make:*` with `--no-interaction` to create new files (models, controllers, migrations, tests, etc.). + +## Architecture + +### Multi-Tenancy +Every major model has a `company_id` foreign key. The `CompanyMiddleware` sets the active company from the `company` request header. Bouncer authorization is scoped to the company level via `DefaultScope` (`app/Bouncer/Scopes/DefaultScope.php`). + +### Authentication +Three guards: `web` (session), `api` (Sanctum tokens for `/api/v1/`), `customer` (session for customer portal). API routes use `auth:sanctum` middleware; customer portal uses `auth:customer`. + +### Routing +- **API**: All endpoints under `/api/v1/` in `routes/api.php`, grouped with `auth:sanctum`, `company`, and `bouncer` middleware +- **Web**: `routes/web.php` serves PDF endpoints, auth pages, and catch-all SPA routes (`/admin/{vue?}`, `/{company:slug}/customer/{vue?}`) + +### Frontend +- Entry point: `resources/scripts/main.js` +- Vue Router: `resources/scripts/admin/admin-router.js` (admin), `resources/scripts/customer/customer-router.js` (customer portal) +- State: Pinia stores in `resources/scripts/admin/stores/` +- Path aliases: `@` = `resources/`, `$fonts`, `$images` for static assets +- Vite dev server expects `invoiceshelf.test` hostname + +### Backend Patterns +- **Authorization**: Silber/Bouncer with policies in `app/Policies/`. Controllers use `$this->authorize()`. +- **Validation**: Form Request classes, never inline validation +- **API responses**: Eloquent API Resources in `app/Http/Resources/` +- **PDF generation**: DomPDF (`GeneratesPdfTrait`) or Gotenberg +- **Email**: Mailable classes with `EmailLog` tracking +- **File storage**: Spatie MediaLibrary, supports local/S3/Dropbox +- **Serial numbers**: `SerialNumberFormatter` service +- **Company settings**: `CompanySetting` model (key-value per company) + +### Database +Supports MySQL, PostgreSQL, and SQLite. Prefer Eloquent over raw queries. Use `Model::query()` instead of `DB::`. Use eager loading to prevent N+1 queries. + +## Code Conventions + +- PHP: snake_case, constructor property promotion, explicit return types, PHPDoc blocks over inline comments +- JS: camelCase +- Always check sibling files for patterns before creating new ones +- Use `config()` helper, never `env()` outside config files +- Every change must have tests (feature tests preferred over unit tests) +- Run `vendor/bin/pint --dirty --format agent` after modifying PHP files + +## CI Pipeline + +GitHub Actions (`check.yaml`): runs Pint style check, then builds frontend and runs Pest tests on PHP 8.4. diff --git a/app/Console/Commands/ResetApp.php b/app/Console/Commands/ResetApp.php index 6724286f..2e9036ba 100644 --- a/app/Console/Commands/ResetApp.php +++ b/app/Console/Commands/ResetApp.php @@ -24,7 +24,7 @@ class ResetApp extends Command * * @var string */ - protected $description = 'Clean database, database_created and public/storage folder'; + protected $description = 'Clean database and public/storage folder'; /** * Create a new command instance. diff --git a/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php b/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php index ee13d402..0be5349e 100755 --- a/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php +++ b/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php @@ -165,11 +165,11 @@ class MailConfigurationController extends Controller switch ($driver) { case 'smtp': $MailData = array_merge($MailData, [ - 'mail_host' => $mailSettings['mail_host'] ?? '', - 'mail_port' => $mailSettings['mail_port'] ?? '', - 'mail_username' => $mailSettings['mail_username'] ?? '', - 'mail_password' => $mailSettings['mail_password'] ?? '', - 'mail_encryption' => $mailSettings['mail_encryption'] ?? 'none', + 'mail_host' => $mailSettings['mail_host'] ?? config('mail.mailers.smtp.host', ''), + 'mail_port' => $mailSettings['mail_port'] ?? config('mail.mailers.smtp.port', ''), + 'mail_username' => $mailSettings['mail_username'] ?? config('mail.mailers.smtp.username', ''), + 'mail_password' => $mailSettings['mail_password'] ?? config('mail.mailers.smtp.password', ''), + 'mail_encryption' => $mailSettings['mail_encryption'] ?? config('mail.mailers.smtp.encryption', 'none'), 'mail_scheme' => $mailSettings['mail_scheme'] ?? '', 'mail_url' => $mailSettings['mail_url'] ?? '', 'mail_timeout' => $mailSettings['mail_timeout'] ?? '', diff --git a/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php b/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php index a977055e..446a1e31 100644 --- a/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php +++ b/app/Http/Controllers/V1/Installation/DatabaseConfigurationController.php @@ -48,8 +48,9 @@ class DatabaseConfigurationController extends Controller public function getDatabaseEnvironment(Request $request) { $databaseData = []; + $connection = $request->connection ?? config('database.default'); - switch ($request->connection) { + switch ($connection) { case 'sqlite': $databaseData = [ 'database_connection' => 'sqlite', diff --git a/app/Http/Controllers/V1/Installation/FinishController.php b/app/Http/Controllers/V1/Installation/FinishController.php index a7405bd2..8e7f4e1c 100644 --- a/app/Http/Controllers/V1/Installation/FinishController.php +++ b/app/Http/Controllers/V1/Installation/FinishController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers\V1\Installation; use App\Http\Controllers\Controller; -use App\Space\InstallUtils; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -16,10 +15,6 @@ class FinishController extends Controller */ public function __invoke(Request $request) { - if (! InstallUtils::createDbMarker()) { - \Log::error('Install: Unable to create db marker.'); - } - return response()->json(['success' => true]); } } diff --git a/app/Http/Controllers/V1/Installation/OnboardingWizardController.php b/app/Http/Controllers/V1/Installation/OnboardingWizardController.php index 954d86f4..7630420c 100644 --- a/app/Http/Controllers/V1/Installation/OnboardingWizardController.php +++ b/app/Http/Controllers/V1/Installation/OnboardingWizardController.php @@ -17,7 +17,7 @@ class OnboardingWizardController extends Controller */ public function getStep(Request $request) { - if (! InstallUtils::dbMarkerExists()) { + if (! InstallUtils::isDbCreated()) { return response()->json([ 'profile_complete' => 0, 'profile_language' => 'en', diff --git a/app/Http/Middleware/InstallationMiddleware.php b/app/Http/Middleware/InstallationMiddleware.php index 0386a453..d8900199 100644 --- a/app/Http/Middleware/InstallationMiddleware.php +++ b/app/Http/Middleware/InstallationMiddleware.php @@ -17,7 +17,11 @@ class InstallationMiddleware */ public function handle(Request $request, Closure $next): Response { - if (! InstallUtils::isDbCreated() || Setting::getSetting('profile_complete') !== 'COMPLETED') { + try { + if (! InstallUtils::isDbCreated() || Setting::getSetting('profile_complete') !== 'COMPLETED') { + return redirect('/installation'); + } + } catch (\Exception $e) { return redirect('/installation'); } diff --git a/app/Http/Middleware/RedirectIfInstalled.php b/app/Http/Middleware/RedirectIfInstalled.php index 0a788da4..23cad525 100644 --- a/app/Http/Middleware/RedirectIfInstalled.php +++ b/app/Http/Middleware/RedirectIfInstalled.php @@ -17,9 +17,13 @@ class RedirectIfInstalled */ public function handle(Request $request, Closure $next): Response { - if (InstallUtils::dbMarkerExists()) { - if (Setting::getSetting('profile_complete') === 'COMPLETED') { - return redirect('login'); + if (InstallUtils::isDbCreated()) { + try { + if (Setting::getSetting('profile_complete') === 'COMPLETED') { + return redirect('login'); + } + } catch (\Exception $e) { + // Settings table may not exist yet during installation } } diff --git a/app/Space/InstallUtils.php b/app/Space/InstallUtils.php index 7b2944e1..c618983a 100644 --- a/app/Space/InstallUtils.php +++ b/app/Space/InstallUtils.php @@ -5,8 +5,6 @@ namespace App\Space; use App\Models\Setting; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\File; -use Illuminate\Support\Facades\Log; -use League\Flysystem\FilesystemException; class InstallUtils { @@ -17,7 +15,7 @@ class InstallUtils */ public static function isDbCreated() { - return self::dbMarkerExists() && self::tableExists('users'); + return self::tableExists('users'); } /** @@ -44,54 +42,6 @@ class InstallUtils return $cache[$table]; } - /** - * Check if database created marker exists - * - * @return bool - */ - public static function dbMarkerExists() - { - try { - return \Storage::disk('local')->has('database_created'); - } catch (FilesystemException $e) { - Log::error('Unable to verify db marker: '.$e->getMessage()); - } - - return false; - } - - /** - * Creates the database marker - * - * @return bool - */ - public static function createDbMarker() - { - try { - return \Storage::disk('local')->put('database_created', time()); - } catch (\Exception $e) { - Log::error('Unable to create db marker: '.$e->getMessage()); - } - - return false; - } - - /** - * Deletes the database marker - * - * @return bool - */ - public static function deleteDbMarker() - { - try { - return \Storage::disk('local')->delete('database_created'); - } catch (\Exception $e) { - Log::error('Unable to delete db marker: '.$e->getMessage()); - } - - return false; - } - /** * Set the app version * diff --git a/database/seeders/DemoSeeder.php b/database/seeders/DemoSeeder.php index 6b334147..199c8446 100644 --- a/database/seeders/DemoSeeder.php +++ b/database/seeders/DemoSeeder.php @@ -8,7 +8,6 @@ use App\Models\CompanySetting; use App\Models\Customer; use App\Models\Setting; use App\Models\User; -use App\Space\InstallUtils; use Illuminate\Database\Seeder; use Silber\Bouncer\BouncerFacade; @@ -71,8 +70,5 @@ class DemoSeeder extends Seeder // Mark profile setup as complete Setting::setSetting('profile_complete', 'COMPLETED'); - - // Create installation marker - InstallUtils::createDbMarker(); } } diff --git a/package.json b/package.json index 3de6f470..c91c4fc7 100644 --- a/package.json +++ b/package.json @@ -9,56 +9,50 @@ "test": "eslint ./resources/scripts --ext .js,.vue" }, "devDependencies": { - "@rvxlab/tailwind-plugin-ios-full-height": "^1.1.0", - "@tailwindcss/aspect-ratio": "^0.4.2", "@tailwindcss/forms": "^0.5.10", "@tailwindcss/typography": "^0.5.16", - "@vitejs/plugin-vue": "^5.2.1", + "@tailwindcss/vite": "^4.0.0", + "@vitejs/plugin-vue": "^6.0.0", "@vue/compiler-sfc": "^3.5.13", - "autoprefixer": "^10.4.20", - "cross-env": "^7.0.3", "eslint": "^9.18.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-vue": "^9.32.0", - "postcss": "^8.4.49", "prettier": "^3.4.2", - "sass": "^1.83.1", - "tailwind-scrollbar": "^3.1.0", - "tailwindcss": "^3.4.17" + "tailwind-scrollbar": "^4.0.0", + "tailwindcss": "^4.0.0" }, "dependencies": { "@headlessui/vue": "^1.7.23", "@heroicons/vue": "^2.2.0", "@popperjs/core": "^2.11.8", "@stripe/stripe-js": "^2.4.0", - "@tiptap/core": "^2.11.2", - "@tiptap/extension-link": "^2.11.2", - "@tiptap/extension-text-align": "^2.11.2", - "@tiptap/pm": "^2.11.2", - "@tiptap/starter-kit": "^2.11.2", - "@tiptap/vue-3": "^2.11.2", + "@tiptap/core": "^3.0.0", + "@tiptap/extension-text-align": "^3.0.0", + "@tiptap/pm": "^3.0.0", + "@tiptap/starter-kit": "^3.0.0", + "@tiptap/vue-3": "^3.0.0", "@types/node": "^20.11.9", "@vuelidate/components": "^1.2.6", "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4", "@vueuse/core": "^12.4.0", - "axios": "0.30.0", + "axios": "1.14.0", "chart.js": "^2.9.4", "guid": "^0.0.12", - "laravel-vite-plugin": "^1.1.1", + "laravel-vite-plugin": "^3.0.0", "lodash": "^4.17.21", "maska": "^3.0.4", "mini-svg-data-uri": "^1.4.4", "moment": "^2.30.1", "path": "^0.12.7", - "pinia": "^2.3.0", + "pinia": "^3.0.0", "v-money3": "^3.24.1", "v-tooltip": "^4.0.0-beta.17", - "vite": "^6.0.7", + "vite": "^8.0.0", "vue": "^3.5", "vue-flatpickr-component": "^11.0.5", "vue-i18n": "^11.0.1", "vue-router": "^4.5.0", "vuedraggable": "^4.1.0" } -} \ No newline at end of file +} diff --git a/postcss.config.cjs b/postcss.config.cjs deleted file mode 100644 index 61bb5f95..00000000 --- a/postcss.config.cjs +++ /dev/null @@ -1,7 +0,0 @@ -// postcss.config.js -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/resources/sass/components/animation.scss b/resources/css/components/animation.css similarity index 100% rename from resources/sass/components/animation.scss rename to resources/css/components/animation.css diff --git a/resources/css/components/pace-loader.css b/resources/css/components/pace-loader.css new file mode 100644 index 00000000..0ec870df --- /dev/null +++ b/resources/css/components/pace-loader.css @@ -0,0 +1,56 @@ +.pace { + -webkit-pointer-events: none; + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.pace-inactive { + display: none; +} + +.pace .pace-progress { + background: #3f39ad; + position: fixed; + z-index: 2000; + top: 0; + right: 100%; + width: 100%; + height: 2px; +} + +.pace .pace-progress-inner { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #5851d8, 0 0 5px #5851d8; + opacity: 1; + transform: rotate(3deg) translate(0px, -4px); +} + +.pace .pace-activity { + display: block; + position: fixed; + z-index: 2000; + top: 15px; + right: 15px; + width: 14px; + height: 14px; + border: solid 2px transparent; + border-top-color: #5851d8; + border-left-color: #5851d8; + border-radius: 10px; + animation: pace-spinner 400ms linear infinite; +} + +@keyframes pace-spinner { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/resources/sass/components/v-tooltips.scss b/resources/css/components/v-tooltips.css similarity index 94% rename from resources/sass/components/v-tooltips.scss rename to resources/css/components/v-tooltips.css index 5c665e03..b6c6164b 100644 --- a/resources/sass/components/v-tooltips.scss +++ b/resources/css/components/v-tooltips.css @@ -80,18 +80,16 @@ } &.popover { - $color: #f9f9f9; - .popover-inner { - background: $color; + background: #f9f9f9; color: black; padding: 24px; border-radius: 5px; - box-shadow: 0 5px 30px rgba(black, .1); + box-shadow: 0 5px 30px rgba(0, 0, 0, 0.1); } .popover-arrow { - border-color: $color; + border-color: #f9f9f9; } } diff --git a/resources/css/invoiceshelf.css b/resources/css/invoiceshelf.css new file mode 100644 index 00000000..eb8a2b27 --- /dev/null +++ b/resources/css/invoiceshelf.css @@ -0,0 +1,98 @@ +@import "tailwindcss"; +@import "./themes.css"; +@import "./components/animation.css"; +@import "./components/pace-loader.css"; +@import "./components/v-tooltips.css"; + +@plugin "@tailwindcss/forms"; +@plugin "@tailwindcss/typography"; +@plugin "tailwind-scrollbar"; + +@source "../scripts/**/*.vue"; +@source "../scripts/**/*.js"; +@source "../../resources/views/**/*.php"; + +@theme inline { + --color-primary-50: var(--color-primary-50); + --color-primary-100: var(--color-primary-100); + --color-primary-200: var(--color-primary-200); + --color-primary-300: var(--color-primary-300); + --color-primary-400: var(--color-primary-400); + --color-primary-500: var(--color-primary-500); + --color-primary-600: var(--color-primary-600); + --color-primary-700: var(--color-primary-700); + --color-primary-800: var(--color-primary-800); + --color-primary-900: var(--color-primary-900); + --color-primary-950: var(--color-primary-950); + --color-black: #040405; +} + +@theme { + --spacing-88: 22rem; + --font-base: Poppins, sans-serif; +} + +@utility bg-multiselect-caret { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='h-5 w-5' viewBox='0 0 20 20' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z' clip-rule='evenodd'/%3E%3C/svg%3E"); +} + +@utility bg-multiselect-spinner { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' fill='%234a3dff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z'/%3E%3C/svg%3E"); +} + +@utility bg-multiselect-remove { + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='white' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z'/%3E%3C/svg%3E"); +} + +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("$fonts/Poppins-Black.ttf") format("truetype"); +} + +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url("$fonts/Poppins-Light.ttf") format("truetype"); +} + +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url("$fonts/Poppins-Medium.ttf") format("truetype"); +} + +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("$fonts/Poppins-Regular.ttf") format("truetype"); +} + +@font-face { + font-family: "Poppins"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("$fonts/Poppins-SemiBold.ttf") format("truetype"); +} + +body { + min-height: 100vh; + min-height: -webkit-fill-available; +} + +html { + height: -webkit-fill-available; +} + +.h-screen-ios { + height: -webkit-fill-available; +} diff --git a/resources/css/themes.css b/resources/css/themes.css new file mode 100644 index 00000000..e911544e --- /dev/null +++ b/resources/css/themes.css @@ -0,0 +1,13 @@ +:root { + --color-primary-50: rgb(241, 243, 255); + --color-primary-100: rgb(229, 231, 255); + --color-primary-200: rgb(206, 209, 255); + --color-primary-300: rgb(167, 170, 255); + --color-primary-400: rgb(118, 117, 255); + --color-primary-500: rgb(74, 61, 255); + --color-primary-600: rgb(51, 22, 255); + --color-primary-700: rgb(33, 4, 253); + --color-primary-800: rgb(27, 3, 211); + --color-primary-900: rgb(25, 5, 173); + --color-primary-950: rgb(9, 0, 118); +} diff --git a/resources/sass/components/pace-loader.scss b/resources/sass/components/pace-loader.scss deleted file mode 100644 index 33999964..00000000 --- a/resources/sass/components/pace-loader.scss +++ /dev/null @@ -1,112 +0,0 @@ -$pace-loader-color: #5851d8; - -.pace { - -webkit-pointer-events: none; - pointer-events: none; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} - -.pace-inactive { - display: none; -} - -.pace .pace-progress { - background: darken($pace-loader-color, 10%); - position: fixed; - z-index: 2000; - top: 0; - right: 100%; - width: 100%; - height: 2px; -} - -.pace .pace-progress-inner { - display: block; - position: absolute; - right: 0px; - width: 100px; - height: 100%; - box-shadow: 0 0 10px $pace-loader-color, 0 0 5px $pace-loader-color; - opacity: 1; - -webkit-transform: rotate(3deg) translate(0px, -4px); - -moz-transform: rotate(3deg) translate(0px, -4px); - -ms-transform: rotate(3deg) translate(0px, -4px); - -o-transform: rotate(3deg) translate(0px, -4px); - transform: rotate(3deg) translate(0px, -4px); -} - -.pace .pace-activity { - display: block; - position: fixed; - z-index: 2000; - top: 15px; - right: 15px; - width: 14px; - height: 14px; - border: solid 2px transparent; - border-top-color: $pace-loader-color; - border-left-color: $pace-loader-color; - border-radius: 10px; - -webkit-animation: pace-spinner 400ms linear infinite; - -moz-animation: pace-spinner 400ms linear infinite; - -ms-animation: pace-spinner 400ms linear infinite; - -o-animation: pace-spinner 400ms linear infinite; - animation: pace-spinner 400ms linear infinite; -} - -@-webkit-keyframes pace-spinner { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-moz-keyframes pace-spinner { - 0% { - -moz-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -moz-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-o-keyframes pace-spinner { - 0% { - -o-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -o-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@-ms-keyframes pace-spinner { - 0% { - -ms-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -ms-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@keyframes pace-spinner { - 0% { - transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - transform: rotate(360deg); - } -} diff --git a/resources/sass/invoiceshelf.scss b/resources/sass/invoiceshelf.scss deleted file mode 100644 index 52da6518..00000000 --- a/resources/sass/invoiceshelf.scss +++ /dev/null @@ -1,61 +0,0 @@ -@use "themes.scss"; -@use "components/animation.scss"; - -@tailwind base; - -@tailwind components; - -@tailwind utilities; - -@font-face { - font-family: "Poppins"; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("$fonts/Poppins-Black.ttf") format("truetype"); -} - -@font-face { - font-family: "Poppins"; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url("$fonts/Poppins-Light.ttf") format("truetype"); -} - -@font-face { - font-family: "Poppins"; - font-style: normal; - font-weight: 500; - font-display: swap; - src: url("$fonts/Poppins-Medium.ttf") format("truetype"); -} - -@font-face { - font-family: "Poppins"; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("$fonts/Poppins-Regular.ttf") format("truetype"); -} - -@font-face { - font-family: "Poppins"; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("$fonts/Poppins-SemiBold.ttf") format("truetype"); -} - -body { - min-height: 100vh; - min-height: -webkit-fill-available; -} - -html { - height: -webkit-fill-available; -} - -.h-screen-ios { - height: -webkit-fill-available; -} diff --git a/resources/sass/themes.scss b/resources/sass/themes.scss deleted file mode 100644 index 7c3e8a86..00000000 --- a/resources/sass/themes.scss +++ /dev/null @@ -1,13 +0,0 @@ -:root { - --color-primary-50: 241, 243, 255; - --color-primary-100: 229, 231, 255; - --color-primary-200: 206, 209, 255; - --color-primary-300: 167, 170, 255; - --color-primary-400: 118, 117, 255; - --color-primary-500: 74, 61, 255; - --color-primary-600: 51, 22, 255; - --color-primary-700: 33, 4, 253; - --color-primary-800: 27, 3, 211; - --color-primary-900: 25, 5, 173; - --color-primary-950: 9, 0, 118; -} diff --git a/resources/scripts/admin/components/CopyInputField.vue b/resources/scripts/admin/components/CopyInputField.vue index a4995820..1227b63f 100644 --- a/resources/scripts/admin/components/CopyInputField.vue +++ b/resources/scripts/admin/components/CopyInputField.vue @@ -6,7 +6,7 @@ px-4 py-2 rounded-lg - bg-opacity-40 bg-gray-300 + bg-gray-300/40 whitespace-nowrap flex-col mt-1 @@ -33,7 +33,7 @@ h-full inset-y-0 cursor-pointer - focus:outline-none + focus:outline-hidden text-primary-500 " width="37" diff --git a/resources/scripts/admin/components/SelectNotePopup.vue b/resources/scripts/admin/components/SelectNotePopup.vue index 822a8e2c..a435e358 100644 --- a/resources/scripts/admin/components/SelectNotePopup.vue +++ b/resources/scripts/admin/components/SelectNotePopup.vue @@ -4,14 +4,14 @@ @@ -50,7 +50,7 @@ overflow-hidden rounded-md shadow-lg - ring-1 ring-black ring-opacity-5 + ring-1 ring-black/5 " >
@@ -117,7 +117,7 @@ py-3 bg-gray-200 border-none - outline-none + outline-hidden " @click="openNoteModal" > diff --git a/resources/scripts/admin/components/currency-exchange-rate/ExchangeRateBulkUpdate.vue b/resources/scripts/admin/components/currency-exchange-rate/ExchangeRateBulkUpdate.vue index 2f058ccc..3e202640 100644 --- a/resources/scripts/admin/components/currency-exchange-rate/ExchangeRateBulkUpdate.vue +++ b/resources/scripts/admin/components/currency-exchange-rate/ExchangeRateBulkUpdate.vue @@ -58,7 +58,7 @@ justify-end mt-4 pt-4 - border-t border-gray-200 border-solid border-modal-bg + border-t border-gray-200 border-solid " > diff --git a/resources/scripts/admin/components/estimate-invoice-common/CreateItemRow.vue b/resources/scripts/admin/components/estimate-invoice-common/CreateItemRow.vue index 0b0dd4c1..f0d971c1 100644 --- a/resources/scripts/admin/components/estimate-invoice-common/CreateItemRow.vue +++ b/resources/scripts/admin/components/estimate-invoice-common/CreateItemRow.vue @@ -143,7 +143,7 @@ diff --git a/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue b/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue index 222bf6dc..53c02f79 100644 --- a/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue +++ b/resources/scripts/admin/components/estimate-invoice-common/CreateItemRowTax.vue @@ -42,7 +42,7 @@