Deploy Ladill Transfer / deploy (push) Successful in 26s
Add shared btn-primary components and plus icons on create/new actions; limit overview recent transfers to three. Co-authored-by: Cursor <cursoragent@cursor.com>
98 lines
6.5 KiB
PHP
98 lines
6.5 KiB
PHP
@extends('layouts.email')
|
|
@section('title', 'New mailbox — Ladill Email')
|
|
@section('content')
|
|
<div class="mx-auto max-w-lg">
|
|
<h1 class="text-xl font-semibold tracking-tight text-slate-900">Create a mailbox</h1>
|
|
@if(empty($domains))
|
|
<div class="mt-6 rounded-2xl border border-amber-200 bg-amber-50 p-6 text-sm text-amber-800">
|
|
You need a <strong>verified domain</strong> first. <a href="{{ route('email.domains.index') }}" class="font-semibold underline">Set up a domain</a>.
|
|
</div>
|
|
@else
|
|
@php $fmt = fn ($m) => $quota['currency'].' '.number_format($m / 100, 2); @endphp
|
|
<div x-data="{
|
|
tiers: @js($quota['tiers']),
|
|
sel: {{ $quota['default_mb'] }},
|
|
balance: {{ $walletBalanceMinor }},
|
|
get tier() { return this.tiers.find(t => t.mb == this.sel) || this.tiers[0]; },
|
|
get price() { return this.tier.price_minor; },
|
|
get free() { return this.price === 0; },
|
|
fmt(m) { return '{{ $quota['currency'] }} ' + (m / 100).toFixed(2); },
|
|
}">
|
|
{{-- Pricing banner (reacts to the selected storage plan) --}}
|
|
<template x-if="!free">
|
|
<div class="mt-5 rounded-2xl border border-indigo-200 bg-indigo-50 px-4 py-3 text-sm text-indigo-800">
|
|
This plan is <strong><span x-text="fmt(price)"></span>/month</strong>, charged from your Ladill wallet
|
|
(balance: <span x-text="fmt(balance)"></span>).
|
|
<a href="{{ $topupUrl }}" class="font-semibold underline" x-show="balance < price" x-cloak>Top up</a>
|
|
</div>
|
|
</template>
|
|
<template x-if="free">
|
|
<div class="mt-5 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-800">
|
|
The <strong>1 GB</strong> plan is <strong>free, forever</strong>. You can upgrade for more storage anytime.
|
|
</div>
|
|
</template>
|
|
|
|
<form method="POST" action="{{ route('email.mailboxes.store') }}" class="mt-4 space-y-4 rounded-2xl border border-slate-200 bg-white p-6">
|
|
@csrf
|
|
<div>
|
|
<label class="block text-xs font-medium text-slate-600">Domain</label>
|
|
<select name="email_domain_id" class="mt-1 w-full rounded-xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none">
|
|
@foreach($domains as $d)<option value="{{ $d['id'] }}">{{ $d['domain'] }}</option>@endforeach
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-medium text-slate-600">Mailbox name</label>
|
|
<input name="local_part" required value="{{ old('local_part') }}" placeholder="you"
|
|
class="mt-1 w-full rounded-xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none">
|
|
@error('local_part')<p class="mt-1 text-xs text-rose-600">{{ $message }}</p>@enderror
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-medium text-slate-600">Display name</label>
|
|
<input name="display_name" required value="{{ old('display_name') }}" placeholder="Your Name"
|
|
class="mt-1 w-full rounded-xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none">
|
|
</div>
|
|
|
|
{{-- Storage plan (sets quota + price) --}}
|
|
<div>
|
|
<label class="block text-xs font-medium text-slate-600">Storage plan</label>
|
|
<div class="mt-1.5 grid grid-cols-1 gap-2">
|
|
@foreach($quota['tiers'] as $t)
|
|
<label class="flex cursor-pointer items-center justify-between rounded-xl border bg-slate-50 px-3.5 py-2.5 text-sm transition"
|
|
:class="sel == {{ $t['mb'] }} ? 'border-indigo-400 bg-indigo-50 ring-1 ring-indigo-200' : 'border-slate-200 hover:bg-slate-100'">
|
|
<span class="flex items-center gap-2.5">
|
|
<input type="radio" name="quota_mb" value="{{ $t['mb'] }}" x-model.number="sel" class="text-indigo-600 focus:ring-indigo-500">
|
|
<span class="font-medium text-slate-800">{{ $t['label'] }}</span>
|
|
</span>
|
|
@if($t['price_minor'] === 0)
|
|
<span class="font-semibold text-emerald-600">Free</span>
|
|
@else
|
|
<span class="text-slate-500">{{ $fmt($t['price_minor']) }}<span class="text-xs">/mo</span></span>
|
|
@endif
|
|
</label>
|
|
@endforeach
|
|
</div>
|
|
@error('quota_mb')<p class="mt-1 text-xs text-rose-600">{{ $message }}</p>@enderror
|
|
</div>
|
|
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<div>
|
|
<label class="block text-xs font-medium text-slate-600">Password</label>
|
|
<input type="password" name="password" required class="mt-1 w-full rounded-xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-medium text-slate-600">Confirm</label>
|
|
<input type="password" name="password_confirmation" required class="mt-1 w-full rounded-xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm focus:border-indigo-300 focus:bg-white focus:outline-none">
|
|
</div>
|
|
</div>
|
|
@error('password')<p class="text-xs text-rose-600">{{ $message }}</p>@enderror
|
|
|
|
<button class="btn-primary w-full btn-primary-lg">
|
|
<svg class="h-4 w-4 shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
|
<span x-text="free ? 'Create free mailbox' : ('Create mailbox — ' + fmt(price) + '/mo')">Create mailbox</span>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endsection
|