Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Andy/store item page #94

Merged
merged 106 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
de74b0b
Rough outline of SizeSelector
WishingWell13 Nov 14, 2023
b79de60
Created a file to represent the item page
WishingWell13 Nov 28, 2023
092c092
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Nov 28, 2023
3701562
Edited config file to be nested under "Store" header
WishingWell13 Nov 28, 2023
517ad64
Size Toggle V1, Styling Only
WishingWell13 Dec 18, 2023
557e125
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Dec 18, 2023
3447dff
State of SizeToggle now passed up to the item page
WishingWell13 Dec 18, 2023
3bc3660
Updated styling of size selector to match Figma
WishingWell13 Dec 19, 2023
1b3c66f
Part 1 of AddCartButton styling
WishingWell13 Dec 20, 2023
3049461
Out of Stock Button and "Please Select Size"
WishingWell13 Dec 20, 2023
a47a827
Fixed issue with AddCartButton props breaking
WishingWell13 Dec 20, 2023
6fb2bad
Began formatting for item header and item page
WishingWell13 Dec 21, 2023
6ac2138
Store Component now linked to API, price added
WishingWell13 Dec 25, 2023
554bafe
Size Selection Buttons Now Dynamically Generated
WishingWell13 Dec 27, 2023
7e38576
Merge branch 'main' into andy/StoreItemPage
farisashai Dec 27, 2023
2705bb4
Buy ability based on lifetime/monthly limits, added item picture
WishingWell13 Dec 31, 2023
f928e29
Cleaned up some old comments
WishingWell13 Dec 31, 2023
c458a32
Moved Navbar to top of page
WishingWell13 Dec 31, 2023
b9573aa
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Dec 31, 2023
c91551d
Resolved linting error (unused var)
WishingWell13 Dec 31, 2023
74bfe70
Update src/styles/pages/store/item.module.scss
WishingWell13 Dec 31, 2023
d8c7689
Update src/styles/pages/store/item.module.scss
WishingWell13 Dec 31, 2023
78916e9
Update src/styles/pages/store/item.module.scss
WishingWell13 Dec 31, 2023
bcd7d25
Update src/lib/api/StoreAPI.ts
WishingWell13 Dec 31, 2023
3259dce
Resolved merge error with calendar
WishingWell13 Jan 1, 2024
045dc34
Minor package changes
WishingWell13 Jan 1, 2024
cb9c7a4
Fix package.json
alexzhang1618 Jan 1, 2024
539cc01
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Jan 1, 2024
1e5f40b
Make compatible with multiple store gallery images
WishingWell13 Jan 1, 2024
c2aafc9
Moved item header to be above sizing buttons
WishingWell13 Jan 1, 2024
385c9df
Merge branch 'main' into andy/StoreItemPage
farisashai Jan 2, 2024
8762d70
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Jan 5, 2024
e211d47
Centered the body of the item page.
WishingWell13 Jan 5, 2024
b4551e2
Fixed merge error by updating name of file path
WishingWell13 Jan 5, 2024
a7659d0
Update src/styles/pages/store/item.module.scss
WishingWell13 Jan 5, 2024
4a3454d
Update src/pages/store/item/[uuid].tsx
WishingWell13 Jan 5, 2024
1ad9b78
Update src/pages/store/item/[uuid].tsx
WishingWell13 Jan 5, 2024
88cbf89
Update src/pages/store/item/[uuid].tsx
WishingWell13 Jan 5, 2024
de7272a
Update .vscode/settings.json
WishingWell13 Jan 5, 2024
704e7b2
Update src/styles/pages/store/item.module.scss
WishingWell13 Jan 5, 2024
079c9af
Update src/components/store/AddCartButton/index.tsx
WishingWell13 Jan 5, 2024
e404445
Addressed PR comments, Add to Cart button behavior edit
WishingWell13 Jan 5, 2024
3d42280
Updated diamond component in Item Header
WishingWell13 Jan 5, 2024
4d30231
Add To Cart button disappears when UserPurchaseLimit reached
WishingWell13 Jan 5, 2024
96e8061
AddCartButton maxCanBuy saftey checks and styling
WishingWell13 Jan 5, 2024
b396330
Renamed styling files, AddToCart Button Behavior Change
WishingWell13 Jan 5, 2024
4814377
Added border back to disabled AddToCart Button
WishingWell13 Jan 6, 2024
c01e652
Added border back to cart button, cleaned up unused vars
WishingWell13 Jan 6, 2024
f567d94
Hid toggle when maxCanBuy = 1
WishingWell13 Jan 6, 2024
1a250f8
Removed unused comments
WishingWell13 Jan 6, 2024
518cfb7
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Jan 6, 2024
b0c8a08
Merge branch 'main' into andy/StoreItemPage
farisashai Jan 6, 2024
7707313
Removed eslint disable lines
WishingWell13 Jan 6, 2024
a88f8a0
Removed title attribute from buy button
WishingWell13 Jan 6, 2024
c402a80
Removed trailing spaces from button text
WishingWell13 Jan 6, 2024
bdae3ef
Hide price when size is not selected
WishingWell13 Jan 6, 2024
8977e2a
Added back other types accidently deleted from last commit
WishingWell13 Jan 6, 2024
cd57e84
Delete blue-diamond.svg
WishingWell13 Jan 6, 2024
3b1bf4a
Basic mobile formatting implemented
WishingWell13 Jan 11, 2024
5dfe30a
Fixed image clipping issue, reduced image gap on mobile
WishingWell13 Jan 20, 2024
af6d505
Removed vertical scrollbar from mobile view
WishingWell13 Jan 20, 2024
e96356c
Removed unnecessary CSS
WishingWell13 Jan 20, 2024
846638c
Merge remote-tracking branch 'origin/main' into andy/StoreItemPage
SheepTester Jan 21, 2024
aefaaff
Rename store/collections.module.scss to be consistent with other chan…
SheepTester Jan 21, 2024
ee97807
PermissionService.allUserTypes is no longer a function
SheepTester Jan 21, 2024
48ba4e4
Fixed a linting error with the options dropdown
WishingWell13 Jan 23, 2024
35bada4
Shrunk some UI items for mobile version of site
WishingWell13 Jan 23, 2024
78c5df2
Set upper limit on quantity of items can buy
WishingWell13 Jan 23, 2024
49017ee
Deleted unnecessary comments
WishingWell13 Jan 23, 2024
7e86f3f
Update src/components/store/SizeSelector/index.tsx
WishingWell13 Jan 23, 2024
17f8325
Fixed various linting errors, removed comments
WishingWell13 Jan 23, 2024
d914bce
Decreased font size of dropdown text
WishingWell13 Jan 23, 2024
1373cea
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Jan 23, 2024
869f8b3
New styling changes to adjust spacing
WishingWell13 Jan 27, 2024
2bcd085
Locked width of description and fixed line breaks
WishingWell13 Jan 28, 2024
dcf3076
Title now properly wraps with very long titles
WishingWell13 Jan 30, 2024
4b47cc3
Made padding a little bigger for right column
WishingWell13 Jan 30, 2024
16efb57
Removed in stock / out of stock messages
WishingWell13 Jan 30, 2024
a7dcb90
@media now uses the media breakpoint variables
WishingWell13 Jan 30, 2024
031457f
Renamed variables and adjusted white space behavior
WishingWell13 Jan 30, 2024
d1f4d11
Update src/components/store/AddCartButton/index.tsx
WishingWell13 Feb 1, 2024
1c8f48f
Update src/components/store/AddCartButton/style.module.scss
WishingWell13 Feb 1, 2024
e8aae1f
Fixed some gap inconsistencies
WishingWell13 Feb 1, 2024
c36a84e
Update settings.json
WishingWell13 Feb 1, 2024
186c904
Update settings.json
WishingWell13 Feb 1, 2024
b84ba08
Made SizeSelector title change based on metadata
WishingWell13 Feb 1, 2024
907a602
Fixed bug where add to cart button no longer worked
WishingWell13 Feb 6, 2024
2ba9dbb
Condensed imports in `uuid`, removed "Remove from Cart" text
WishingWell13 Feb 7, 2024
04436a0
Before attempting to remove currOption
WishingWell13 Feb 10, 2024
c6b9cda
Made the "please select an option" text to show key value
WishingWell13 Feb 10, 2024
b24b38a
Update src/components/store/AddCartButton/style.module.scss
WishingWell13 Feb 11, 2024
54e7ebe
Changed AddCartButton to CartOptionsGroup
WishingWell13 Feb 11, 2024
78e1cd5
Merge branch 'andy/StoreItemPage' of https://github.com/acmucsd/membe…
WishingWell13 Feb 11, 2024
6f5454f
Removed unnecessary properties, simplified CSS
WishingWell13 Feb 11, 2024
808630c
Updated code to have one item selected by default
WishingWell13 Feb 12, 2024
11446c8
Removed empty div when there are no options
WishingWell13 Feb 12, 2024
795951c
Removed console.log statement
WishingWell13 Feb 12, 2024
b9a1e7f
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Feb 13, 2024
24a363f
Fixed bug where you couldn't purchase no option items
WishingWell13 Feb 13, 2024
9be7b77
Button and option name updates
WishingWell13 Feb 15, 2024
de8b569
Merge branch 'main' into andy/StoreItemPage
WishingWell13 Feb 15, 2024
0dbba80
Updated components to use Typography, not <p>
WishingWell13 Feb 15, 2024
b2526a8
Merge branch 'andy/StoreItemPage' of https://github.com/acmucsd/membe…
WishingWell13 Feb 15, 2024
7bd1416
Refactored the toggle value array creation
WishingWell13 Feb 16, 2024
71ad5ad
Implemented discount functionality
WishingWell13 Feb 17, 2024
f4f4099
Cleaned up CSS and conditionals by adding variables
WishingWell13 Feb 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
WishingWell13 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
"*.env.development": "env",
"*.env.production": "env"
}
}
}
2 changes: 1 addition & 1 deletion src/components/home/Hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const Hero = ({ firstName, points, checkin }: HeroProps) => {
</button>
</div>
</form>
<Link href={config.storeRoute} className={styles.link}>
<Link href={config.store.homeRoute} className={styles.link}>
<ShopIcon />
<Typography variant="h4/regular" className={styles.subheading}>
Spend points on merch
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const Navbar = ({ accessType }: NavbarProps) => {
<ProfileIcon className={styles.iconLink} />
Profile
</Link>
<Link className={styles.mobileNavItem} href={config.storeRoute}>
<Link className={styles.mobileNavItem} href={config.store.homeRoute}>
<ShopIcon className={styles.iconLink} />
Store
</Link>
Expand Down
100 changes: 100 additions & 0 deletions src/components/store/CartOptionsGroup/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Dropdown, Typography } from '@/components/common';
import { useId } from 'react';
import styles from './style.module.scss';

interface CartOptionGroupProps {
currOption: string | undefined;
inStock: boolean;
inCart: boolean;
lifetimeRemaining: number;
monthlyRemaining: number;
amountToBuy: number;
optionsKey: string;
onCartChange: (inCart: boolean) => void;
onAmountChange: (amountToBuy: number) => void;
}

const CartOptionsGroup = ({
currOption,
inStock,
inCart,
onCartChange,
lifetimeRemaining,
monthlyRemaining,
amountToBuy,
optionsKey,
onAmountChange,
}: CartOptionGroupProps) => {
const myID = useId();

// 20 is a number decided upon to prevent large maximum purchase limits from crashing the webpage
const maxCanBuy = Math.min(20, Math.min(lifetimeRemaining, monthlyRemaining));
WishingWell13 marked this conversation as resolved.
Show resolved Hide resolved

const isPurchasable = inStock && maxCanBuy > 0;
const noOptionSelected = currOption === undefined && optionsKey != null;

let buyButtonText = 'Add to Cart';

if (maxCanBuy === 0) {
buyButtonText = 'Limit Reached';
} else if (currOption === undefined && optionsKey !== undefined) {
buyButtonText = `Select a ${optionsKey}`;
} else if (inStock) {
buyButtonText = 'Add to Cart';
} else {
buyButtonText = 'Out of Stock';
}

// Fills values of the Dropdown to be increasing sequential numbers
const optionArr: Array<{ value: string; label: string }> = Array(maxCanBuy)
.fill({ value: `${1}`, label: `${1}` })
.map((_, index) => {
return { value: `${index + 1}`, label: `${index + 1}` };
});

return (
<div className={styles.addCartGroup}>
<p>{`In cart: ${inCart}`}</p>

{maxCanBuy > 0 ? (
<Typography variant="h5/regular">You can buy up to {maxCanBuy} of this item.</Typography>
) : (
<Typography variant="h5/regular">You can&apos;t buy any more of this item!.</Typography>
)}
{noOptionSelected ? (
<Typography variant="h5/regular" className={styles.error}>
{`Please select a ${optionsKey?.toLocaleLowerCase() ?? 'option'}`}.
</Typography>
) : null}

{noOptionSelected ? null : (
<div className={styles.buttonRow}>
{!isPurchasable ? null : (
<div className={styles.quantityColumn}>
<Typography variant="h4/bold">Quantity</Typography>
<Dropdown
name={`options${currOption}_${optionsKey}${myID}`}
ariaLabel={`Dropdown to select the number of items to purchase for ${myID}`}
options={optionArr}
value={`${amountToBuy}`}
onChange={val => onAmountChange(Number(val))}
/>
</div>
)}

<button
className={`${isPurchasable ? styles.buttonInStock : styles.buttonNoStock} ${
styles.button
}`}
type="button"
onClick={() => onCartChange(!inCart)}
disabled={!isPurchasable}
>
{buyButtonText}
</button>
</div>
)}
</div>
);
};
export default CartOptionsGroup;
60 changes: 60 additions & 0 deletions src/components/store/CartOptionsGroup/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
@use 'src/styles/vars.scss' as vars;

.addCartGroup {
display: flex;
flex-direction: column;
gap: 1rem;

.buttonRow {
align-items: flex-end;
display: flex;
flex-direction: row;
gap: 2rem;
}

.quantityColumn {
display: flex;
flex-direction: column;
gap: 1rem;
@media (max-width: vars.$breakpoint-md) {
gap: 0.75rem;
}

div > select {
font-size: 1.25rem;
font-style: normal;
font-weight: 700;
line-height: 2.5rem;

text-align: center;
}
}

.error {
color: vars.$danger-1;
}

.valid {
color: vars.$success-1;
}

.button {
border-radius: 10px;
font-size: vars.$input-text-medium;
font-weight: bold;
margin: 0.2rem 0;
padding: 0.3rem 1rem;
word-break: break-word;
}

.buttonInStock {
background-color: var(--theme-primary-2);
color: vars.$dark-text-on-background-1;
}

.buttonNoStock {
background-color: var(--theme-background);
border: 1px solid var(--theme-accent-line-2);
color: vars.$disabled;
}
}
16 changes: 16 additions & 0 deletions src/components/store/CartOptionsGroup/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export type Styles = {
addCartGroup: string;
button: string;
buttonInStock: string;
buttonNoStock: string;
buttonRow: string;
error: string;
quantityColumn: string;
valid: string;
};

export type ClassNames = keyof Styles;

declare const styles: Styles;

export default styles;
2 changes: 1 addition & 1 deletion src/components/store/CollectionSlider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const CollectionSlider = ({ title, description, items }: CollectionSliderProps)
className={styles.card}
image={getDefaultMerchItemPhoto(item)}
title={item.itemName}
href={`${config.itemRoute}${item.uuid}`}
href={`${config.store.itemRoute}${item.uuid}`}
cost={item.options[0]?.price ?? 0}
key={item.uuid}
/>
Expand Down
25 changes: 25 additions & 0 deletions src/components/store/ItemHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Typography } from '@/components/common';
import Diamonds from '@/components/store/Diamonds';
import styles from './style.module.scss';

interface ItemHeaderProps {
itemName: string;
cost: number | undefined;
discountPercentage: number;
}

const ItemHeader = ({ itemName, cost, discountPercentage }: ItemHeaderProps) => {
return (
<div className={styles.itemHeaderGroup}>
<Typography variant="h1/bold" style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
{itemName}
</Typography>
{cost === undefined ? null : (
<div className={styles.price}>
<Diamonds count={cost} discount={cost - (cost * discountPercentage) / 100} />
</div>
)}
</div>
);
};
export default ItemHeader;
24 changes: 24 additions & 0 deletions src/components/store/ItemHeader/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@use 'src/styles/vars.scss' as vars;

.price {
align-items: center;
align-self: stretch;
display: flex;
flex-direction: row;
gap: 0.5rem;
}

.itemHeaderGroup {
display: flex;
flex-direction: column;
flex-wrap: wrap;
gap: 1rem;

.error {
color: vars.$danger-1;
}

.valid {
color: vars.$success-1;
}
}
12 changes: 12 additions & 0 deletions src/components/store/ItemHeader/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export type Styles = {
error: string;
itemHeaderGroup: string;
price: string;
valid: string;
};

export type ClassNames = keyof Styles;

declare const styles: Styles;

export default styles;
43 changes: 43 additions & 0 deletions src/components/store/SizeSelector/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Typography } from '@/components/common';
import styles from '@/components/store/SizeSelector/style.module.scss';
import { MerchItemOptionMetadata } from '@/lib/types/apiRequests';
import { PublicMerchItemOption } from '@/lib/types/apiResponses';
import { toTitleCase } from '@/lib/utils';
import { Fragment, useId } from 'react';

interface SizeSelectorProps {
currOption: MerchItemOptionMetadata | undefined;
options: PublicMerchItemOption[];
onOptionChange: (currSize: PublicMerchItemOption) => void;
}

const SizeSelector = ({ currOption, options, onOptionChange }: SizeSelectorProps) => {
const myID = useId();
const myOptions = options.map(val => {
const tempId = val.metadata.value ? `${val.metadata.value}${myID}` : `${val.uuid}${myID}`;
return (
<Fragment key={tempId}>
<input
id={tempId}
name="state-d"
type="radio"
defaultChecked={currOption?.value === val.metadata?.value}
onClick={() => onOptionChange(val)}
/>
<label htmlFor={tempId}>{val.metadata?.value}</label>
</Fragment>
);
});

return options.length > 1 && options ? (
<div className={styles.sizeSelector}>
{options[0]?.metadata.type === undefined ? (
<Typography variant="h4/bold">Options</Typography>
) : (
<Typography variant="h4/bold">{toTitleCase(options[0]?.metadata.type)}</Typography>
)}
<form className={styles.switch}>{myOptions}</form>
</div>
) : null;
};
export default SizeSelector;
56 changes: 56 additions & 0 deletions src/components/store/SizeSelector/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@use 'src/styles/vars.scss' as vars;
$indicator-size: 30px;
$component-roundness: 10px;

.sizeSelector {
display: flex;
flex-direction: column;
gap: 1rem;
overflow: auto;

.switch {
WishingWell13 marked this conversation as resolved.
Show resolved Hide resolved
align-items: center;
border-color: #9f9f9f;
border-radius: $component-roundness;
display: flex;
flex-wrap: wrap;
float: left;
gap: 0.75rem;
position: relative;

label {
align-items: center;
background-color: var(--theme-surface-2);
border-radius: $component-roundness;
border-style: solid;
border-width: 1px;
color: var(--theme-text-on-background-1);
cursor: pointer;
display: flex;
flex-direction: row;
float: left;
height: $indicator-size;
justify-content: center;
min-width: #{$indicator-size * 2};
padding: 0 1rem;
}

input {
opacity: 0;
pointer-events: none;
position: absolute;
}

input:hover + label {
border-color: var(--theme-size-selector-border);
}

input:checked + label {
border-color: var(--theme-size-selector-border);
color: var(--theme-size-selector-border);
}
}
}

// INFO LINKS
// https://markheath.net/post/customize-radio-button-css
10 changes: 10 additions & 0 deletions src/components/store/SizeSelector/style.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type Styles = {
sizeSelector: string;
switch: string;
};

export type ClassNames = keyof Styles;

declare const styles: Styles;

export default styles;
Loading