---
title: 'Laravel 11 + React SaaS with Stripe Integration'
source: 'https://youtube.com/watch?v=BdGvI3W0f9E'
video_id: 'BdGvI3W0f9E'
date: 2026-06-15
duration_sec: 0
---

# Laravel 11 + React SaaS with Stripe Integration

> Source: [Laravel 11 + React SaaS with Stripe Integration](https://youtube.com/watch?v=BdGvI3W0f9E)

## Summary

This tutorial demonstrates building a full-stack Software-as-a-Service (SaaS) project using Laravel 11, React, Tailwind CSS, and Stripe for online payments. The core functionality includes user registration with default credits, feature usage that deducts credits, and a credit purchase system via Stripe. The project is designed to be a foundation for more complex features like AI-based services.

### Key Points

- **Project Overview** [00:00] — Building a SaaS project with Laravel 11, React, Tailwind CSS, and Stripe. Users get 10 credits on registration. Features: sum (1 credit) and difference (3 credits).
- **Real-World Feature Examples** [00:35] — Features could be complex like generating audio transcripts, restoring images with AI, or creating 3D avatars. Credit requirements are customizable.
- **Credit Packages** [00:52] — Three packages (Basic, Silver, Gold) are defined in the database, making credits and prices customizable.
- **Credit Purchase Flow** [01:02] — When credits are insufficient, users can choose a package, pay via Stripe, and the feature becomes active again.
- **Dashboard Features** [01:15] — Dashboard shows used features: feature name, credits spent, timestamp, and additional data (input/output).
- **Prerequisites** [02:13] — Requires PHP (XAMPP recommended), Composer, Node.js, and an IDE (VS Code or PhpStorm). Git Bash is recommended on Windows.
- **Laravel Project Setup** [03:43] — Create Laravel project: `composer create-project laravel/laravel laravel11-react-saas`.
- **Installing Laravel Breeze** [05:02] — Install Breeze: `composer require laravel/breeze --dev`. Then run `php artisan breeze:install` and select React stack with dark mode.
- **Dark Mode Configuration** [07:00] — Enable dark mode by setting `darkMode: 'class'` in tailwind.config.js and adding `class="dark"` to the layout.
- **Generating Models and Migrations** [07:50] — Generate models: Package, Transaction, Feature, UsedFeature with migrations.
- **Migrations Structure** [08:39] — Packages: name, price, credits. Transactions: status, price, credits, session_id, user_id, package_id. Features: image, route_name, name, description, required_credits, active. UsedFeatures: credits, feature_id, user_id, data (JSON).
- **Model Relationships** [11:00] — Transaction belongsTo User. UsedFeature belongsTo User and Feature. UsedFeature casts data as array.
- **Database Seeder** [12:48] — Seeder creates a user, two features (calculate sum and difference), and three packages (Basic, Silver, Gold).
- **User Observer for Default Credits** [15:33] — Create UserObserver with `creating` method to set `available_credits = 10`. Use `#[ObservedBy(UserObserver::class)]` attribute on User model.
- **Migrate and Seed** [17:32] — Run `php artisan migrate:fresh --seed` to apply migrations and seed data.
- **Creating Feature Controllers** [19:00] — Create FeatureOneController and FeatureTwoController with index and calculate methods.
- **Feature Controller Logic** [20:00] — Constructor selects feature by route name and checks if active. Index renders the feature page. Calculate validates input, checks credits, deducts credits, saves used feature, and returns result.
- **Feature Resource** [23:00] — Create FeatureResource to safely pass feature data to React components, preventing sensitive data exposure.
- **React Feature Component** [27:00] — Reusable Feature component displays feature details, locks feature if insufficient credits, and includes a link to buy more credits.
- **Feature One Index Page** [34:00] — React component with form for two numbers, uses useForm from Inertia, submits to calculate route.
- **Navigation and Credits Display** [38:43] — Add feature links to sidebar and display user credits with a coin icon and 'Get More' link.
- **Testing Feature Usage** [43:00] — Test sum and difference features. Credits decrease correctly. When credits run out, feature locks with a message.
- **Credit Controller Setup** [45:07] — Create CreditController with index, buyCredits, success, cancel, and webhook methods.
- **Installing Stripe SDK** [46:42] — Run `composer require stripe/stripe-php` and add Stripe secret key to .env.
- **Package Resource** [48:57] — Create PackageResource to return id, name, price, credits.
- **Buy Credits Method** [50:00] — Creates Stripe checkout session with line items, creates a pending transaction, and redirects to Stripe.
- **Success and Cancel Methods** [53:29] — Redirect to credit index with success or error message.
- **Webhook Handling** [54:09] — Validates Stripe signature, processes checkout.session.completed event, updates transaction status to paid, and increases user credits.
- **Credit Index React Component** [58:00] — Displays user credits, success/error messages, and pricing cards for each package.
- **Pricing Cards Component** [64:00] — Iterates over packages, displays name, price, credits, and features list. Form submits to buyCredits route.
- **Routes Definition** [66:24] — Define routes for credit index, buy, success, cancel, and webhook (outside auth middleware).
- **CSRF Exemption for Webhook** [68:00] — Exclude webhook route from CSRF validation in bootstrap/app.php.
- **Testing Stripe Integration** [70:00] — Use Stripe CLI to forward webhooks locally. Test payment with test card. Webhook returns 200 and credits are updated.
- **Dashboard Controller** [77:22] — Create DashboardController with index method that fetches paginated used features for the authenticated user.
- **UsedFeature Resource** [78:31] — Returns id, credits, feature (as FeatureResource), created_at, and data.
- **Dashboard React Component** [80:00] — Displays a table of used features with columns: feature name, credits, date, additional data. Shows message if no features used.
- **Fixing Data Field** [85:36] — Add 'data' to fillable in UsedFeature model to ensure it is saved.
- **Homepage Controller** [89:30] — Create HomeController to render welcome page with active features.
- **Homepage React Component** [91:00] — Update welcome.jsx to display feature cards with image, name, description, and link to feature page.

### Conclusion

This tutorial provides a complete foundation for a Laravel 11 + React SaaS application with Stripe payments, credit management, and a dashboard. You can extend it by replacing dummy features with real AI or other paid services.

## Transcript

in this video we're going to build fully
functional software as a service project
with Lal 11 react Talon CSS and stripe
online payments on registration user
gets 10 credits by default there are two
features implemented in the project the
first one is to calculate sum of two
numbers which requires one credits and
the second feature is to calculate the
difference of two numbers which requires
three credits these are simplest
possible features which I implemented
for Simplicity my main focus in this
project is to build software as a
service website in reality these
features might be as complex as
generating script of the uploaded audio
file restoring broken images using AI or
generating 3D avatars based on uploaded
portrait images the number of credits
required for a specific feature is also
customizable I have also defined three
packages to purchase credits these are
coming from the database so the number
of credits inside package or the price
of package is also customizable once the
user doesn't have enough credits to use
a specific feature they can choose the
package they want pay using stripe
online payments after which the blocked
feature will become activated again and
user will be able to use it on dashboard
you're going to see all your used
features you're going to see the feature
name how many credits you spend on that
feature at what time you did that and
additional information that might be the
input you gave to that specific feature
out output the feature generated and any
other information you want to put right
here the link of the project source code
will be in the video description I'm
super excited to hear your opinion on
this project so let me know your
thoughts in the comment section down
below repairing building and editing
such type of projects requires a lot of
time and energy 70% of the channel
viewers are not even subscribed to the
channel if the project idea excites you
the single best thing what you can do
right now is to hit the Subscribe button
and enable notifications additionally
liking the video and providing a
positive comment will help the channel a
lot to grow all right no further Ado
let's start building this awesome
project before we start working on the
project let's just make sure that we
have all the necessary programs
installed if I don't develop my projects
with Docker I generally use examp so if
you don't have PHP comment globally
available in your terminal I recommend
to download and install examp if you
already have PHP available you don't
need to do anything so we're going to
need composer which is the PHP package
manager we're going to need node.js as
well because we're going to create the
reactjs application as well as a choice
of the IDE editor I'm going to use
Visual Studio code for this particular
tutorial I use generally PHP storm or
Visual Studio code for PHP I prefer to
use PHP storm however for YouTube and
for such type of tutorials I'm trying to
use more Visual Studio code because I
can understand that most of you doesn't
have that uh cannot afford PHP storms
paid license that's why I try marking my
working setup to be as close to your
working setup as possible that's why I
have I'm going to use vs code and um
with a couple of extensions I have also
a dedicated video how to set up vs code
for Lal development you can check it out
on my YouTube channel okay and I'm going
to use gitbash if you don't have gitbash
uh it comes with a git just download and
have it I recommend to use gitbash
because that's my preferred terminal on
Windows on Mac or or on Linux you can
use your preferred terminal that's
absolutely fine gitbash is not something
like a must have okay now I'm going to
open gitbash and I'm going to create a
LEL project by executing composer create
d project laravel SL laravel in here I'm
going to provide the local folder name
Lal 11- react D SAS and I'm going to hit
the enter which is going to download the
LEL project and set it up for
us in this tutorial we're going to learn
how to build software as a service
project with Lal and react however if
you want to deploy this specific project
on production environment and assign
custom domain to it I do have separate
dedicated videos on specifically
deployment my personal choice of Hosting
provider is hostinger which is very
kindly sponsoring this video let's see
how lot of installation goes okay it is
downloading packages and progressing I
have been personally using hostinger for
past three years and I have been
extremely happy with their services they
provide shared hosting VPS hosting Cloud
hosting and even email hosting their
prices are very affordable and servers
are very fast let's check Lal
installation progress okay it finished
installation and now we're going to open
it using vs code now I'm going to bring
up the terminal and and collapse the
left side and I'm going to install Lal
Bree composer require
l/ Breeze D- Dev once Breeze is
installed we're going to execute PHP
Artisan Breeze colon install it's going
to ask us which stack we would like to
install and I'm going to go with react
then it's going to ask us which
additional features we want to include
and I'm going to choose dark mode and
the final question is which testing
framework we want we prefer and I'm
going to leave this default because I'm
not going to write test in this project
I'm going to hit the enter and it's
going to require additional packages
like inertia related packages uh
additional uh react related packages
Ziggy and it's going to set up the react
within nura project for us hostinger
shared hosting services start at
$2.99 per month during holidays this
price goes even lower and that price
includes free domain free unlimited
number of SSL certificates unlimited
number of databases G support SSH access
backups and even more I recommend to
check their website explore your desired
service check all the features because
there are tons of features actually
included in this price and if you decide
to grab the hosting during checkout use
the coupon code zura TC which will give
you extra 10% off on already discounted
price all the links will be in the video
description and I want to say big thanks
to hostinger for supporting this channel
so far and sponsoring this video the
command also executed mpm install and
bued also react assets and we can start
the Artisan server already by executing
PHP Artisan serve and I'm going to open
second terminal and I'm going to execute
mpm run Dev to have the V server up and
running for development purposes now
let's open the browser and I'm going to
type Local Host Port 8000 and we're
going to see Lal 11's default welcome
page this is awesome now let me enable
dark mode for this I'm going to open tnd
config JS and I'm going to add right
here uh dark mode property to be based
on class and I'm going to also open up
dot. blade PHP which is the main layout
file in and I'm going to add right here
class to be dark as soon as I save this
and open in the browser we're going to
see that LEL 11's welcome page is
already in the dark mode all the
migrations are also properly applied so
if I try to register right now I was
able to successfully register and I'm
also authenticated now let's generate
models and migrations PHP artisan make
model package is the first model with
migration I'm going to also
generate transaction
model then we're going to generate
feature
model and I'm going to also
generate used feature
model okay we have four models and four
migration files let's close this and I'm
going to go inside database migrations
and I'm going to open all four migration
files and I'm going to work on each of
them one after after another okay let's
write the migrations and in the packages
table we're going to need the name of
the package like basic silver gold and
so on we're going to also need the price
for each package and the number of
credits inside each package then let's
go into transactions here we need the
status of the transaction so whenever we
create the transaction and whenever we
redirect user to the stripe checkout
page the transaction status will be
pending then whenever the uh payment is
completed the transaction status is
complet is changed into done or paid and
then we're going to also increase the
number of remaining credits for the user
okay so we will need the status on
transaction we're going to need also the
price for each transaction we need how
many credits that transaction included
the session ID and this is going to be
the stripe checkout session ID we're
going to need the user ID who made that
transaction and we need package ID and
uh I think that's it yeah we don't need
anything else then we are going to
create the features table here we need
the image we need rout name that's going
to be the actual rout name okay we're
going to need the name description
required credits and the active flag
whether this feature is active or not we
can have multiple features but you can
easily deactivate them from the database
and they will not be um just displayed
on the website and users will not be
able to use that specific features also
then we go into used features and here
we will need credits we will need
feature ID we will need user ID we will
need um data which is going to be
additional information when the user
used the specific feature what
additional information the user passed
to that feature
okay so this is great so we created four
tables um for migration files let me
close all of them and I'm going to open
now models like I'm going to open
hackage PHP I'm going to open
transaction PHP I'm going to open
feature oops feature. PHP and I'm going
to open used feature. PHP
let's start with the package PHP and
we're going to first provide um elements
inside the fillable so we're going to
need name price and credits inside the
fillable then let's go in transactions
and here we need fillable as well
providing status price credits session
ID user ID package ID and I think that's
it and I'm going to also Define relation
from transaction to user uh and the
transaction belongs to user we're going
to need that
relation uh then let's go into feature
and here we need image Road name we need
name as well we need description
required credits and active as well okay
and in the used features we need a
couple of more information um except
that like other than fillable uh we need
feature ID user ID credits uh we also
need the casts basically we have the
data property in the used features which
is Json B
uh and we're going to convert that into
an array basically or whenever there's
an array we're going to save this as a
Json in the database because we are
using SQ light we need that cast so
we're going to return that the data is
basically an array uh this is additional
uh like a new feature in Lal 11
previously cast uh casts in Lal 10 was
an array but now in Lal 11 we can have
costs as a function
okay then down below we need the
relation from the use features to user
where the use feature belongs to user
and down below in the same way we need
the relation to feature
itself now we have all the modules and
migrations ready I'm going to close
everything and I'm going to open
database Cedar and right here I'm going
to update the existing user Factory let
me actually delete everything and
rewrite okay first let's create the US
user and we're going to provide name
email and encrypted password to the user
then we're going to create U several
features so um this is a dummy image
which I actually grabbed from the Google
this is just a plus image so I can click
right here it actually opens into
another tab let me open this very
quickly right here this is a plus icon
okay so because we're going to implement
very dummy features like just to
calculate the sum of two numbers and
difference of two numbers we're going to
just have an image for the feature okay
then we're going to need the root name
okay and the root name in this case is
feature one. index why I use this
feature one right here and uh the name
used as a calculate sum for example
because I don't want to stick just with
my features my features are Dam features
as I mentioned they are called calculate
sum and calculate difference but I also
uh use the names like feature one
because uh those are very generic
features and the whole idea of this
project is that you can Implement your
own additional features uh you can take
this project remove those dummy features
Implement your own features and you're
going to have something awesome okay so
sometimes I use calculate some sometimes
feature one so don't uh get confused
with that okay so then we in the
description we have calculate some of
two numbers we have number of required
credits for this Feature Feature one
basically and we have the active as as
well so then down below I'm going to
just uh paste this entire feature two
which has the road name feature two the
image is for the minus calculate
difference the description this requires
three credits okay each one requires one
credit this requires three credit and we
have the active true so uh and down
below we're going to Define packages as
well each package will have a name we
have price and we have number of credits
and I'm going to just duplicate this and
have silver with price 20 credits 100
and duplicate this once again and we're
going to have name golden price 50 and
credits 500 and just like this we have
this uh migration um sorry the database
C ready we just need to import the
package up modules package and the
feature because we are using this um
right
here okay we added new column in the
users and this is called available
credits we added migration for this
whenever the new user is created we want
the available credits to be set as 10
for every new user so we're giving every
user 10 credits upon registration okay
how we're going to do this I'm going to
create user Observer for this let me
open the terminal and I'm going to
execute PHP artisan
make Observer user
Observer let's hit the enter it created
that user Observer we're going to open
this it doesn't open
user Observer and we are going to add
right here public function creating okay
which accepts instance of the user and
we can import that user um app models
user inside this class and what we need
to do is just to set
user available
able
credits equals 10 so whenever the new
user is created we're going to set this
available credits to 10 and we just need
to now use that user Observer and
slightly new method of using the
observers on models is the is using uh
PHP attributes so here we're going to
use attribute called uh obser oberved
Pi oops what just happened observed
Pi this one and we're going to provide
the class name which should observe the
current model so in our case this is
going to be user
Observer okay through this line I'm
telling LEL that this class is observed
by user Observer so whenever the new
instance is created for this user it's
going to call this creating function
passate user and the 10 will be set now
what we need to do is just bring up the
terminal again and execute PHP
Artisan uh migrate so if I execute
migrate it's going to apply new
migrations the new migrations are those
four migrations we just created but we
also change something in the user
migration and plus we want to execute
seed data as well so I'm just going to
execute PHP Artisan
migrate um
bres Das D seed it's going to drop
everything reapply everything and it's
going to seed the data as well now I
want to check what is the data uh inside
the database so I'm going to access the
database through Tinker PHP Artisan
Tinker okay let's um let's get the first
user user first and this is the first
user it has all that information what
what we provided in the database CER and
it also has this available credits 10
awesome uh now let's execute up
models feature and get all features here
and we see two features basically with
their all the information and you can
assume that in the same way credits um
uh sorry packages we also are also
created so I'm just going to just uh
select them as well but we have the
database structure ready and we o have
the SE data
ready now let's bring up new terminal so
this terminal is actually for Tinker
this is for V this is for Artisan I'm
going to open one more terminal this is
going to be my Artisan terminal and I'm
going to create new controller feature
One controller PHP artisan make
controller feature One controller and in
the same way let's just create feature 2
controller as well okay awesome so let
me close everything and now I'm going to
open feature One controller and I'm
going to work right here first of all
I'm going to Define public um feature
class uh instance basically property uh
which will be nullable and by default
I'm going to assign this um null okay
I'm going to Define also Constructor I'm
going to Define index function and I'm
going to Define calculate function and
I'm going to explain why I have those
functions before I write anything okay
so inside the Constructor I'm going to
select the feature based on the root
name and I'm going to save this in this
public feature property okay inside the
index I'm going to render the feature
page and inside calculate I'm going to
handle the post submission of the
feature I'm going to do all the
operations that is necessary for that
specific feature and I'm going to return
the result render the result or redirect
back to the index with the result okay
and this controller is kind of universal
controller feature One controller you
can create similar controllers for your
specific features whether this is going
to be speech to text or image
restoration or um image generation
whatever okay you will render uh the
form for example upload image F image
file then you're going to handle this
inside the calculate you can call this
method whatever you want and then you
will redirect user back to index with
the actual result of the calculation
okay this is awesome now inside um
Constructor let's select this feature
based on the road name where the road
name equals feature one. index okay if
you if you remember in the database s
this is the root name what we gave to
the feature one I'm going to also uh
select if the feature is active if the
feature is not active simply I want to
show
404 so if for some reason I decided to
deactivate the feature I don't want the
users to use that specific feature I
will change its active status and nobody
be will be able to use
that okay once I have the feature
selected then let's move into index here
I'm going to render the inertia page
okay however I am going to pass the
feature right here so uh first of all
just pay attention that this feature one
index doesn't exist okay so we're going
to create that function and not a
function it's going to be a reactjs
component okay and we're going to pass
the feature which is going to be a
feature resource this is another
thing the feature resource is another
file that doesn't exist okay and we're
going to pass to that feature resource
this feature we're going to create that
feature resource in a moment okay and
I'm going to pass additional property
which is going to be the answer okay
whenever we calculate the answer from
this calculate function we're going to
put this in the session redirect user
back to the index and we're going to get
that from the session and pass it as the
answer variable inside this feature one
index now we're going to do two things
uh first we're going to create this
feature resource so I'm going to
basically bring up the terminal and
execute PHP design make resource feature
resource let's hit the enter feature
resource was created let's open that and
I'm going to change this return an array
and I'm going to define the properties
right
here we're going to return ID we're
going to return image Road name name
description required credits and active
Okay so why do I need this Source you
probably have a question I'm returning
almost every property except created
that and updated that generally the
inertia type of applications where you
use react or view it doesn't matter the
information what you pass to that react
component in this case feature will be
visible inside the browser so if you
pass sensitive information as a variable
to that feature one Index this is no
good okay that information will be be
can be um exposed to um anybody else
basically so we want always to give the
models to the resources and return that
resource to the uh give that resource to
the
component okay so this is a security
measurement um and it's a very
recommended thing actually to do so we
now have this feature resource and what
we need to do um with we obviously need
to import the feature resource but let
me actually uh continue and then I will
import that
okay then I'm going to inside calculate
I'm going to get the user okay and I'm
going to do the following check if the
user's available credits is less than
the number of credits the feature
requires it means that we don't user
doesn't have enough credits so we simply
go back we don't proceed with the
calculate so if it's enough then we
start validation of the data so we're
going to validate the number one uh
basically uh the we're going to
calculate some of two numbers right so
we're going to have number one and
number two and we're going to get those
two numbers I'm going to create separate
variables out of that and cast them into
float variables and then I'm going to
calculate the sum of those numbers but
I'm going to also save in the database
that user used the feature okay I'm
going to also decrease the number of
credits on the user so on the user I'm
going to call this decrease credits and
I'm going to pass these feature required
credits so if the feature requires one
credit we're going to decrease the users
available credits with one if the
feature requires three credits we're
going to decrease it by three okay once
we do this then we're going to save used
feature we're going to pass the feature
ID we're going to pass the user ID we're
going to pass the credits and we're
going to pass additional data so this
user used that feature which cost that
amount of credits and this is the
additional information which contains
number one and number two again this is
kind of something Universal which I
wanted to create for uh almost all kind
of features so even if you do like a
image conversion or um like speech to
text whatever you have the feature ID
user ID number of credits and inside
this data you can put any additional
information you want you can put uh like
image one image two and whatever okay
once we save that used uh feature uh
then we simply go to uh rout feature
one. index we redirect user back to the
index page and we're going to pass also
the answer the answer will be number one
plus number two and this is going to be
it okay so I'm going to scroll up and
I'm going to include that feature
resource I'm going to include the uh
models feature and I think we need the
used feature as well okay now we have
this feature One controller ready um I
can close that and I'm going to open
actually I need to do one additional
thing in the feature resource I am going
to create right
here public
static um WP equals false so I'm
disabling W for this feature resource
okay I'm going to close this now let's
open web.php
and let me scroll down below and I'm
going to create Define the rules for the
feature one now let's create feature one
component feature one index component
I'm going to go into resources JS pages
and inside Pages I'm going to create new
file called feature one slash index that
should be uppercase i index js6 let's
hit the enter so here we have this index
js6 and I'm going to also create one
component under component section so
that components basically is um was
added by Lal breeze so here we have
couple of ready components which we are
going to use but I'm going to add one
more component and this is going to be
feature JS jsx component so I'm going to
create one reusable feature js6
component which I'm going to use in
feature one component and feature two
component as well and you can use in any
other components um you are going to add
in any other feature components you are
going to add so that's going to be a
generic feature component which will
display the feature name feature
description number of credits required
for the specific feature and this will
be also responsible to lock that
specific feature if the user has a less
number of credits than the feature
requires okay so this is good so I'm
going to collapse the left side and
let's implement this feature
component let's define now component
export default function feature and I'm
going to also import the necessary um
classes like we're going to use
authenticated layout which is the main
layout what we see when we access the
dashboard page right now I'm not
authenticated but when you authenticate
you see the dashboard with the nav bar
this is the authenticated layout okay
and that authenticated layout also is
used in dashboard js6 and we're going to
use it in the same way then I'm going to
import couple of classes components from
inera Jes react package so we're going
to need the head link and use page and
I'm going to explain uh what each does
whenever I'm going to use that okay
inside feature we're going to get these
um properties like feature answer and
we're going to get additional children
then I'm going to use page from this
injs react and that gives me the page
object which has props okay and from
that page props I'm going to get the out
that out contains the user inside okay
so I can access out. user and the user
has available credits and I will get
this available credits inside in on its
own separate variable but how do I know
that this page props has out I'm going
to open uh handle inertia JS requests
middle we which comes with this U
inertia Js basically and right here if
we scroll down below inside sheare
function which uh the shear function
basically are those variables uh it
returns an associative array where keys
are those variables which are shared
across all pages of inertia JS react or
view doesn't matter so in this case we
are returning out so that out property
will be available on every react
component page okay and once
uh we are going to have that uh feature
one component rendered right here which
is going to be Associated to uh Road
this is going to be rendered from the um
controller feature One
controller the the out will be available
in every component basically it doesn't
matter you can access this out in the
index JS feature one index JS or feature
js6 uh yeah the out will be always there
and through that we get this authent the
avail aable credits okay let's move on
and I'm going to return the uh jsx um
from here I'm going to use this
authenticated layout pass the user and
header to this authenticated layout
similar to how it is done in dashboard
inside header I'm going to pass this H2
and I'm going to provide the feature
name as a title okay the feature is
accepted right here then if I scroll
down below I'm going to use this head
and that head basically is the HTML head
tag
okay and the title is the HTML title tag
and this comes from again inertial JS
react and it's going to handle this
using the title properly in the head
section okay the title in this case is
feature one you can call this feature.
name if you want then down below I'm
going to create couple of Dives with the
Talan CSS classes to properly uh set up
the layout car type of
layout and we're going to also output
the answer right here at the top of the
four so if the answer is not
null and then in this case we're going
to render this Steve okay which will
have like a green background text white
and inside there I'm going to Output
result of calculation is the answer that
answer is received right here okay then
we're going to proceed we're going to
create one additional
div and inside there I'm going to check
if available credits that available
credits are the user available credits
okay if the available credits is not
null and if the feature requires more
credits than the user has remaining we
are going to display we're going to lock
the specific feature so here we have the
D with position absolute left zero top
zero right zero bottom zero so basically
that div is stretched on that div right
here and it's going to lock every every
interaction to uh the PN div so that div
inside there will have an SVG icon and
that SVG icon is the lock SVG icon you
can find this icon if you go into hero
icons click the very first link then
type lock right here and this is the
icon what I used here so the same SVG
icon then down below we're going to have
div you don't have enough credits for
this feature go and then I'm going to
put a link right here with the text go
buy more credits okay and the link right
now will have href just slash but we're
going to replace this with the page URL
Page Road uh on which we can buy more
credits okay down below we're going to
have additional div and we're going to
have feature description we're going to
have uh the uh information how many
credits the feature requires and at the
very bottom we're going to render all
the children okay so this feature is a
generic feature component which will be
used right now in this index jsx so in
this index jsx let's define this
function index I'm going to import every
component I need so I will need this
input error from components again this
component comes from LEL Bree I will
need um input label text input PR
primary button uh use form is something
which is uh imported from inertia JS
react and I'm going to explain what this
use form does that's that's the um
correct way interact how you can
interact with a form data in inertia so
and I'm going to also import that
feature component what we just described
okay then let's accept feature and
answer and this feature and answer are
the properties we are passing from
feature one
controller from here okay so we get this
feature an answer and then I'm going to
declare a form using use form and this
use form returns an object and that I'm
going to destructure that object and
take out data from there set data method
I'm going to get the post method and
using this we're going to send the data
to the server we're going to have resit
function we're going to have errors and
processing flag as well in I'm going to
pass you inside this use form number one
and number two as an initial data for
this use form whatever we're going to
pass right here it will be accepted
inside this data and then we can use
this data to display that number one and
number two if we need down below I'm
going to declare the submit function we
accept an event call event PR and
default and then I'm going to execute
post method okay I'm going to pass the
root name uh the I'm going to use these
root function which basically is the
function available in every component so
I'm going to use that uh function and
I'm going to pass feature one calculate
as a root name these posts accept second
argument which is an object and inside
there I'm going to pass on success call
back and on success I'm going to call
reset function okay down below I'm going
to return js6 I'm going to use that
feature component which we just
described and I'm going to pass this
feature and answer to this feature
component inside there I'm going to
declare the form I'm going to add the
submit Handler there I'm going to Define
div inside there I'm going to have this
input label for number one and I'm going
to have text input with ID type name
value class name and on change we're
going to listen on change and get the
event and I'm going to call this set
data this set data and uh the set data
accepts two arguments the first is the
field I want to update and the second is
the value even Target value and the
initial value for this input will be
data. number one and again this data
will contain whatever we pass right
here okay awesome then I'm going to
declare input error we're going to pass
the message to this input error which
will be error. number one if there is
some sort of validation errors they will
be received right here inside this eror
okay good and we're going to provide the
class name as well so down below we're
going to have very similar div to this
uh number one it will have this input
label uh text input with all these same
properties what the number one has and
the input error as well and down below
we're going to have additional D which
will be for the button inside there I'm
going to put the primary button and I'm
going to uh give it text calculate and
and I'm going to disable the Bon if the
form is in processing
State okay and I save this and I think
there is nothing um we need to do uh at
the moment inside here so I think we can
open in the browser I'm going to log in
with
my email and
password and we're going to try to have
a look uh actually before I access the
URL let me open
authenticated
layout I'm going to find this dashboard
I'm going to duplicate these two times
and here we're going to have wrot name
feature one. index the feature name will
be feature
one and here we are going to have
feature 2
index with feature 2 text and we need
something similar for the mobile version
as well so I'm going to scroll down
below
here we have this dashboard I'm going to
duplicate this two more
times feature one
index feature one and this is going to
be feature two
index feature two let me save this and
now we have this feature one and feature
two I'm going to click on this feature
one it renders the page and we see the
title is calculate sum calculate sum of
two numbers is the description and we
see it requires one credits if I go on
feature
two it doesn't work um probably because
we have not created this feature two uh
component so even though we have the
feature to controller and the feature
Two controller um has some content
inside there let's
open feature 2 controller we are
returning this feature 2 index that view
doesn't exist and because the inertia
was not able to return the correct
response uh it doesn't uh navigate us to
the feature two I think we can easily
duplicate now feature one I'm going to
come to feature one duplicate paste this
inside Pages this is feature one copy
and I'm going to rename this into
feature 2 and let's open this feature 2
index and I'm going to search for
Feature Feature one here and I think the
only usage is whenever we submit the
form again at the moment feature one and
feature two pages are very very similar
to each other but um I just demonstrated
how you can have multiple features and
obviously if you have different features
like game speech to text or image
restoration you can have absolutely
different content HTML content or
functionality inside each own component
feature component
okay so right now we have this feature
two defined already and I'm going to
click this feature two let's and yeah we
redirected calculate difference
calculate difference of two numbers and
requires three credits okay this is
awesome and before I test the
functionality I'm going to put also in
the nav bar the number of credits the
user has let's open authenticated layout
again scroll down below and find that
drop- down section right here and above
the drop- down div uh I'm going to add
this pan with some tle on CSS classes
and I'm going to put an image right here
which will be coin image uh I'm going to
also show this image to you but that's
actually a coin image which you can
easily get from Google any coin image
basically will work this is a just my
example okay and then next to the image
we're going to have the number of
available credits on the user okay so we
have that user accessed in this
authenticated layout uh and just like
this we can uh print how many credits
the user has then down below I'm going
to create a link and give it some tal
and CSS classes and give it text get
more okay the user has 10 credits to get
more just click right here at the moment
the href is just an empty um the slash
uh but later we're going to implement
that to go to the purchase credits page
each so if I save this and reload right
now I see 10 credits and get more right
here I'm going to add right here Gap
three to create more Gap uh between
these uh two elements and I'm going to
also uh put right here the image for
coin here is the image which I added in
Public Image folder and once I save that
in the browser I reload and I see coin
image right here 10 credits and get more
okay I think this is awesome and I want
to test now the functionality I'm going
to type one here two here and hit the
calculate and we have this error Call to
undefine
um undefine method up us decrease
credits okay I think it might be called
differently user PHP let's scroll down
below we call
this decrease okay it should be decrease
credits right so I just hit the
calculate once again and now I see
result of calculation is three we see
the number of credits we are decrease by
one and that's that's cool let's go into
feature two and provide like four and
two here hit the calculate result of
calculation is two and the number of
credits is now six I'm going to try this
two more times so that I'm going to just
run up the credits and let's see what
happens cck calculate and now look at
this so we saw the result and then this
feature got locked you don't have enough
credits for this feature go buy more
credits this buy more credits is not
valid Link at the moment it's going to
go to the homepage but you get the idea
we're going to implement that and this
link and this like the get more link
we'll do the same thing and open that
credit page but so far this is awesome
and this is
good now let's start working on the
credit controller which will be
responsible for purchasing of the
credits PHP artisan make
controller
credit controller I'm going to hit the
enter let's open this credit controller
and this should render the credit index
view which I know I I haven't written
this but I know that I'm going to do
this so I'm going to go under resources
JS pages and I'm going to create right
here credit SL index jsx
file okay awesome now let's start with
the credit
controller let's define a couple of
methods right here I'm going to Define
index which will be for rendering the
pricing packages then we're going to
have buy credits which is going to be to
buy a specific credit okay uh buy a
specific package and here we accept also
package we're going to Define rules as
well then we're going to have the
success callback and this is going to be
the stripe success URL whenever the
purchase was completed successfully will
be completed successfully user will be
redirected to the success callback we're
going to also have cancel URL and down
below I'm going to also add a web hook
for stripe okay before I proceed right
here I'm going to install stripe I'm
going to bring up the terminal and
execute composer require stripe SL
stripe
dphp so we need this
SDK stripe PHP package was installed and
then I'm going to open uh my stripe
dashboard which is right now in test
mode sandbox mode and I'm going to get
the secret uh Ral secret uh test key
right here so and I'm going to copy this
test key and I am going to put that
inside en okay so inside enan let's
open right
here and at the very bottom I'm going to
call this stripe
secret key and I'm going to paste my
secret key right here now let's open
create controller again and proceed and
start rendering um packages so we're
going to select all the packages what we
have in the database we're going to
select active features what we have in
the database and then I'm going to
render credit index react component and
I'm going to pass packages in features
but I'm going to pass them as
resources okay so this you should use
resources whenever it's um it's
necessary and applicable okay I could
not use resources Because the actual
fields for this package model is very
identical to the um what whatever I'm
going to return from this package
resource but I try to encourage you to
use resources whenever you are using
inertia application with LEL I don't
want you to get used to some bad
practices that's why I try to always use
resources when you have this like a full
stack application with inertia where
every information passed to react
component is actually visible for any
user so we are passing packages and
we're passing features we actually have
feature resource already created we're
going to import everything in a moment
but we don't have package resource
created yet okay so I'm going to bring
up the terminal and I'm going to execute
PHP artisan
make
resource package resource and I'm going
to hit the enter and let's open this
package resource and I'm going to change
this into an array and if we just open
Package PHP we have three Fields right
here and plus we also have this ID so
what I'm going to do is just um return
maybe it even autocompletes that
name we are going to have
price and we're going to have
credits
okay so we have this package resource
ready I'm going to close that and let's
continue in the credit controller okay
I'm going to import everything at the
bottom at at the um top right here so
then we proceed and we move into um
additional properties we're going to
pass into this credit index we're going
to pass the success message and we're
going to pass the error message to this
and the success and error messages will
be pushed into session from the success
and cancel methods okay now let's move
on and implement this buy credits which
is uh inside which we're going to create
the stripe session and redirect user to
stripe checkout page we're going to get
this stripe secret key from Ian which we
already put right there we're going to
create the stripe client and then from
the stripe client we're going to create
checkout s session this function create
accepts an array and inside there we
need line items line items is array of
arrays and we're going to pass the very
first item inside here we're going to
have the price data and we're going to
have quantity one for this okay so
basically in stripe those line items is
going to be products so and whatever
we're going to pass uh will be actually
created in stripe as product which we
actually don't care because we there is
something we want to buy we're going to
buy credits which if it will be product
in stripe we don't care but there are
certain fields we have to provide like
the currency product data for example
and inside product data we have to
provide the name and inside name we
provide package name concatenated with
how many credits that package has for
example for gold gold package this is
going to be
gold- 500 credits okay this is going to
be product
name so whenever you check your stripe
dashboard uh what items are sold mostly
you might see inside products called 500
credits so and we're going to also have
the unit amount which is the price and
we're going to have price in cents so
I'm going to multiply package price on
100 at the uh down below we're going to
have next to the line items we're going
to have mode payment okay and using this
we created the check out session we're
going to provide also success URL and
cancel URL and those going to be the
roles we will Define but we are using
this third parameter true for generating
absolute URLs we need those absolute
URLs uh because they will be passed to
stripe and then we will the the stripe
will redirect us back
to the um page so we need them to be
Absol
URLs so and I'm going to also create
transaction okay I'm going to provide
status pending the price package price
credits package credits we're going to
provide session ID we're going to
provide the authenticated user ID and
the package ID as well okay and then
we're going to redirect user to this
checkout session URL and basically this
method is finished okay let's scroll
down below and in the success basically
we are going to uh redirect user to
credit index which will be the
following action okay credit index and
I'm going to provide with success
message you have successfully bought new
credits for cancel we're going to
redirect again to credit index how
however we're going to provide error
message will be there was an error in
payment process please try again okay
and the next thing is web hook the
stripe will send requests to us in the
background that this checkout process
was completed successfully and then we
need to take care of that and we have to
um we have to basically do the necessary
things like increase the users available
credit and so on so let's proceed here
so we are going to get the um secret so
this endpoint secret is actually
necessary
to uh to make sure that the web Hook is
going to work successfully okay so we
have this stripe web hook key which
we're going to put inside en en I'm
going to open en and at the moment I'm
going to put this right here with m
string but we're going to populate this
um a little bit later okay so then we're
going to get the entire
payload we're going to get the HTTP
stripe signature header and by the way
this is also written in the stripe
documentation and I'm going to fill this
part and then I'm going to show where
you can find that okay so I'm going to
define the event which will be n and
then inside I'm going to do try catch so
I'm going to try to construct it an
event based on the following information
I'm going to pass the payload entire
payload I'm going to pass the signature
header and I'm going to pass the
endpoint secret so if the event is
constructed successfully it means that
the request is coming from stripe it's a
valid request and we get we can get the
information from there and that's
awesome and we need to take care of this
properly okay so however we need catch
as well I'm going to add two catch
statements here unexpected value
exception and signature verification
exceptions so and in both cases simply
I'm going to return uh with the response
400 status code and down below I'm going
to check if the event exists so if the
event was created right here what is the
event type so if the event type is
checkout session completed this is
exactly what we are interested in
then we need to do something so in
default case we simply write um received
unknown even type however in this case
we're going to get this session and we
get this session from even data object
so this is the same uh session object we
created uh right here and that session
has its own ID which we saved in the
transaction session ID column so now
based on that session I I'm going to
select the transaction from the database
the first transaction if the transaction
exists and if its status is pending I'm
checking it status if it's pending
because I don't know stripe might send
this more than once uh for me so I just
need to be sure that I don't do any un
like weird and incorrect things if
stripe send this twice so if this status
is pending in this case I set this
transaction status to be paid and I save
the transaction but I'm going to also
access the transaction user who made the
transaction and I'm going to increase
that user's available credits with the
transaction number of credits whenever
we created the transaction right here we
provided how many credits user is trying
to buy and we took that credits and add
it to the users available credits and
finally we're going to save the
transaction user okay this is perfect
and at the bottom of this uh web hook we
are going to return with the response of
empty string but the status code is 200
and that's going to be totally enough
for stripe if we return status code 200
this means that we got the web hook and
we handled
that now I am going to
open index jsx and let's work right here
so this is the um react component
actually we need to import certain
things so let's scroll up and I'm going
to do these Imports I'm going to import
the feature resource package resource
I'm going to import this uh package um
and feature and
transaction uh and we also need to
import this facade out because we are
using here whenever we are assigning the
user ID I think there's nothing um to
import um except that so we are good in
the credit controller uh now I'm going
to work inside this file credit index
and we we are passing these packages and
features and success and error and we
need to handle this properly okay so I'm
going to Define this function and I'm
going to also import all the necessary
components authenticated layout I'm
going to import the head and I'm going
to create new component for this credit
pricing card
okay and there's going to be three tiers
uh one for each package and I'm going to
create separate component for this okay
but right now I assume that the
component is already there so I'm going
to do this import
beforehand then I'm going to accept
inside index couple of properties like
out packages and
features and I'm going to also accept
success and error okay we are passing
these packages feature success and error
from the credit controller from here but
remember that the out prop is passed
from handle inertia JS request uh middle
wear okay then we're going to get the
number of available credits for the user
and then we're going to render js6 so
here I'm going to use authenticated
layout with user and header then I'm
going to provide title right here and
down below uh we're going to have some
boiler plate layout code and if the
success is given then I'm going to
render the success message with
background green if the error is given
and if it's if it exists I'm going to
render the error message with background
red okay then I'm going to do additional
div and uh inside there I'm going to
have one more div and image with the
coin icon so we have the we have the
following coin icon and I'm going to use
the same coin icon
okay and inside there I'm going to just
write you have X whatever is available
credits and down below I'm going to
render these credit pricing cards and
I'm going to pass packages and features
to that
okay so now we need to create these
credit pricing cards and we're passing
this uh packages data and features data
because we are passing them as a
resources and the resources uh resource
collection basically has this data if
you want to actually access that you
need to access this through
data okay
good uh now let's create this whatever
is the name credit pricing cards
component I'm going to do this right
here do
jsx now let's define these uh credit
pricing cards and um I'm going to use
the page import that use page from
inertia JS react and I'm going to use
that page right here to get the csrf
token okay the csrf token is something
we're going to add uh in inside the
middle we which doesn't exist yet but
we're going to also accept these
packages and features we are passing
from here which is totally
clear however let's add this csrf token
so I'm going to open handle inertia JS
request and just like like we are
putting this out I'm going to put right
here
csrf token will be
csrf
token okay I'm going to save that and
we're good now I'm going to return a jsx
section with some Talon CSS classes div
another div inside there I'm going to
have this H2 uh it's that's going to be
a promotional text the more credits you
choose the bigger savings you will make
and before before I proceed I'm going to
show you the template I use for this
pricing um table which you can also get
from uh flow bite so I use this flow
bite pricing cards something like
this
um ton CSS pricing cards so this is
exactly what I used I'm going to switch
into dark mode and you're going to see
okay so this this is the promotional
text which obviously I changed and we
have three price cards with features so
this is the exact same I'm using the
exact same layout I actually uh got the
code and I copied that okay I also have
these SVG icons in my
code okay now let me proceeded you can
get this uh entire HTML and modify as
you need or you can just follow with me
and type that HTML
content okay then I'm going to Define
another div and uh iterate over packages
okay
and for each package I'm going to render
div and for each package I'm going to
render uh the following div okay inside
there we're going to have H3 which will
be the package name we're going to have
also the package price and the number of
credits the package includes and we're
going to also have an unordered list of
features so I'm going to iterate over
all the features which is passed to the
credit pricing cards
and um then I'm going to render Li for
it and print the feature name okay
however before this feature name I'm
going to also put an SVG and again this
is the same SVG what what uh is
available in the following
template
um right here this one okay cool now if
I scroll down below I'm going to create
four okay so there is this
button uh right here but only button is
not enough I'm going to have a form and
submit that form to
the uh let me close unnecessary files to
this credit controller buy credits and
I'm going to pass the package of which I
want to buy okay so once I have the form
um the action will be wrote credit buy
and I'm going to provide the package
which I want to buy the road does
doesn't exist yet and we're going to
create that no big deal the method is
post and we're going to do traditional
form submission we are not going to do
inertia JS type of form
submission okay then inside this form
we're going to have input type hidden
with csrf token because we're going to
do form submission we need this csrf
token as well okay and I'm going to have
also button with a lot of Talan CSS
classes this is the same button and uh
we have have this get started or
whatever we can call this whatever like
buy more
credits okay so I think this part uh
this component is actually ready and we
are importing this in the uh credit
pricing cards the only thing what we
don't have is rules these credit buy
rules and other rules so we are going to
open web.php and create that rules uh
I'm going to do this inside right here
this out and
verified uh we already have these
feature one and feature two roots and
then at the bottom right here I'm going
to add uh road to buy credits and I'm
going to provide credit controller index
and let's give it also a name credit
index okay I'm going to Define another
rout uh for bu credit success which will
be credit controller success and the
route name will be credit success as
well I'm going to Define in the same way
cancel
root and I'm going to define a post
request for buy credits package okay
this is uh how we're going to redirect
to to
stripe this is going to be credit
controller by credits which is actually
the following method and it has this
credit by which we are using right here
okay so I think this is great and we are
going to also Define web hook regarding
web hook you should have few things uh
in your mind first is that uh stripe
will make request on web hook with the
um as unau unauthenticated user so we
are not going to put this web hook um
right here okay we should put this
outside of any middle we we should put
this right here so this is the first
thing second thing is that we need to
disable and by the way we need to import
this uh crate controller uh so let's
just do the
import here we have that uh so the
second thing is that stripe will make
the post request on the following web
hook URL and we are going to disable
csrf validation for that specific
endpoint so right now I'm in Lal 11 and
Lal 11 has done it slightly differently
so we're going to open app.php from
bootstrap folder okay and here we have
this middle wear and on that middle wear
I am going to execute a method called uh
validate csrf tokens and that
accepts um accepts an accept array so
it's fine so uh the validate CSF token
excepts an array uh and that's going to
be
exclude um roots and that's going to be
buy Das credits SL web hook so the CSI
validation should happen besides that
route okay once I save
this uh I want to open
now feature
jsx and if you scroll down below we have
the following h which I'm going to
change now
into proper root and it's going to
be
root credit
index and I'm going to do something
similar in authenticated
layout uh we have
the where is it right here we have this
uh Slash and we're going to need
root credit do
index so I'm going to save
this and now let's have a look in our
browser okay whenever I click this on
buy more credits uh we have the
following error this
Credit Credit pricing
cards
[Music]
um okay that doesn't exist where did I
create
that credit pricing cards
credit
pricing
cards yep it should be in plural we call
this credits pricing cards and I should
call
this maybe we should even call this
packages pricing cards uh and let's go
into credit index and I'm going to
change this
into packages pricing cards and then
we're going to fix the import packages
pricing cards now let's have a look I'm
going to click this buy more credits and
we are redirected to that page your
credits okay you have zero credits the
more credits you choose the bigger
savings you will make and here we see
the all the plans the packages and we
see also this calculate sum calculate
difference um as separate features
I think this is awesome whenever I click
on this we should be redirected to this
trip
page okay we are redirected this is
awesome and the one last thing is to uh
test the web hook functionality okay so
for this let me open the stripe
dashboard and inside search I'm going to
search for web hooks okay and we're
going to do this local testing so uh I'm
going to do this add local listener I I
whenever I Was preparing for this
project I actually added this already
but I'm going to add this once again
okay so what we need to do first is to
download the CLI from the stripe okay
then we are going to do the stripe login
then we're going to do the stripe uh
forwarding to the local project and then
we're good to go and on the right side
you can also see that uh the the code
which which we wrote in the web hook
okay to get the event and validate
construct the event and validate that
and then do the corresponding things um
for bason even type okay just make sure
you that you have this um stripe CLI so
I'm going to click this download CLI
open this in a new tab okay here we have
a different operating systems and I'm
going to go to Windows and uh we have to
download the following file from GitHub
so I'm going to open this in a new tab
and I'm going to search for The
Following part right there this is it
this is what I'm going to download the
download is going to start I'm going to
do this inside
downloads so here I have downloaded that
zip file I'm going to extract it that
and inside there we have the stripe
xcept okay I'm going to open git bash
right here or you can open CMD and
navigate to the following path the main
think that you're going to have some
terminal you will need that so then
right here in this terminal let me zoom
in uh we are going to log in first of
all based on the um based on the
documentation so I'm going to close
these two tabs okay and we're going to
do stripe login but because we are on
Windows we're going to execute
stripe do XA
login uh what's that I think we need
/ stripe XA
login okay
good now we're going to click on this to
open that stripe dashboard it is opening
and from here we need to log in and it's
prints the following puring code joyful
warm whatever and we have the same code
so I'm going to click on L access access
has been granted let's close this and
right here we can see that we are
authenticated and the key will expire in
90 uh days and now we can do this
forwarding so I'm going to copy that
into clipboard and I'm going
to paste this right here
oops let me copy this and paste here and
we're going to change the port in the
web hook URL so uh any web hooks sent
from stripe will come should come from
Local Host port 8,000 SL
by- credits SL web hook this is the URL
on which we handle the web hook so I'm
going to hit the enter right here sorry
again so do SL
strip.
XM okay let's wait one second and here
we see that the connection has been
submitted and the web hook signing
secret is this so this is what I am
going to copy
this one and this is what I am going to
put
inside in
file for the stripe webook key right
here okay so now I save that and I
should have this web hook opened and
observing that and now I'm going to test
this functionality so this is my
previously open page let me test if this
still valid uh test at example.com we're
going to provide test stripe card
details just make sure you provide any
data in the future any CVC and let's
provide any name here and I'm going to
click on pay and I'm going to open this
web hook um and let's see as you can see
the status code returned from our web
Hook is 200 which means it successfully
processed the incoming request and it
should have up updated the number of
credits on the user so if you open now
in the browser we're going to see that
the user has 20 credits and feature one
and feature two both are actually
available please also keep in mind that
whenever you're doing the stripe
checkout process your computer time
needs to be uh precise basically even
five minutes out of sync your computer
time will cause problems during this
checkout I have this issue personally
that's why I'm telling this to you just
make sure you have the correct time set
on your computer because then the
signature validation inside web hook
simply will fail okay and it will not
succeed okay that's perfect so we have
now implemented this um automatic credit
fing functionality and that's awesome
user can choose any tier they want and
they can fill the number of credits
right there now I'm going to implement
the dashboard inside which I'm going to
show
all the used features the user has
basically used okay so let's open now vs
code and I'm going to generate new
controller for the dashboard and I think
we don't have um dashboard controller
don't we let's check this web
roads where we yeah we don't have the
controller dedicated controller for the
dashboard so let's execute PHP artisan
make control
controller dashboard controller let's
hit the enter the controller was created
this is awesome we are going to display
used features okay so I will need to
also create used feature resource so I'm
going to execute PHP artison make
resource used feature resource let's hit
the enter okay that was also
created
awesome and now we're going to write um
the corresponding Fields right here
we're going to populate the dashboard
controller and I'm going to also open
dashboard js6 and I'm going to render
table right here uh like for the table
I'm going to use also table component
from this flow bite so if I search for
table right here we can click on the ver
first link and uh I'm going to show you
the the uh UI first so this is how table
looks like this is Tyle one CSS table
the First Column basically is a in a
bold in a white color so it has
different styles so if we expand this
code and see right here the First Column
has different styles okay so I'm going
to basically use the same table you can
copy and paste I'm going to quickly um
write it right here okay okay awesome so
let's start with the dashboard
controller we do I have this code I lost
it okay here we go let's create index
function right here and inside there I'm
going to select used features I'm going
to select this used features with
feature because we're going to display
the feature name also in the table then
I'm going to sort them um I'm going to
first first of all filter them by the
currently authed user ID and then I'm
going to sort them by I created a date
okay so I'm selecting all the features
for the current user sorting them latest
used feature at the top and I'm going to
also call paginate so I'm going to get
this paginated response and then I'm
going to render the dashboard jsx
component and I'm going to pass these
used features as a a used feature
resource collection okay so awesome
let's go into uh yeah let's actually
import uh we're going to import the used
feature uh resource and we're going to
need uh the used feature as well and I
think we're going to need to import Ina
as well U right here now let's go into
used feature resource and we are going
to return ID we're going to return
credits we're going to return this
feature which is relation to the feature
object and we're going to pass this into
new feature resource and then this
feature will be an instance of new
feature resource and and we're going to
return create date but we're going to
format this nicely into our own format
and we're going to return the entire
data as well which will be extra
information used for this feature now
let's go into J into dashboard jsx and
first of all I'm going to use uh like
take this prop used features which we
are passing from here okay so we need
this use features then I'm going to
delete that that part completely
uh and I'm going to uh use the template
I mentioned or this table okay so we're
going to need this position relative
overflow X Auto what we have right here
inside there we're going to have table
I'm going to add some t one CSS classes
to this table inside there we're going
to have t head with Ty one CSS classes
again inside there we're going to have
TR and th couple of th's first will be
feature second will be credits then
we're going to have date and finally
we're going to have additional data down
below we're going to have t body as well
and we're going to iterate over used
features data okay this used features is
an instance of a collection so we're
going to take data out of it and then
iterate over the data using map function
and we're going to use that used feature
variable to render TRS so inside each TR
we're going to add key we're going to
add Talon CSS classes to each TR and
then we're going to display play uh the
in the first the first element of this
TR basically will be th okay this will
be in a different color as it is written
right here so the th will have its own
different uh Talon CSS classes and then
we're going to display the used feature
do feature which is relation to feature
do name after th we're going to display
a used feature number of credits we're
going to display used feature created
that and then we're going to display
used feature. data so those are all the
properties which we returned inside our
resource okay and down below I'm going
to do one check if the used feature data
length does not exist which means that
if the user doesn't have any features
used yet I'm going to display another TR
and inside the TR we're going to have TD
with call span 4 basically I'm going to
combine all the four columns uh with
text Center and padding and inside there
I'm going to display you don't have used
any features
yet okay that's going to be for new
users now I'm going to save this let's
open web.php I'm going to remove this
function and I'm going to replace this
with dashboard
controller
index uh just make sure we have the
dashboard controller imported right here
this is awesome we have that now if I
save this actually because we need the
same middle Weare in the dashboard
controller maybe we can just remove
middle wear from here and maybe we can
just take this out and insert this
entire this group without and verified
middle wear I'm going to paste this
right here and let's move this name down
below okay cool now let's open dashboard
and have a look here we see the table so
here we see the future uh feature name
calculate difference we see sum whatever
number of credits the feature required
at the time the date when it was used
but we don't see anything inside
additional data that's strange let's go
into dashboard jsx and have a look we
have this used feature data let's
actually print entire used feature using
Json
stringify and I'm going to print the
entirely used feature let's see what we
have here we have ID we have the
feature uh we have created it but the
data is null now let's check the
database what is data
there uh okay so let's access the
database using
Tinker
up models oops excuse me so up
moduls used
feature let's get
all okay the data is null in the
database for all of
them okay why is this is this null don't
we save it or maybe there's some issue
When selecting the data I'm going to
open uh I'm going to open um used
feature class and here we have this uh
cast in to data array I think the reason
is that we don't have data inside
fillable but we are actually filling
that right here through this used
feature create so we just need to put
data right here let's save this and
let's test the functionality so I'm
going to open feature one provide two
numbers hit on calculate that was
calculated let's go into dashboard and
here we see data which contains number
one and number number two let's go into
dashboard js6 and let's undo right here
and just print feature. data and we
have uh and we have
error actually that's strange what error
do we have let's see okay I see what
error do we have so the uh use feature
data is actually an array in order us to
be able to print that nicely we need to
use Json stringify again you can render
this data as you like okay you can
iterate over the keys of that used
feature data and render it if you if it
contains like um processed image paths
you can obviously render images or you
can add um additional link let me reload
the page and close these developer tools
uh you can also put additional link to
view details of the specific feature and
if that additional data contains as
image paths you can display that images
inside Details page okay so just the
main idea is that we have all the
information about uh how the user used
the specific feature what data was
provided we can even save result right
here you can easily do this in the um
feature One controller let's open this
and give you hint so you can calculate
some of these two numbers at at the top
of this used feature create function and
and you can put this in the result
variable and you can put that result
into Data as well and pass the result
right here so you can put the actual
result of the feature inside data and
save this in the database as well it's
it's it's up to you how you're going to
decide but we have the dashboard which
displays all that information um we
don't have the pagination I'm not going
to implement the pagination but you have
everything what you need if you uh see
what is this used features right here it
basically is an object which contains
let me stringify this for you so it
contains uh data which we already
iterated but it contains also additional
information such as where it
is it contains some meta information and
that meta contains what is the current
page from to it contains all the
pagination links okay you just need to
iterate the those meta links and render
them nicely uh I'm just going to provide
right here undefined and two and now we
have this um much more um nicely
rendered actually if you want to see how
to implement the pagination as well you
can check my other projects with Lal and
react I have a couple of projects
already and those include the pagination
part as well but it's pretty
straightforward that's why I'm not going
to spend uh more time on this specific
feature let me remove this pre right now
and we're going to have this table
remaining now the last thing I'm going
to do is I'm going to change the
homepage which right now displays this
uh updated L 11 homepage and instead I'm
going to display uh cards like similar
to this lost card and I'm going to
display one card for each feature and
for this I'm going to create a new
controller for the homepage and I'm I'm
going to also update the root right here
instead of this I'm going to render
those
features okay I'm going to close every
other Tab and I'm going to create Now
new controller home controller PHP
artisan make controller home controller
let's hit the enter let's open the home
controller and right here I'm going to
Define index function and inside there
I'm going to uh do the
following first of all I'm going to
select all the features uh not all all
but I'm going to select only active
features if the feature is disabled we
don't want it to be displayed on the
homepage then I'm going to use this
inertia render uh rendering the welcome
jsx component and we're going to pass
these features uh as through this uh
feature resource collection but we're
going to also pass two additional
variables which are by itself passed
from uh from here which comes with the
L's default installation can login and
can register so we're going to pass
those two variables as well however we
don't need this L Val version and PHP
version and I'm going to remove that so
right here we're going to pass can login
and can register okay and at the top
let's import uh we need a feature
resource we need feature model we need
this uh rout fac side and we also need
inertia class to render this welcome js6
okay let's go into web PHP and I'm going
to remove this function and I'm going to
change this into home controller class
index name home okay and right here we
don't need inertia and we don't need
application so I can remove them already
and we need to open welcome js6 so right
now the Lal go to view extension refers
to Blade file file if I control and
click on this it's going to open the
blade file excuse
me but we don't need this blade file
what we want is jsx file so I'm going to
open welcome jsx and I'm going to work
right here if you scroll down below uh
and analyze this a little bit so this is
again updated to welcome jsx file which
is in the latest L version so here we
have this image which I think is the
background image which we can actually
leave
let's open this yeah we can leave that
and then we have this div the main div
inside there we have uh another div
inside there we have this header section
we're going to leave that header section
and inside there we have one div for the
uh laravel official documentation then
another D which is going to be uh for
laracast another one and four divs
basically there are still four divs like
it was previously but just the layout is
slightly different this one will have
some Rose spine or something like
this okay now let me remove the first um
first documentation div and if we check
right now the homepage we don't see this
documentation div anymore okay and I'm
going to delete others as well and what
I'm going to do is um we just left only
one okay which is perfectly fine we can
remove this F uh footer as well because
we don't pass this Lal version in PHP
version as well so I'm going to remove
this from footer as well we can leave
this logo or we can remove it's up to us
but we are going to accept let's remove
these props we are going to accept
features as prop and the features uh
we're going to render right here so
features.
data. map we're going to get
feature and for each feature we are
going to render the following a tag so
I'm going to save this I just saved and
it was formatted nicely let me collapse
this and if we check right now on the
homepage we're going to see two
identical divs because we have two uh
features actually and we are uh
rendering two divs right here now let's
adjust the image and adjust this H ref
as well uh so this is actually a tag but
I'm going to change this into link okay
and we need to import that link right
here inside this inertia JS react which
is already
imported next we need to provide right
here feature dot root name okay now
whenever we click on this it will have
if you m if you uh if I Mouse over
you're going to see in the bottom left
corner the URL so it is feature one.
index uh sorry so that should be we
we're going to use Road and pass this
feature rot name to that so now we see
feature one as a URL and feature two as
a URL right here okay let's scroll down
below and here we have this SVG which is
I think the logo not the logo but the
actual um icon so instead of that
SVG uh I'm thinking about putting an
image right here because we have images
for each feature so image and inside
source I'm going to provide
feature. image that's going to be
probably large image oh no it is
actually perfectly fine so this is the
feature image for the um calculate sum
this is for the calculate difference and
let's finalize this right now so we're
going to Output feature. name right here
and here we're going to Output uh
feature.
description so down below we have this
SVG path something which we can leave
this I think this Arrow so now we have
two features on the homepage calculate
sum which opens this feature go back and
calculate difference which opens the
feature to and I think this finalizes
our project we have this nice homepage
where we list and show all the features
again you obviously need to implement
more complex and sophisticated features
something people Worth to pay some money
for it you can put them on your homepage
then on the dashboard user can see the
use features we have the feature Pages
itself and whenever user runs out with
its credit they can buy the predefined
package uh with the following price and
the following number of credits this is
awesome project and we also have this uh
Lal brid profile management right here
all right that's it my friends and I
hope you learned something new please
hit the like button and subscribe if you
are not yet for more videos like this
also let me know your thoughts about
this project in the comment section down
below if you want to support the channel
you can check my website the cool.com
you can buy my course or you can check
my patreon page as well thanks for
watching I appreciate your comments your
likes uh Your Love simply and I will see
you in another video
