Skip to content

Commit

Permalink
cart v1
Browse files Browse the repository at this point in the history
  • Loading branch information
andre-brandao committed Aug 6, 2024
1 parent 5771f09 commit 506c698
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 15 deletions.
75 changes: 75 additions & 0 deletions src/lib/components/navbar/Cart.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<script>
import { getCartContext } from '$lib/stores/cart'
import { getImagePath } from '$utils/image'
import { icons } from '$utils'
const cart = getCartContext()
$: subtotal = $cart.reduce(
(acc, item) => acc + item.quantity * item.item.retail_price,
0,
)
</script>

<div class="flex-none">
<div class="dropdown dropdown-end">
<div tabindex="0" role="button" class="btn btn-circle btn-ghost">
<div class="indicator">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"
/>
</svg>
<span class="badge indicator-item badge-sm">{$cart.length}</span>
</div>
</div>
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
<div
tabindex="0"
class="card dropdown-content card-compact z-[1] mt-3 w-72 bg-base-100 shadow"
>
<div class="card-body">
<span class="text-lg font-bold">{$cart.length} Items</span>
<!-- TODO: format price -->
<span class="text-info">Subtotal: {subtotal}</span>
<div class="card-actions">
{#each $cart as item}
<div class="flex items-center justify-between gap-2">
<img
src={getImagePath(item.item.image)}
alt={item.item.name}
class="h-10 w-10 rounded-lg"
/>

<div class="flex w-full justify-between p-1">
<div class="font-bold">{item.quantity} x</div>
<div>{item.item.name}</div>
</div>

<button
class="btn btn-error"
onclick={() => cart.removeItem(item.item.id)}
>
{@html icons.trash()}
</button>
</div>
{/each}
{#if $cart.length === 0}
<p class="text-center">No items in cart</p>
{:else}
<button class="btn btn-outline w-full">Checkout</button>
{/if}
</div>
</div>
</div>
</div>
</div>
14 changes: 8 additions & 6 deletions src/lib/components/navbar/NavBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { User } from 'lucia'
import ThemeSwiter from './ThemeSwiter.svelte'
import ChangeLanguage from './ChangeLanguage.svelte'
import Cart from './Cart.svelte'
import { website } from '$lib/config'
Expand All @@ -18,7 +19,7 @@
async function logout() {
user.set(null)
await trpc($page).auth.logOut.query()
goto("/")
goto('/')
}
</script>

Expand Down Expand Up @@ -48,11 +49,12 @@
</svg>
</label>
</div>
<div class="mx-2 flex-1 px-2 ">
<a href="/" class="btn btn-ghost text-xl max-sm:hidden">{website.siteShortTitle}</a>
<div class="mx-2 flex-1 px-2">
<a href="/" class="btn btn-ghost text-xl max-sm:hidden">
{website.siteShortTitle}
</a>
</div>


<div class="hidden flex-none lg:block">
<ul class="menu menu-horizontal space-x-1">
<!-- Navbar menu content here -->
Expand All @@ -61,8 +63,6 @@
</div>

<div class="flex-none gap-2">


{#if $user}
<div class="dropdown dropdown-end dropdown-hover">
<div tabindex="0" role="button" class="btn m-1">
Expand All @@ -83,6 +83,8 @@
<a class="btn" href="/login">{@html icons.login()}Login</a>
{/if}

<Cart />

<ThemeSwiter />

<ChangeLanguage />
Expand Down
17 changes: 16 additions & 1 deletion src/lib/server/db/schema/customer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ export const customerRelations = relations(customerTable, ({ one, many }) => ({
}),
}))
export const insertCustomerSchema = createInsertSchema(customerTable, {})
export const updateCustomerSchema = insertCustomerSchema.pick({
birth_date: true,
cellphone: true,
cpf_cnpj: true,
rg_ie: true,
email: true,
name: true,
phone: true,
is_retail: true,
max_credit: true,
used_credit: true,
})
export type SelectCustomer = typeof customerTable.$inferSelect
export type InsertCustomer = typeof customerTable.$inferInsert

Expand All @@ -61,7 +73,10 @@ export const addressTable = sqliteTable('address', {
})

export const addressRelations = relations(addressTable, ({ one, many }) => ({
customer: one(customerTable),
customer: one(customerTable, {
fields: [addressTable.customer_id],
references: [customerTable.id],
}),
orders: many(customerOrderTable),
}))
export const insertAddressSchema = createInsertSchema(addressTable)
Expand Down
54 changes: 54 additions & 0 deletions src/lib/stores/cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { writable } from 'svelte/store'
import { getContext, setContext } from 'svelte'
import type { SelectProductItem } from '$db/schema'
const CART_STORE_KEY = 'cart'

type Cart = {
item: SelectProductItem
quantity: number
}[]

function createCartStore(base_cart: Cart = []) {
const { set, subscribe, update } = writable<Cart>(base_cart)
return {
set,
subscribe,
update,
addItem: (input: { item: SelectProductItem; quantity: number }) => {
update(cart => {
const existing = cart.findIndex(i => i.item.id === input.item.id)
if (existing !== -1) {
cart[existing].quantity += input.quantity
} else {
cart.push(input)
}
return cart
})
},
setItem: (input: { item: SelectProductItem; quantity: number }) => {
update(cart => {
const existing = cart.findIndex(i => i.item.id === input.item.id)
if (existing) {
cart[existing].quantity = input.quantity
} else {
cart.push(input)
}
return cart
})
},
removeItem: (item_id: number) => {
update(cart => {
return cart.filter(i => i.item.id !== item_id)
})
},
}
}

export function createCartContext(cart: Cart = []) {
const store = createCartStore(cart)
return setContext(CART_STORE_KEY, store)
}

export function getCartContext(): ReturnType<typeof createCartStore> {
return getContext(CART_STORE_KEY)
}
2 changes: 2 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import NavBar from '$lib/components/navbar/NavBar.svelte'
// STORE
import { createUserContext } from '$lib/stores/user'
import { createCartContext } from '$lib/stores/cart'
// COMPONENTS
import { ModalContainer } from '$lib/components/modal'
import DrawerContainer from '$lib/components/drawer/base/DrawerContainer.svelte'
Expand All @@ -21,6 +22,7 @@
const user = createUserContext(data.user)
$: user.set(data.user)
const cart = createCartContext()
onMount(() => {
changeTheme('bumblebee')
Expand Down
34 changes: 26 additions & 8 deletions src/routes/products/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
import { icons } from '$lib/utils/icons'
import Detail from '$components/detail/Detail1.svelte'
import { tweened } from 'svelte/motion'
import { getCartContext } from '$lib/stores/cart'
const cart = getCartContext()
console.log(cart)
export let data: PageData
const { produto } = data
Expand All @@ -18,12 +23,23 @@
let activeItemIndex = 0
// let total = tweened(
// (variants[activeEntry].price[activePrice]?.price_value ?? 0) * quantity,
// {
// duration: 300,
// },
// )
let total = tweened(
(produto.items[activeItemIndex].retail_price ?? 0) * quantity,
{
duration: 300,
},
)
$: $total = (produto.items[activeItemIndex].retail_price ?? 0) * quantity
function addToCart() {
console.log(cart)
cart.addItem({
item: produto.items[activeItemIndex],
quantity: quantity ?? 1,
})
quantity = 1
}
</script>

<section class="body-font overflow-hidden">
Expand Down Expand Up @@ -81,7 +97,7 @@
</div>
<div class="flex items-center justify-between">
<span class="title-font text-2xl font-bold">
${'TODO'}
${$total.toFixed(2)}
</span>
<div class="flex items-center gap-4">
<button
Expand All @@ -100,7 +116,9 @@
></path>
</svg>
</button>
<button class="btn btn-primary flex">Add to cart</button>
<button class="btn btn-primary flex" onclick={addToCart}>
Add to cart
</button>
</div>
</div>
</div>
Expand Down

0 comments on commit 506c698

Please sign in to comment.