From 3bdc8783461a1f63318a5efc8a2d7b1be120c54e Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Thu, 12 Aug 2021 14:58:05 -0700 Subject: [PATCH] feat: setup cart page --- app/src/components/LayoutHeader.vue | 2 +- app/src/router/index.ts | 1 + app/src/types/index.ts | 5 +++ app/src/utils/utils.ts | 11 +++---- app/src/views/Cart.vue | 47 +++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 app/src/views/Cart.vue diff --git a/app/src/components/LayoutHeader.vue b/app/src/components/LayoutHeader.vue index efae7a96..a94cb690 100644 --- a/app/src/components/LayoutHeader.vue +++ b/app/src/components/LayoutHeader.vue @@ -53,7 +53,7 @@ import { ExclamationIcon } from '@heroicons/vue/solid'; const navigation = [ { name: 'Home', href: '/' }, { name: 'About', href: '/about' }, - { name: 'Docs', href: '/docs' }, + { name: 'Cart', href: '/cart' }, { name: 'Contact', href: '/contact' }, ]; diff --git a/app/src/router/index.ts b/app/src/router/index.ts index 07951a3f..a6a6d1ef 100644 --- a/app/src/router/index.ts +++ b/app/src/router/index.ts @@ -12,6 +12,7 @@ import Home from '../views/Home.vue'; const routes: Array = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', component: () => import('../views/About.vue') }, + { path: '/cart', name: 'Cart', component: () => import('../views/Cart.vue') }, { path: '/dgrants', name: 'dgrants', component: () => import('../views/GrantRegistryList.vue') }, { path: '/dgrants/new', name: 'dgrants-new', component: () => import('../views/GrantRegistryNewGrant.vue') }, { path: '/dgrants/:id', name: 'dgrants-id', component: () => import('../views/GrantRegistryGrantDetail.vue') }, diff --git a/app/src/types/index.ts b/app/src/types/index.ts index ff4bb9cf..95a08745 100644 --- a/app/src/types/index.ts +++ b/app/src/types/index.ts @@ -1 +1,6 @@ // App-specific type definition go here +export type CartItemOptions = { + grantId: string; + contributionTokenAddress: string; // store address instead of TokenInfo to reduce localStorage size used + contributionAmount: string; +}; diff --git a/app/src/utils/utils.ts b/app/src/utils/utils.ts index 2e9ea4d8..597b3c61 100644 --- a/app/src/utils/utils.ts +++ b/app/src/utils/utils.ts @@ -4,6 +4,7 @@ import router from 'src/router/index'; import { RouteLocationRaw } from 'vue-router'; import { BigNumber, isAddress, parseUnits } from 'src/utils/ethers'; +import { CartItemOptions } from 'src/types'; import { BigNumberish, Contract, ContractTransaction } from 'ethers'; import { Grant, GrantRound } from '@dgrants/types'; @@ -45,14 +46,9 @@ export function isValidAddress(val: string | undefined) { const CART_KEY = 'cart'; const DEFAULT_CONTRIBUTION_TOKEN_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; // DAI const DEFAULT_CONTRIBUTION_AMOUNT = parseUnits('5', 18).toString(); // DAI has 18 decimals -type CartItem = { - grantId: string; - contributionTokenAddress: string; // store address instead of TokenInfo to reduce localStorage size used - contributionAmount: string; -}; // Loads cart data -export function loadCart(): CartItem[] { +export function loadCart(): CartItemOptions[] { // Return empty array if nothing found const rawCart = localStorage.getItem(CART_KEY); if (!rawCart) return []; @@ -67,7 +63,8 @@ export function loadCart(): CartItem[] { } // Adds a grant to the cart -export function addToCart(grant: Grant) { +export function addToCart(grant: Grant | null | undefined) { + if (!grant) return; // null and undefined input types are to avoid lint errors when calling this from a template // If this grant is already in the cart, do nothing const cart = loadCart(); if (cart.map((grant) => grant.grantId).includes(grant.id.toString())) return; diff --git a/app/src/views/Cart.vue b/app/src/views/Cart.vue new file mode 100644 index 00000000..9baedf1f --- /dev/null +++ b/app/src/views/Cart.vue @@ -0,0 +1,47 @@ + + +