Skip to content

Commit

Permalink
Shop cart implementation 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanyshak committed Jun 16, 2021
1 parent c29eef6 commit 59ac214
Show file tree
Hide file tree
Showing 24 changed files with 261 additions and 22 deletions.
25 changes: 25 additions & 0 deletions app/assets/stylesheets/app/base/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,28 @@ q {
.pk-no-display {
display: none !important;
}

.shopping_cart-icon {
display: inline-block;
position: fixed;
left: 1450px;
opacity: 80%;

&:hover {
opacity: 100%;
}
}

.cart_table {
margin: 40px;

table {
border-collapse: collapse;
width: 100%;
}

th, td {
text-align: left;
padding: 8px;
}
}
3 changes: 0 additions & 3 deletions app/views/layouts/app/_header.slim
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,5 @@ header.pk-header class="#{header_classlist.compact.join(' ')}"
li.pk-header__li-list-item = register_link
li.pk-header__li-list-item = login_link

li.pk-list__unit
= link_to supporters_path do
i.fas.fa-shopping-cart.fa-2x
li.pk-list__unit
= support_us_link(class: 'btn pk-btn--green-bg donate-btn')
9 changes: 9 additions & 0 deletions components/shop/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
carrierwave (1.3.2)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
ssrf_filter (~> 1.0)
coderay (1.1.3)
concurrent-ruby (1.1.8)
crass (1.0.6)
Expand Down Expand Up @@ -125,6 +130,9 @@ GEM
mini_mime (>= 0.1.1)
marcel (1.0.1)
method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0225)
mini_mime (1.1.0)
minitest (5.14.4)
nenv (0.3.0)
Expand Down Expand Up @@ -219,6 +227,7 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.4.2)
ssrf_filter (1.0.7)
temple (0.8.2)
thor (1.1.0)
thread_safe (0.3.6)
Expand Down
4 changes: 4 additions & 0 deletions components/shop/app/controllers/shop/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ module Shop
class BaseController < ApplicationController
before_action :authenticate_user!

def current_order
session[:order_id] ? Shop::Order.find(session[:order_id]) : []
end

private

def render_form
Expand Down
1 change: 1 addition & 0 deletions components/shop/app/controllers/shop/items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module Shop
class ItemsController < BaseController
helper_method :items
helper_method :current_order

# @deprecated
# def add_to_cart
Expand Down
26 changes: 24 additions & 2 deletions components/shop/app/controllers/shop/order_items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,42 @@
module Shop
class OrderItemsController < BaseController
helper_method :item
helper_method :order_items
helper_method :current_order

def index
def create
order_item = ::Shop::OrderItem.new(item_id: item.id, order_id: order_id, price: item.price)
order_item.save

redirect_to shop_items_path
end

def update
order_item.increase_quantity!
redirect_to shop_order_items_path
end

def destroy
order_item.reduce_quantity!
redirect_to shop_order_items_path
end

private

def order_items
order_items = Shop::OrderItem.includes(:item)
end

def order_item
@order_items ||= Shop::OrderItem.find(params[:id])
end

def item
@items ||= Shop::Item.find(params[:id])
@items ||= Shop::Item.find(params[:item_id])
end

def order_id
session[:order_id] ||= Shop::Order.create.id
end
end
end
6 changes: 6 additions & 0 deletions components/shop/app/helpers/shop/item_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module Shop
module ItemHelper
end
end
1 change: 1 addition & 0 deletions components/shop/app/models/shop/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Item < ApplicationRecord
self.table_name = 'shop_items'

has_many :item_images
has_many :order_items
accepts_nested_attributes_for :item_images

scope :active, -> { where(published: true) }
Expand Down
11 changes: 9 additions & 2 deletions components/shop/app/models/shop/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ module Shop
class Order < ApplicationRecord
self.table_name = 'shop_orders'

enum status: { shopping_cart: 0, placed: 1, processing: 2, shipping: 3, complete: 4, canceled: 5 }

has_many :order_items
has_many :items, through: :order_items

def total_sum
order_items.map(&:price).sum.to_f
end

def total
@totoal ||= 0
def order_items_count
order_items.count
end
end
end
32 changes: 27 additions & 5 deletions components/shop/app/models/shop/order_item.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
# frozen_string_literal: true

# item_id
# qty
# price

module Shop
class OrderItem < ApplicationRecord
self.table_name = 'shop_orders'
self.table_name = 'shop_order_items'

validates_uniqueness_of :item_id

belongs_to :order
belongs_to :item

def increase_quantity!
self.quantity += 1
update_price(quantity)
save!
end

def reduce_quantity!
if self.quantity > 1
self.quantity -= 1
update_price(quantity)
save!
else
delete_order_item
end
end

def delete_order_item
destroy!
end

def update_price(qty)
self.price = item.price * qty
end
end
end
4 changes: 3 additions & 1 deletion components/shop/app/uploaders/item_image_uploader.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# frozen_string_literal: true

class ItemImageUploader < CarrierWave::Uploader::Base
end
end
15 changes: 14 additions & 1 deletion components/shop/app/views/shop/items/index.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
h2.main-header Shop

- if current_order.present?
span.shopping_cart-icon
= link_to shop_order_items_path do
i.fas.fa-shopping-cart.fa-8x
div.item_counts
span
= current_order.order_items_count

.main
ul.cards
- items.each do |item|
Expand All @@ -9,4 +17,9 @@ h2.main-header Shop
.card_content
h2.card_title = item.name
p.card_text = item.description
button.btn.card_btn Add to cart
- if current_order.present? && current_order.items.include?(item)
= link_to shop_order_items_path do
button.btn.card_btn Added to the cart
- else
= link_to shop_order_items_path(item_id: item.id), method: :post do
button.btn.card_btn Add to cart
32 changes: 32 additions & 0 deletions components/shop/app/views/shop/order_items/index.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
h2.main-header Cart

.cart_table
- if current_order.present? && current_order.order_items.any?
table
thead
tr
th Image
th.company Name
th.company Price
th.count Count
tbody
- order_items.each do |item|
tr
td= image_tag item.item.item_images.first.image_url(:small).to_s, class: 'card_image' if item.item.item_images.first.try(:image_url)
td= item.item.name
td= item.price
td
div
= link_to shop_order_item_path(item.id), method: :delete do
i.fas.fa-minus

= item.quantity

= link_to shop_order_item_path(item.id), method: :put do
i.fas.fa-plus

.total_sum
h2 Total
h2= current_order.total_sum
- else
h1 Your cart is empty for now
2 changes: 1 addition & 1 deletion components/shop/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Rails.application.routes.draw do
namespace :shop do
resources :items, only: %i[index]
resources :order_items, only: %i[index update destroy]
resources :order_items, only: %i[index create update destroy]
end

namespace :admin do
Expand Down
10 changes: 10 additions & 0 deletions components/shop/db/migrate/20210611210804_create_orders.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class CreateOrders < ActiveRecord::Migration[5.2]
def change
create_table :shop_orders do |t|
t.integer :status, default: 0
t.text :shipment_address
end
end
end
12 changes: 12 additions & 0 deletions components/shop/db/migrate/20210611211002_create_order_items.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class CreateOrderItems < ActiveRecord::Migration[5.2]
def change
create_table :shop_order_items do |t|
t.integer :quantity, default: 1
t.decimal :price, null: false
t.references :item
t.references :order
end
end
end
2 changes: 1 addition & 1 deletion components/shop/shop.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ Gem::Specification.new do |spec|

spec.add_dependency 'rails', '~> 5.2.2', '>= 5.2.2.1'

spec.add_dependency 'carrierwave', '~> 1.2'
spec.add_dependency 'friendly_id'
spec.add_dependency 'kaminari'
spec.add_dependency 'simple_form'
spec.add_dependency 'slim-rails'
spec.add_dependency 'carrierwave', '~> 1.2'

spec.add_development_dependency 'capybara'
spec.add_development_dependency 'faker'
Expand Down
16 changes: 15 additions & 1 deletion components/shop/spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20_210_514_113_103) do
ActiveRecord::Schema.define(version: 20_210_611_211_002) do
create_table 'shop_item_images', force: :cascade do |t|
t.string 'image'
t.integer 'item_id'
Expand All @@ -30,4 +30,18 @@
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
end

create_table 'shop_order_items', force: :cascade do |t|
t.integer 'quantity'
t.decimal 'price', null: false
t.integer 'item_id'
t.integer 'order_id'
t.index ['item_id'], name: 'index_shop_order_items_on_item_id'
t.index ['order_id'], name: 'index_shop_order_items_on_order_id'
end

create_table 'shop_orders', force: :cascade do |t|
t.integer 'status', default: 0
t.text 'shipment_address'
end
end
7 changes: 7 additions & 0 deletions components/shop/spec/factories/order_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

FactoryBot.define do
factory :order, class: Shop::Order do
shipment_address { 'Lviv, Pivorak street' }
end
end
7 changes: 7 additions & 0 deletions components/shop/spec/factories/order_item_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

FactoryBot.define do
factory :order_item, class: Shop::OrderItem do
price { 12 }
end
end
16 changes: 15 additions & 1 deletion components/shop/spec/features/shop/add_to_cart_spec.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
# frozen_string_literal: true
# TODO

require 'rails_helper'

RSpec.describe '/shop' do
let!(:active_item) { create(:item, published: true) }

scenario 'display items' do
visit shop_items_path

click_button 'Add to cart'

expect(page).to have_current_path '/shop/items'
# expect(page).to have_button('Added to the cart')
end
end
4 changes: 2 additions & 2 deletions components/shop/spec/features/shop/home_page_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
let!(:item_b) { create(:item, published: false) }

scenario 'display items' do
visit admin_shop_items_path
visit shop_items_path

expect(page).to have_content item_a.name
expect(page).to have_content item_b.name
expect(page).to have_button('Add to cart')
end
end
end
Loading

0 comments on commit 59ac214

Please sign in to comment.