diff --git a/src/app/Http/Controllers/API/SignupController.php b/src/app/Http/Controllers/API/SignupController.php --- a/src/app/Http/Controllers/API/SignupController.php +++ b/src/app/Http/Controllers/API/SignupController.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Controller; use App\Jobs\SignupVerificationEmail; use App\Jobs\SignupVerificationSMS; +use App\Discount; use App\Domain; use App\Plan; use App\Rules\ExternalEmail; @@ -40,7 +41,8 @@ { $plans = []; - Plan::all()->map(function ($plan) use (&$plans) { + // Use reverse order just to have individual on left, group on right ;) + Plan::select()->orderByDesc('title')->get()->map(function ($plan) use (&$plans) { $plans[] = [ 'title' => $plan->title, 'name' => $plan->name, @@ -71,6 +73,7 @@ 'email' => 'required', 'name' => 'required|max:512', 'plan' => 'nullable|alpha_num|max:128', + 'voucher' => 'max:32', ] ); @@ -89,6 +92,7 @@ 'email' => $request->email, 'name' => $request->name, 'plan' => $request->plan, + 'voucher' => $request->voucher, ] ]); @@ -142,12 +146,13 @@ $has_domain = $this->getPlan()->hasDomain(); - // Return user name and email/phone from the codes database, + // Return user name and email/phone/voucher from the codes database, // domains list for selection and "plan type" flag return response()->json([ 'status' => 'success', 'email' => $code->data['email'], 'name' => $code->data['name'], + 'voucher' => $code->data['voucher'], 'is_domain' => $has_domain, 'domains' => $has_domain ? [] : Domain::getPublicDomains(), ]); @@ -169,6 +174,7 @@ 'login' => 'required|min:2', 'password' => 'required|min:4|confirmed', 'domain' => 'required', + 'voucher' => 'max:32', ] ); @@ -182,6 +188,17 @@ return $v; } + // Find the voucher discount + if ($request->voucher) { + $discount = Discount::where('code', \strtoupper($request->voucher)) + ->where('active', true)->first(); + + if (!$discount) { + $errors = ['voucher' => \trans('validation.voucherinvalid')]; + return response()->json(['status' => 'error', 'errors' => $errors], 422); + } + } + // Get the plan $plan = $this->getPlan(); $is_domain = $plan->hasDomain(); @@ -222,6 +239,12 @@ ]); } + if (!empty($discount)) { + $wallet = $user->wallets()->first(); + $wallet->discount()->associate($discount); + $wallet->save(); + } + $user->assignPlan($plan, $domain); // Save the external email and plan in user settings diff --git a/src/resources/js/routes-user.js b/src/resources/js/routes-user.js --- a/src/resources/js/routes-user.js +++ b/src/resources/js/routes-user.js @@ -71,6 +71,7 @@ }, { path: '/signup/:param?', + alias: '/signup/voucher/:param', name: 'signup', component: SignupComponent }, diff --git a/src/resources/lang/en/validation.php b/src/resources/lang/en/validation.php --- a/src/resources/lang/en/validation.php +++ b/src/resources/lang/en/validation.php @@ -129,6 +129,7 @@ 'packageinvalid' => 'Invalid package selected.', 'packagerequired' => 'Package is required.', 'usernotexists' => 'Unable to find user.', + 'voucherinvalid' => 'The voucher code is invalid or expired.', 'noextemail' => 'This user has no external email address.', 'entryinvalid' => 'The specified :attribute is invalid.', 'entryexists' => 'The specified :attribute is not available.', diff --git a/src/resources/sass/app.scss b/src/resources/sass/app.scss --- a/src/resources/sass/app.scss +++ b/src/resources/sass/app.scss @@ -200,3 +200,19 @@ height: 6rem; } } + +.plan-selector { + .plan-ico { + width: 100px; + font-size: 4em; + color: #f1a539; + border: 3px solid #f1a539; + width: 100px; + margin-bottom: 1rem; + border-radius: 50%; + } + + ul:last-child { + margin-bottom: 0; + } +} diff --git a/src/resources/vue/Signup.vue b/src/resources/vue/Signup.vue --- a/src/resources/vue/Signup.vue +++ b/src/resources/vue/Signup.vue @@ -1,7 +1,15 @@