diff --git a/.env.testing b/.env.testing new file mode 100644 index 0000000..15fdfe4 --- /dev/null +++ b/.env.testing @@ -0,0 +1,8 @@ +DB_DATABASE=testing +DB_HOST=127.0.0.1 +DB_CONNECTION=mysql +DB_USERNAME=root +DB_PASSWORD=password +APP_KEY=base64:JzqP44/5fNz4B9cqzDtE6ktvlUmv9q9U0I2o4FjRtUY= +APP_ENV=testing +APP_DEBUG=true diff --git a/app/Console/Commands/BadgesPrintCommand.php b/app/Console/Commands/BadgesPrintCommand.php new file mode 100644 index 0000000..3403357 --- /dev/null +++ b/app/Console/Commands/BadgesPrintCommand.php @@ -0,0 +1,23 @@ +update([ + 'status' => Printed::$name, + 'printed_at' => now(), + ]); + } +} diff --git a/app/Console/Commands/BadgesUnprintCommand.php b/app/Console/Commands/BadgesUnprintCommand.php new file mode 100644 index 0000000..6897308 --- /dev/null +++ b/app/Console/Commands/BadgesUnprintCommand.php @@ -0,0 +1,23 @@ +update([ + 'status' => Pending::$name, + 'printed_at' => null, + ]); + } +} diff --git a/app/Console/Commands/CreateOrUpdateEventForStateCommand.php b/app/Console/Commands/CreateOrUpdateEventForStateCommand.php new file mode 100644 index 0000000..6ad9329 --- /dev/null +++ b/app/Console/Commands/CreateOrUpdateEventForStateCommand.php @@ -0,0 +1,72 @@ +environment(['local', 'testing'])) { + $this->error('This command can only be run in local or testing environments.'); + return; + } + + $state = $this->argument('state'); + $event = Event::first(); + + $fromInput = EventStateEnum::tryFrom($state); + + switch ($fromInput) { + case EventStateEnum::COUNTDOWN: + $this->createOrUpdateEvent($event, now()->addDays(11), now()->addDays(20), now()->addDays(21), now()->addDays(30)); + break; + case EventStateEnum::PREORDER: + $this->createOrUpdateEvent($event, now()->subDays(1), now()->subDays(10), now()->addDays(11), now()->addDays(20)); + break; + case EventStateEnum::LATE: + $this->createOrUpdateEvent($event, now()->subDays(20), now()->subDays(10), now()->subDays(9), now()->addDays(10)); + break; + case EventStateEnum::CLOSED: + $this->createOrUpdateEvent($event, now()->subDays(30), now()->subDays(20), now()->subDays(19), now()->subDays(1)); + break; + default: + $this->error('Invalid state provided.'); + return; + } + + $this->info("Event has been created or updated to match the '$state' state."); + } + + private function createOrUpdateEvent($event, $startsAt, $preorderStartsAt, $preorderEndsAt, $orderEndsAt) + { + if ($event) { + $event->update([ + 'starts_at' => $startsAt, + 'preorder_starts_at' => $preorderStartsAt, + 'preorder_ends_at' => $preorderEndsAt, + 'order_ends_at' => $orderEndsAt, + ]); + } else { + Event::create([ + 'starts_at' => $startsAt, + 'preorder_starts_at' => $preorderStartsAt, + 'preorder_ends_at' => $preorderEndsAt, + 'order_ends_at' => $orderEndsAt, + ]); + } + } +} diff --git a/app/Http/Controllers/BadgeController.php b/app/Http/Controllers/BadgeController.php index 170b108..fc86dda 100644 --- a/app/Http/Controllers/BadgeController.php +++ b/app/Http/Controllers/BadgeController.php @@ -24,12 +24,13 @@ public function index(Request $request) { return Inertia::render('Badges/BadgesIndex', [ 'badges' => auth()->user()->badges()->with('fursuit.species')->get(), + 'canCreate' => Gate::allows('create', Badge::class), ]); } public function create(Request $request) { - $request->user()->can('create', Badge::class); + Gate::authorize('create', Badge::class); return Inertia::render('Badges/BadgesCreate', [ 'species' => Species::has('fursuits', count: 5)->orWhere('checked', true)->get('name'), 'isFree' => auth()->user()->badges()->where('is_free_badge', true)->doesntExist(), @@ -38,7 +39,7 @@ public function create(Request $request) public function store(BadgeCreateRequest $request) { - $request->user()->can('create', Badge::class); + Gate::authorize('create', Badge::class); $badge = DB::transaction(function () use ($request) { // Lock Wallet Balance $request->user()->balanceInt; @@ -130,6 +131,7 @@ public function edit(Badge $badge, Request $request) public function update(BadgeUpdateRequest $request, Badge $badge) { + Gate::authorize('update', $badge); $badge = DB::transaction(function () use ($request, $badge) { $request->user()->can('update', $badge); // Lock Wallet Balance diff --git a/app/Models/Badge/Badge.php b/app/Models/Badge/Badge.php index 9ea6d21..25914c5 100644 --- a/app/Models/Badge/Badge.php +++ b/app/Models/Badge/Badge.php @@ -8,6 +8,7 @@ use Bavix\Wallet\Interfaces\Customer; use Bavix\Wallet\Interfaces\ProductInterface; use Bavix\Wallet\Traits\HasWalletFloat; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; @@ -17,7 +18,7 @@ class Badge extends Model implements ProductInterface { - use HasStates, SoftDeletes, HasWalletFloat, LogsActivity; + use HasStates, SoftDeletes, HasWalletFloat, LogsActivity, HasFactory; protected $guarded = []; protected $casts = [ diff --git a/app/Models/Fursuit/Fursuit.php b/app/Models/Fursuit/Fursuit.php index d141811..3f9e763 100644 --- a/app/Models/Fursuit/Fursuit.php +++ b/app/Models/Fursuit/Fursuit.php @@ -8,6 +8,7 @@ use App\Models\Species; use App\Models\User; use Illuminate\Database\Eloquent\Casts\Attribute; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Facades\Storage; @@ -17,7 +18,7 @@ class Fursuit extends Model { - use HasStates, LogsActivity; + use HasStates, LogsActivity, HasFactory; protected $guarded = []; protected $casts = [ diff --git a/app/Models/Species.php b/app/Models/Species.php index 27f758a..7b70f59 100644 --- a/app/Models/Species.php +++ b/app/Models/Species.php @@ -3,10 +3,12 @@ namespace App\Models; use App\Models\Fursuit\Fursuit; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Species extends Model { + use HasFactory; protected $guarded = []; public function fursuits() diff --git a/app/Policies/BadgePolicy.php b/app/Policies/BadgePolicy.php index 3ee3cd9..69ebfbf 100644 --- a/app/Policies/BadgePolicy.php +++ b/app/Policies/BadgePolicy.php @@ -2,9 +2,12 @@ namespace App\Policies; +use App\Enum\EventStateEnum; use App\Models\Badge\Badge; +use App\Models\Badge\States\Pending; use App\Models\User; use Illuminate\Auth\Access\HandlesAuthorization; +use Illuminate\Routing\Route; class BadgePolicy { @@ -12,12 +15,12 @@ class BadgePolicy public function viewAny(User $user): bool { - return $user->is_admin; + return $user->is_admin && request()->routeIs('filament.*'); } public function view(User $user, Badge $badge): bool { - if ($user->is_admin) { + if ($user->is_admin && request()->routeIs('filament.*')) { return true; } return $user->id === $badge->fursuit->user_id; @@ -30,11 +33,17 @@ public function create(User $user): bool if ($event === null) { return false; } - if($event->order_ends_at !== null) { - if($event->order_ends_at->isPast()) { - return false; - } + + // Admin can override + if ($user->is_admin && request()->routeIs('filament.*')) { + return true; + } + + // Safety check if in CLOSED OR LATE return false + if ($event->state === \App\Enum\EventStateEnum::CLOSED || $event->state === \App\Enum\EventStateEnum::COUNTDOWN) { + return false; } + return true; } @@ -45,32 +54,16 @@ public function update(User $user, Badge $badge): bool if ($badge->extra_copy_of !== null) { return false; } - // Admin can do everything - if ($user->is_admin) { - return true; - } - // Cannot edit when no active event - if ($event === null) { - return false; - } - // Cannot edit a badge that has already been printed - if ($badge->printed_at !== null) { - return false; - } - // Safety check - if($event->order_ends_at !== null) { - if($event->order_ends_at->isPast()) { - return false; - } - } - return $user->id === $badge->fursuit->user_id; + return $this->delete($user, $badge); } public function delete(User $user, Badge $badge): bool { $event = \App\Models\Event::getActiveEvent(); + // Admin can do everything IN FILAMENT + // Admin can do everything - if ($user->is_admin) { + if ($user->is_admin && request()->routeIs('filament.*')) { return true; } // Cannot edit when no active event @@ -78,25 +71,25 @@ public function delete(User $user, Badge $badge): bool return false; } // Cannot edit a badge that has already been printed - if ($badge->printed_at !== null) { + if ((string) $badge->status !== Pending::$name) { return false; } - // Safety check - if($event->order_ends_at !== null) { - if($event->order_ends_at->isPast()) { - return false; - } + + // Safety check if in CLOSED OR LATE return false + if ($event->state === \App\Enum\EventStateEnum::CLOSED || $event->state === \App\Enum\EventStateEnum::COUNTDOWN) { + return false; } + return $user->id === $badge->fursuit->user_id; } public function restore(User $user, Badge $badge): bool { - return $user->is_admin; + return $user->is_admin && request()->routeIs('filament.*'); } public function forceDelete(User $user, Badge $badge): bool { - return $user->is_admin; + return $user->is_admin && request()->routeIs('filament.*'); } } diff --git a/database/factories/Badge/BadgeFactory.php b/database/factories/Badge/BadgeFactory.php new file mode 100644 index 0000000..a8b38ba --- /dev/null +++ b/database/factories/Badge/BadgeFactory.php @@ -0,0 +1,43 @@ + $this->faker->boolean(), + 'extra_copy_of' => null, + 'status' => $this->faker->randomElement([ + Pending::$name, + Printed::$name, + ReadyForPickup::$name, + PickedUp::$name + ]), + 'dual_side_print' => $this->faker->boolean(), + 'extra_copy' => $this->faker->boolean(), + 'apply_late_fee' => $this->faker->boolean(), + 'subtotal' => $this->faker->randomNumber(), + 'tax_rate' => 19, + 'tax' => $this->faker->randomNumber(), + 'total' => $this->faker->randomNumber(), + 'printed_at' => Carbon::now(), + 'pickup_location' => $this->faker->word(), + 'ready_for_pickup_at' => Carbon::now(), + 'picked_up_at' => Carbon::now(), + 'fursuit_id' => Fursuit::factory(), + ]; + } +} diff --git a/database/factories/Fursuit/FursuitFactory.php b/database/factories/Fursuit/FursuitFactory.php new file mode 100644 index 0000000..3f418bd --- /dev/null +++ b/database/factories/Fursuit/FursuitFactory.php @@ -0,0 +1,35 @@ + $this->faker->randomElement([ + Pending::$name, + Approved::$name, + Rejected::$name + ]), + 'name' => $this->faker->name(), + 'image' => $this->faker->filePath(), + 'published' => $this->faker->boolean(), + 'catch_em_all' => $this->faker->boolean(), + 'user_id' => User::factory(), + 'species_id' => Species::factory(), + 'event_id' => Event::factory(), + ]; + } +} diff --git a/database/factories/SpeciesFactory.php b/database/factories/SpeciesFactory.php new file mode 100644 index 0000000..c348d3d --- /dev/null +++ b/database/factories/SpeciesFactory.php @@ -0,0 +1,21 @@ + $this->faker->name(), + 'type' => $this->faker->word(), + 'checked' => false, + ]; + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 584104c..0946960 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -24,11 +24,11 @@ class UserFactory extends Factory public function definition(): array { return [ - 'name' => fake()->name(), - 'email' => fake()->unique()->safeEmail(), - 'email_verified_at' => now(), - 'password' => static::$password ??= Hash::make('password'), - 'remember_token' => Str::random(10), + 'remote_id' => $this->faker->unique()->randomNumber(), + 'name' => $this->faker->name, + 'email' => $this->faker->unique()->safeEmail, + 'is_admin' => false, + 'is_reviewer' => false, ]; } diff --git a/database/schema/mysql-schema.sql b/database/schema/mysql-schema.sql new file mode 100644 index 0000000..ac3c6d9 --- /dev/null +++ b/database/schema/mysql-schema.sql @@ -0,0 +1,346 @@ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `activity_log`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `activity_log` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `log_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `description` text COLLATE utf8mb4_unicode_ci NOT NULL, + `subject_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `event` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `subject_id` bigint unsigned DEFAULT NULL, + `causer_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `causer_id` bigint unsigned DEFAULT NULL, + `properties` json DEFAULT NULL, + `batch_uuid` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `subject` (`subject_type`,`subject_id`), + KEY `causer` (`causer_type`,`causer_id`), + KEY `activity_log_log_name_index` (`log_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `badges`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `badges` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `fursuit_id` bigint unsigned NOT NULL, + `is_free_badge` tinyint(1) NOT NULL DEFAULT '0', + `extra_copy_of` bigint unsigned DEFAULT NULL, + `status` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `dual_side_print` tinyint(1) NOT NULL DEFAULT '0', + `extra_copy` tinyint(1) NOT NULL DEFAULT '0', + `apply_late_fee` tinyint(1) NOT NULL, + `subtotal` bigint unsigned NOT NULL DEFAULT '0', + `tax_rate` decimal(8,2) NOT NULL DEFAULT '0.00', + `tax` bigint unsigned NOT NULL DEFAULT '0', + `total` bigint unsigned NOT NULL DEFAULT '0', + `printed_at` datetime DEFAULT NULL, + `pickup_location` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `ready_for_pickup_at` datetime DEFAULT NULL, + `picked_up_at` datetime DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `badges_fursuit_id_foreign` (`fursuit_id`), + KEY `badges_extra_copy_of_foreign` (`extra_copy_of`), + CONSTRAINT `badges_extra_copy_of_foreign` FOREIGN KEY (`extra_copy_of`) REFERENCES `badges` (`id`) ON DELETE CASCADE, + CONSTRAINT `badges_fursuit_id_foreign` FOREIGN KEY (`fursuit_id`) REFERENCES `fursuits` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `cache`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `cache` ( + `key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `value` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, + `expiration` int NOT NULL, + PRIMARY KEY (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `cache_locks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `cache_locks` ( + `key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `owner` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `expiration` int NOT NULL, + PRIMARY KEY (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `events`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `events` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `starts_at` date NOT NULL, + `ends_at` date NOT NULL, + `preorder_starts_at` datetime DEFAULT NULL, + `preorder_ends_at` datetime NOT NULL, + `order_ends_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `failed_jobs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `failed_jobs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `connection` text COLLATE utf8mb4_unicode_ci NOT NULL, + `queue` text COLLATE utf8mb4_unicode_ci NOT NULL, + `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `fursuits`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `fursuits` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint unsigned NOT NULL, + `species_id` bigint unsigned NOT NULL, + `event_id` bigint unsigned NOT NULL, + `status` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `image` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `published` tinyint(1) NOT NULL DEFAULT '0', + `catch_em_all` tinyint(1) NOT NULL DEFAULT '0', + `approved_at` timestamp NULL DEFAULT NULL, + `rejected_at` timestamp NULL DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `fursuits_user_id_foreign` (`user_id`), + KEY `fursuits_species_id_foreign` (`species_id`), + KEY `fursuits_event_id_foreign` (`event_id`), + CONSTRAINT `fursuits_event_id_foreign` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`) ON DELETE CASCADE, + CONSTRAINT `fursuits_species_id_foreign` FOREIGN KEY (`species_id`) REFERENCES `species` (`id`) ON DELETE CASCADE, + CONSTRAINT `fursuits_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `job_batches`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `job_batches` ( + `id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `total_jobs` int NOT NULL, + `pending_jobs` int NOT NULL, + `failed_jobs` int NOT NULL, + `failed_job_ids` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `options` mediumtext COLLATE utf8mb4_unicode_ci, + `cancelled_at` int DEFAULT NULL, + `created_at` int NOT NULL, + `finished_at` int DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `jobs`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `jobs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `queue` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `attempts` tinyint unsigned NOT NULL, + `reserved_at` int unsigned DEFAULT NULL, + `available_at` int unsigned NOT NULL, + `created_at` int unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `jobs_queue_index` (`queue`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `migrations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `migrations` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `batch` int NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `sessions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `sessions` ( + `id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `user_id` bigint unsigned DEFAULT NULL, + `ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `user_agent` text COLLATE utf8mb4_unicode_ci, + `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `last_activity` int NOT NULL, + PRIMARY KEY (`id`), + KEY `sessions_user_id_index` (`user_id`), + KEY `sessions_last_activity_index` (`last_activity`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `species`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `species` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `checked` tinyint(1) NOT NULL DEFAULT '0', + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `species_name_unique` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `transactions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transactions` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `payable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `payable_id` bigint unsigned NOT NULL, + `wallet_id` bigint unsigned NOT NULL, + `type` enum('deposit','withdraw') COLLATE utf8mb4_unicode_ci NOT NULL, + `amount` decimal(64,0) NOT NULL, + `confirmed` tinyint(1) NOT NULL, + `meta` json DEFAULT NULL, + `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `transactions_uuid_unique` (`uuid`), + KEY `transactions_payable_type_payable_id_index` (`payable_type`,`payable_id`), + KEY `payable_type_payable_id_ind` (`payable_type`,`payable_id`), + KEY `payable_type_ind` (`payable_type`,`payable_id`,`type`), + KEY `payable_confirmed_ind` (`payable_type`,`payable_id`,`confirmed`), + KEY `payable_type_confirmed_ind` (`payable_type`,`payable_id`,`type`,`confirmed`), + KEY `transactions_type_index` (`type`), + KEY `transactions_wallet_id_foreign` (`wallet_id`), + CONSTRAINT `transactions_wallet_id_foreign` FOREIGN KEY (`wallet_id`) REFERENCES `wallets` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `transfers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `transfers` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `from_id` bigint unsigned NOT NULL, + `to_id` bigint unsigned NOT NULL, + `status` enum('exchange','transfer','paid','refund','gift') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'transfer', + `status_last` enum('exchange','transfer','paid','refund','gift') COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `deposit_id` bigint unsigned NOT NULL, + `withdraw_id` bigint unsigned NOT NULL, + `discount` decimal(64,0) NOT NULL DEFAULT '0', + `fee` decimal(64,0) NOT NULL DEFAULT '0', + `extra` json DEFAULT NULL, + `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `transfers_uuid_unique` (`uuid`), + KEY `transfers_deposit_id_foreign` (`deposit_id`), + KEY `transfers_withdraw_id_foreign` (`withdraw_id`), + KEY `transfers_from_id_index` (`from_id`), + KEY `transfers_to_id_index` (`to_id`), + CONSTRAINT `transfers_deposit_id_foreign` FOREIGN KEY (`deposit_id`) REFERENCES `transactions` (`id`) ON DELETE CASCADE, + CONSTRAINT `transfers_withdraw_id_foreign` FOREIGN KEY (`withdraw_id`) REFERENCES `transactions` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `users` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `remote_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `valid_registration` tinyint(1) DEFAULT NULL, + `token` text COLLATE utf8mb4_unicode_ci, + `token_expires_at` datetime DEFAULT NULL, + `refresh_token` text COLLATE utf8mb4_unicode_ci, + `refresh_token_expires_at` datetime DEFAULT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `avatar` text COLLATE utf8mb4_unicode_ci, + `is_admin` tinyint(1) NOT NULL DEFAULT '0', + `is_reviewer` tinyint(1) NOT NULL DEFAULT '0', + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `users_remote_id_unique` (`remote_id`), + UNIQUE KEY `users_email_unique` (`email`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `wallets`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `wallets` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `holder_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `holder_id` bigint unsigned NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `slug` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `meta` json DEFAULT NULL, + `balance` decimal(64,0) NOT NULL DEFAULT '0', + `decimal_places` smallint unsigned NOT NULL DEFAULT '2', + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `wallets_holder_type_holder_id_slug_unique` (`holder_type`,`holder_id`,`slug`), + UNIQUE KEY `wallets_uuid_unique` (`uuid`), + KEY `wallets_holder_type_holder_id_index` (`holder_type`,`holder_id`), + KEY `wallets_slug_index` (`slug`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'0001_01_01_000000_create_users_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'0001_01_01_000001_create_cache_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'0001_01_01_000002_create_jobs_table',1); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (4,'2024_06_08_213624_create_events_table',2); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (5,'2024_06_08_221234_create_species_table',3); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (6,'2024_06_08_221534_create_fursuits_table',3); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (7,'2024_06_08_221822_create_badges_table',3); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (8,'2024_06_09_004429_add_unique_name_to_species',4); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (9,'2024_06_09_005032_add_checked_to_species_table',5); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (10,'2024_07_07_220238_add_published_to_fursuits_table',6); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (11,'2024_07_07_232654_add_columns_for_upgrades_to_badges_table',7); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (12,'2024_07_07_233059_add_catch_em_all_after_published_in_fursuits_table',8); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (13,'2024_07_08_003055_add_extra_copy_of_to_badges_table',9); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (14,'2024_07_13_235615_add_is_free_bade_to_badges_table',10); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (15,'2024_07_14_002551_add_all_order_ends_at_to_events_table',11); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (16,'2024_07_14_002810_add_printed_at_to_badges_after_total',12); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (17,'2024_07_14_003146_add_trashed_at_to_badges_table',13); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (18,'2018_11_06_222923_create_transactions_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (19,'2018_11_07_192923_create_transfers_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (20,'2018_11_15_124230_create_wallets_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (21,'2021_11_02_202021_update_wallets_uuid_table',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (22,'2023_12_30_113122_extra_columns_removed',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (23,'2023_12_30_204610_soft_delete',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (24,'2024_01_24_185401_add_extra_column_in_transfer',14); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (25,'2024_07_14_031820_add_token_and_refresh_token_to_users_table',15); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (26,'2024_07_14_034000_add_regstatus_to_users_table',16); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (27,'2024_07_14_035415_add_late_fee_to_badges_table',17); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (28,'2024_07_14_042655_add_is_reviewer_to_users_table',18); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (29,'2024_07_14_063958_create_activity_log_table',19); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (30,'2024_07_14_063959_add_event_column_to_activity_log_table',19); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (31,'2024_07_14_064000_add_batch_uuid_column_to_activity_log_table',19); +INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (32,'2024_07_18_034822_add_preorder_starts_at_to_events_table',20); diff --git a/lang/en/validation.php b/lang/en/validation.php new file mode 100644 index 0000000..165c9f0 --- /dev/null +++ b/lang/en/validation.php @@ -0,0 +1,8 @@ + [ + 'tos' => [ + 'accepted' => 'Please confirm your information.', + ], + ] +]; diff --git a/resources/js/Components/BadgeCreator/ImageUpload.vue b/resources/js/Components/BadgeCreator/ImageUpload.vue index a811fbb..7e3e442 100644 --- a/resources/js/Components/BadgeCreator/ImageUpload.vue +++ b/resources/js/Components/BadgeCreator/ImageUpload.vue @@ -5,20 +5,27 @@ import {Cropper} from 'vue-advanced-cropper' import 'vue-advanced-cropper/dist/style.css'; import pica from 'pica'; import Button from 'primevue/button'; +import InlineMessage from "primevue/inlinemessage"; -const image = reactive({ - src: null, - type: null, +const props = defineProps({ + imageSource: { + type: Object, + default: { + src: null, + type: null, + } + } }); +const image = reactive(props.imageSource); + const croppedImage = ref(null); const rawBlob = ref(null); const picaInstance = pica(); -const emits = defineEmits(['updateImage']) +const emits = defineEmits(['updateImage', 'updateSource']) const onSelectFile = (event) => { - console.log(event); // Reference to the DOM input element const {files} = event; // Ensure that you have a file before attempting to read it @@ -30,12 +37,24 @@ const onSelectFile = (event) => { // 2. Create the blob link to the file to optimize performance: image.src = URL.createObjectURL(files[0]); image.type = files[0].type; + emits('updateSource', { + src: image.src, + type: image.type + }); } } const onChangeCrop = (event) => { const {coordinates, canvas} = event; - coordinates.value = coordinates; + // Save coordinates to img + image.coordinates = { + left: coordinates.left, + top: coordinates.top, + }; + image.size = { + width: coordinates.width, + height: coordinates.height, + }; // Resize using pica picaInstance.toBlob(canvas, image.type) .then(blob => { @@ -51,17 +70,25 @@ const onChangeCrop = (event) => { }); } +function confirmImage() { + emits('updateImage',{ + croppedImage: croppedImage.value, + type: image.type, + blob: rawBlob.value, + }); + emits('updateSource', image); +} + diff --git a/resources/js/Layouts/Layout.vue b/resources/js/Layouts/Layout.vue index 0458310..b8c8613 100644 --- a/resources/js/Layouts/Layout.vue +++ b/resources/js/Layouts/Layout.vue @@ -3,6 +3,7 @@ import {Link, usePage} from '@inertiajs/vue3'; import dayjs from "dayjs"; import Button from "primevue/button"; import {formatEuroFromCents} from "../helpers.js"; + const page = usePage().props; @@ -10,30 +11,33 @@ const page = usePage().props;
- -
- - -
-
- -
- Fursuit Badge Registration +
+
+ + + +
+
+ +
+ Fursuit Badge Registration +
-
+
- +
- +
diff --git a/resources/js/Pages/Badges/BadgesCreate.vue b/resources/js/Pages/Badges/BadgesCreate.vue index d855a68..5e904ec 100644 --- a/resources/js/Pages/Badges/BadgesCreate.vue +++ b/resources/js/Pages/Badges/BadgesCreate.vue @@ -27,6 +27,7 @@ const props = defineProps({ const imageModalOpen = ref(false) const previewImage = ref(null); +const imageSource = reactive({}); const form = useForm('post', route('badges.store'), { species: null, @@ -87,7 +88,7 @@ const total = computed(() => { :style="{ width: '25rem' }"> Please upload a picture, you can crop the image after you uploaded it. - +
@@ -124,7 +125,7 @@ const total = computed(() => {
Only jpg/png
Min 240x340px
-
Max 2MB (after crop)
+
Max 8 MB
diff --git a/resources/js/Pages/Badges/BadgesEdit.vue b/resources/js/Pages/Badges/BadgesEdit.vue index eda37c2..aff3ea0 100644 --- a/resources/js/Pages/Badges/BadgesEdit.vue +++ b/resources/js/Pages/Badges/BadgesEdit.vue @@ -44,6 +44,7 @@ const props = defineProps({ const imageModalOpen = ref(false) const previewImage = ref(null); +const imageSource = reactive({}); const form = useForm('post', route('badges.update',{badge: props.badge.id}), { _method: 'put', @@ -115,7 +116,7 @@ function openImageModal() { :style="{ width: '25rem' }"> Please upload a picture, you can crop the image after you uploaded it. - + @@ -29,6 +30,7 @@ const props = defineProps({