-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
434 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
class CouponsController < ApplicationController | ||
before_action :authenticate_user! | ||
before_action :set_coupon, only: [:show, :edit, :update, :destroy] | ||
|
||
def index | ||
@profile = User.find_by(username: params[:id] || params[:user_id]) | ||
|
||
@coupons = current_user.coupons | ||
end | ||
|
||
def show | ||
end | ||
|
||
def new | ||
@coupon = current_user.coupons.new | ||
end | ||
|
||
def create | ||
@coupon = current_user.coupons.new(coupon_params) | ||
|
||
if @coupon.save | ||
redirect_to user_coupon_path(current_user.username, @coupon), notice: 'Coupon was successfully created.' | ||
else | ||
render :new, status: 422 | ||
end | ||
end | ||
|
||
def edit | ||
end | ||
|
||
def update | ||
if @coupon.update(coupon_params) | ||
redirect_to user_coupon_path(current_user.username, @coupon), notice: 'Coupon was successfully updated.' | ||
else | ||
render :edit | ||
end | ||
end | ||
|
||
def destroy | ||
@coupon.destroy | ||
redirect_to user_coupons_path(current_user.username), notice: 'Coupon was successfully destroyed.' | ||
end | ||
|
||
private | ||
|
||
def set_coupon | ||
@coupon = current_user.coupons.find(params[:id]) | ||
end | ||
|
||
def coupon_params | ||
params.require(:coupon).permit(:code, :discount_type, :discount_amount, :expires_at) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module CouponsHelper | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# app/models/coupon.rb | ||
class Coupon < ApplicationRecord | ||
belongs_to :user | ||
has_many :products | ||
|
||
validates :code, presence: true, uniqueness: true | ||
validates :discount_type, presence: true | ||
validates :discount_amount, presence: true, numericality: { greater_than: 0 } | ||
validates :expires_at, presence: true | ||
|
||
enum discount_type: { percentage: 'percentage', fixed_amount: 'fixed_amount' } | ||
|
||
scope :active, -> { where('expires_at > ?', Time.current) } | ||
|
||
after_create :create_stripe_coupon | ||
before_destroy :delete_stripe_coupon | ||
|
||
def active? | ||
expires_at > Time.current | ||
end | ||
|
||
private | ||
|
||
def create_stripe_coupon | ||
stripe_coupon = if percentage? | ||
Stripe::Coupon.create({ | ||
percent_off: discount_amount, | ||
duration: 'once', | ||
id: code | ||
}) | ||
else | ||
Stripe::Coupon.create({ | ||
amount_off: (discount_amount * 100).to_i, # Convert to cents | ||
currency: 'usd', | ||
duration: 'once', | ||
id: code | ||
}) | ||
end | ||
|
||
update(stripe_id: stripe_coupon.id) | ||
rescue Stripe::StripeError => e | ||
errors.add(:base, "Stripe error: #{e.message}") | ||
throw :abort | ||
end | ||
|
||
def delete_stripe_coupon | ||
Stripe::Coupon.delete(stripe_id) if stripe_id.present? | ||
rescue Stripe::StripeError => e | ||
Rails.logger.error "Failed to delete Stripe coupon: #{e.message}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<tr> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-default sm:pl-0"> | ||
<%= coupon.code %> | ||
</td> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-default sm:pl-0"> | ||
<%= coupon.discount_type.titleize %> | ||
</td> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-default sm:pl-0"> | ||
<%= number_to_currency(coupon.discount_amount) %> | ||
</td> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-default sm:pl-0"> | ||
<%= coupon.expires_at.strftime("%B %d, %Y at %I:%M %p") %> | ||
</td> | ||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-default sm:pl-0"> | ||
|
||
<%= link_to 'View', user_coupon_path(current_user.username, coupon), class: 'btn btn-sm btn-info' %> | ||
<%= link_to 'Edit', edit_user_coupon_path(current_user.username, coupon), class: 'btn btn-sm btn-warning' %> | ||
<%= link_to 'Delete', user_coupon_path(current_user.username, coupon), method: :delete, data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, class: 'btn btn-sm btn-danger' %> | ||
</td> | ||
</tr> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!-- app/views/coupons/_form.html.erb --> | ||
<%= form_with(model: coupon, url: coupon.new_record? ? user_coupons_path(current_user.username) : user_coupon_path(current_user.username, coupon), local: true, data: {turbo_frame: "_top"}) do |form| %> | ||
|
||
<div class="field space-y-2"> | ||
<%= form.text_field :code, class: 'form-control' %> | ||
<%= form.label :discount_type %> | ||
<%= form.select :discount_type, Coupon.discount_types.keys.map { |type| [type.titleize, type] }, {}, class: 'form-control' %> | ||
<%= form.number_field :discount_amount, step: 0.01, class: 'form-control' %> | ||
<%= form.label :expires_at %> | ||
<%= form.datetime_local_field :expires_at, class: 'form-control' %> | ||
<%= form.submit class: 'btn btn-primary' %> | ||
</div> | ||
|
||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<div class="space-y-2 mx-auto max-w-lg"> | ||
|
||
<h1 class="text-lg">Edit Coupon</h1> | ||
|
||
<%= render 'form', coupon: @coupon %> | ||
<%= link_to 'Show', user_coupon_path(current_user.username, @coupon), class: 'btn btn-info' %> | | ||
<%= link_to 'Back to Coupons', user_coupons_path(current_user.username), class: 'btn btn-secondary' %> | ||
|
||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
|
||
<div class="bg-default"> | ||
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl lg:px-8"> | ||
|
||
<div class="flex items-center justify-between"> | ||
<h2 class="text-xl font-bold text-default"> | ||
<%= link_to user_path(current_user.username), class: "text-brand-600 flex items-center space-x-2" do %> | ||
<%= heroicon("chevron-left") %> | ||
<%= current_user.username %> | ||
<% end %> | ||
Coupons | ||
</h2> | ||
|
||
<div class="mt-6 mb-8"> | ||
<%= link_to 'New Coupon', new_user_coupon_path(current_user.username), | ||
class: 'button-sm-outline' %> | ||
</div> | ||
</div> | ||
|
||
|
||
|
||
<% if current_user == @profile %> | ||
<nav class="-mb-px flex space-x-8 text-2xl items-center" aria-label="Tabs"> | ||
<%= link_to "Products", user_products_path(current_user.username), class: "tab-default" %> | ||
<%= link_to "Coupons", user_coupons_path(current_user.username), class: "tab-active" %> | ||
</nav> | ||
<% end %> | ||
|
||
|
||
<div class="mt-4"> | ||
|
||
<table class="min-w-full divide-y divide-subtle"> | ||
<thead> | ||
<tr> | ||
<th class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-default sm:pl-0">Code</th> | ||
<th class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-default sm:pl-0">Discount Type</th> | ||
<th class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-default sm:pl-0">Discount Amount</th> | ||
<th class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-default sm:pl-0">Expires At</th> | ||
<th class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-default sm:pl-0">Actions</th> | ||
</tr> | ||
</thead> | ||
|
||
<tbody class="divide-y divide-muted"> | ||
<% @coupons.each do |coupon| %> | ||
<%= render "coupon", coupon: coupon %> | ||
<% end %> | ||
</tbody> | ||
</table> | ||
|
||
</div> | ||
|
||
<% if @coupons.blank? %> | ||
<p class="p-4 text-muted">No coupons found</p> | ||
<% end %> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
<div class="space-y-2 mx-auto max-w-lg"> | ||
|
||
<h1 class="text-lg">New Coupon</h1> | ||
|
||
<%= render 'form', coupon: @coupon %> | ||
<%= link_to 'Back to Coupons', user_coupons_path(current_user.username), class: 'btn btn-secondary' %> | ||
|
||
</div> |
Oops, something went wrong.