Skip to content

Commit

Permalink
component fun
Browse files Browse the repository at this point in the history
  • Loading branch information
mortenebak committed Nov 1, 2024
1 parent 4528f07 commit ab0e6cc
Show file tree
Hide file tree
Showing 24 changed files with 440 additions and 244 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ php artisan db:seed
php artisan app:create-super-admin
```

## Setting up Stripe
- Set stripe keys in the `.env` file.
- Set the webhook in Stripe to point to your server with the path `/stripe/webhook`.
- In Stripe Panel, set up to subscribe to these events:
- `customer.subscription.created`
- `customer.subscription.updated`
- `customer.subscription.deleted`
- `customer.updated`
- `customer.deleted`
- `payment_method.automatically_updated`
- `invoice.payment_action_required`
- `invoice.payment_succeeded`


# Contributing
Feel free to contribute to this project by submitting a pull request.

Expand Down
14 changes: 14 additions & 0 deletions app/Models/Plan.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,18 @@ class Plan extends Model
'stripe_id',
'features',
];

public function getFeaturesListAttribute(): array
{
// explode per new line
$list = explode("\n", $this->features);

// map the list. If a line begins with a + sign, set the included key to true,else if - sign, set to false
return array_map(function ($item) {
return [
'name' => ltrim($item, '+- '),
'included' => str_starts_with($item, '+'),
];
}, $list);
}
}
3 changes: 3 additions & 0 deletions bootstrap/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]);
$middleware->validateCsrfTokens(except: [
'stripe/*',
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
Expand Down
1 change: 1 addition & 0 deletions lang/en/plans.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
'created_successful' => 'Plan was created',
'features' => 'Features',
'features_hint' => 'Each feature on one line. Use + for included features and - for excluded features.',
'signup_for' => 'Sign up for',
];
8 changes: 4 additions & 4 deletions resources/views/account/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
@section('title', 'Account')

@section('content')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6">
<x-container>
<x-h2>
{{ __('Account') }}
</div>
</div>
</x-h2>
</x-container>>
@endsection

26 changes: 12 additions & 14 deletions resources/views/account/subscriptions/cancel.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@

@section('content')
@include('components.dashboard.subscription-nav')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6 prose max-w-none">
<h2>
Cancel Subscription
</h2>
<p>We're sad to see you go.
You can cancel your subscription at any time. You will still have access to your account until the end of your billing period.
</p>
<form action="{{ route('account.subscriptions.cancel.post') }}" method="post">
@csrf
<x-button type="submit">Cancel Subscription</x-button>
</form>
</div>
</div>
<x-container>
<x-h2>
Cancel Subscription
</x-h2>
<p>We're sad to see you go.
You can cancel your subscription at any time. You will still have access to your account until the end of your billing period.
</p>
<form action="{{ route('account.subscriptions.cancel.post') }}" method="post">
@csrf
<x-button type="submit">Cancel Subscription</x-button>
</form>
</x-container>

@endsection
29 changes: 13 additions & 16 deletions resources/views/account/subscriptions/card.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@

@section('content')
@include('components.dashboard.subscription-nav')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6 prose max-w-none">
<h2>
Update Creditcard Details
</h2>
<p>
Got a new card? Update your card details here.
</p>
<x-card-form :action="route('account.subscriptions.card.post')">
<x-button type="submit" id="card-button" data-secret="{{ $intent->client_secret }}">
Update card details
</x-button>
</x-card-form>
</div>

</div>
<x-container>
<x-h2>
Update Creditcard Details
</x-h2>
<p>
Got a new card? Update your card details here.
</p>
<x-card-form :action="route('account.subscriptions.card.post')">
<x-button type="submit" id="card-button" data-secret="{{ $intent->client_secret }}">
Update card details
</x-button>
</x-card-form>
</x-container>
@endsection
48 changes: 23 additions & 25 deletions resources/views/account/subscriptions/coupon.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,31 @@

@section('content')
@include('components.dashboard.subscription-nav')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6 prose max-w-none">
<h2>
Apply a Coupon
</h2>
<p>
Received a coupon?
You can apply a coupon to your subscription to get a discount.
</p>
<form action="{{ route('account.subscriptions.coupon.post') }}" method="post">
@csrf
<x-container>
<x-h2>
Apply a Coupon
</x-h2>
<p>
Received a coupon?
You can apply a coupon to your subscription to get a discount.
</p>
<form action="{{ route('account.subscriptions.coupon.post') }}" method="post">
@csrf

<div class="mb-5">
<x-label for="coupon">{{ __('Coupon') }}</x-label>
<x-input id="coupon" name="coupon" type="text" :value="old('coupon')" autofocus
placeholder="{{ __('Coupon') }}"/>
@if ($errors->first('coupon'))
<p class="text-red-500 text-xs italic mt-4">{{ $errors->first('coupon') }}</p>
@endif
</div>
<div class="mb-5">
<x-label for="coupon">{{ __('Coupon') }}</x-label>
<x-input id="coupon" name="coupon" type="text" :value="old('coupon')" autofocus
placeholder="{{ __('Coupon') }}"/>
@if ($errors->first('coupon'))
<p class="text-red-500 text-xs italic mt-4">{{ $errors->first('coupon') }}</p>
@endif
</div>

<x-button type="submit" id="card-button">
Apply Coupon
</x-button>
<x-button type="submit" id="card-button">
Apply Coupon
</x-button>


</form>
</div>
</div>
</form>
</x-container>
@endsection
104 changes: 51 additions & 53 deletions resources/views/account/subscriptions/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,62 @@

@section('content')
@include('components.dashboard.subscription-nav')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6 prose max-w-none">
<h2>
Subscription overview
</h2>
<p>
Here's a summary of your subscription.
</p>
@if (auth()->user()->subscribed())
@if ($subscription)
<ul class="list-disc pl-5">
<li>
{{ auth()->user()->plan->title }}
({{ $subscription->amount() }}/{{ $subscription->interval() }}) - <a wire:navigate.hover href="{{ route('account.subscriptions.swap') }}">Change</a>
</li>
{{-- @if (auth()->user()->subscription()->cancelled())--}}
{{-- <li>--}}
{{-- Ends at {{ $subscription->cancelAt() }}--}}
{{-- <a href="{{ route('account.subscriptions.resume') }}" class="underline">Resume--}}
{{-- subscription</a>--}}
{{-- </li>--}}
{{-- @endif--}}
<x-container>
<x-h2>
Subscription overview
</x-h2>
<p>
Here's a summary of your subscription.
</p>
@if (auth()->user()->subscribed())
@if ($subscription)
<ul class="list-disc pl-5">
<li>
{{ auth()->user()->plan->title }}
({{ $subscription->amount() }}/{{ $subscription->interval() }}) - <a wire:navigate.hover href="{{ route('account.subscriptions.swap') }}">Change</a>
</li>
{{-- @if (auth()->user()->subscription()->cancelled())--}}
{{-- <li>--}}
{{-- Ends at {{ $subscription->cancelAt() }}--}}
{{-- <a href="{{ route('account.subscriptions.resume') }}" class="underline">Resume--}}
{{-- subscription</a>--}}
{{-- </li>--}}
{{-- @endif--}}

@if ($invoice)
<li>Next Payment {{ $invoice->amount() }} on {{ $invoice->nextPaymentAttempt() }}</li>
@endif
@if ($invoice)
<li>Next Payment {{ $invoice->amount() }} on {{ $invoice->nextPaymentAttempt() }}</li>
@endif

@if ($customer)
<li>Balance {{ $customer->balance() }}</li>
@endif
@if ($customer)
<li>Balance {{ $customer->balance() }}</li>
@endif

</ul>
@endif

<div class="mt-5">
Use the menu above, or
<a href="{{ auth()->user()->billingPortalUrl(route('account.subscriptions')) }}" class="underline">

go to the Billing Portal at Stripe

</a>
to handle your subscription.
</div>
@else
<div>
<p>You don't have a subscription. </p>
<a href="{{ route('subscriptions.plans') }}">
<x-button>
</ul>
@endif

<span>Go check out our available plans</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
</x-button>
</a>
</div>
<div class="mt-5">
Use the menu above, or
<a href="{{ auth()->user()->billingPortalUrl(route('account.subscriptions')) }}" class="underline">

@endif
go to the Billing Portal at Stripe

</a>
to handle your subscription.
</div>
@else
<div>
<p>You don't have a subscription. </p>
<a href="{{ route('subscriptions.plans') }}">
<x-button>

</div>
</div>
<span>Go check out our available plans</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right">
<path d="M5 12h14"/>
<path d="m12 5 7 7-7 7"/>
</svg>
</x-button>
</a>
</div>
@endif
</x-container>
@endsection
36 changes: 17 additions & 19 deletions resources/views/account/subscriptions/invoices.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@

@section('content')
@include('components.dashboard.subscription-nav')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6 prose max-w-none">
<h2>
Invoices
</h2>
<p>
You can download your invoices here.
</p>
@forelse ($invoices as $invoice)
<div class="flex justify-between">
<div>{{ $invoice->date()->toFormattedDateString() }}</div>
<div>{{ $invoice->total() }}</div>
<a href="{{ route('account.subscriptions.invoice', $invoice->id) }}">Download</a>
</div>
@empty
No invoices
@endforelse
</div>
</div>
<x-container>
<x-h2>
Invoices
</x-h2>
<p>
You can download your invoices here.
</p>
@forelse ($invoices as $invoice)
<div class="flex justify-between">
<div>{{ $invoice->date()->toFormattedDateString() }}</div>
<div>{{ $invoice->total() }}</div>
<a href="{{ route('account.subscriptions.invoice', $invoice->id) }}">Download</a>
</div>
@empty
No invoices
@endforelse
</x-container>
@endsection
26 changes: 12 additions & 14 deletions resources/views/account/subscriptions/resume.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@

@section('content')
@include('components.dashboard.subscription-nav')
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg border border-stone-200">
<div class="p-6 prose max-w-none">
<h2>
Resume your subscription
</h2>
<p>
We're glad to see you back. You can resume your subscription here.
</p>
<form action="{{ route('account.subscriptions.resume.post') }}" method="post">
@csrf
<x-button type="submit">Resume Subscription</x-button>
</form>
</div>
</div>
<x-container>
<x-h2>
Resume your subscription
</x-h2>
<p>
We're glad to see you back. You can resume your subscription here.
</p>
<form action="{{ route('account.subscriptions.resume.post') }}" method="post">
@csrf
<x-button type="submit">Resume Subscription</x-button>
</form>
</x-container>
@endsection
Loading

0 comments on commit ab0e6cc

Please sign in to comment.