defining and integrating a small component library
This commit is contained in:
@@ -2,6 +2,8 @@ import { useSupabase } from "../../supabase/SupabaseContext";
|
|||||||
import { FormInput, getSession, handleLogin, handleRegister } from "../../util/authHelpers";
|
import { FormInput, getSession, handleLogin, handleRegister } from "../../util/authHelpers";
|
||||||
import { AuthFormType } from "../../util/types";
|
import { AuthFormType } from "../../util/types";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import Button from "../_ui/Button/Button";
|
||||||
|
import Page from "../_ui/Page/Page";
|
||||||
|
|
||||||
const AuthForm: AuthFormType = ({ format }) => {
|
const AuthForm: AuthFormType = ({ format }) => {
|
||||||
const [input, setInput] = useState<FormInput>({ email: "", password: "" });
|
const [input, setInput] = useState<FormInput>({ email: "", password: "" });
|
||||||
@@ -10,25 +12,25 @@ const AuthForm: AuthFormType = ({ format }) => {
|
|||||||
const formFunction = format == "login" ? () => handleLogin(supabase, input) : () => handleRegister(supabase, input);
|
const formFunction = format == "login" ? () => handleLogin(supabase, input) : () => handleRegister(supabase, input);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<Page>
|
||||||
<h1>{formText}</h1>
|
<h1>{formText}</h1>
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<div>
|
<div className="form-row">
|
||||||
<label>Email:</label>
|
<label htmlFor="auth-form-email">Email:</label>
|
||||||
<input required type="text" onChange={(e) => setInput({...input, email: e.target.value})} />
|
<input id="auth-form-email" required type="text" onChange={(e) => setInput({...input, email: e.target.value})} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="form-row">
|
||||||
<label>Password:</label>
|
<label htmlFor="auth-form-password">Password:</label>
|
||||||
<input required type="text" onChange={(e) => setInput({...input, password: e.target.value})} />
|
<input id="auth-form-password" required type="password" onChange={(e) => setInput({...input, password: e.target.value})} />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div className="auth-actions">
|
<div className="auth-actions">
|
||||||
<button onClick={formFunction}>{formText}</button>
|
<Button onClick={formFunction}>{formText}</Button>
|
||||||
<button onClick={() => getSession(supabase)}>Session</button>
|
<Button onClick={() => getSession(supabase)}>Session</Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
|
import Button from "./_ui/Button/Button";
|
||||||
|
import Page from "./_ui/Page/Page";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<Page>
|
||||||
<h1>The finest spice shop on the internet.</h1>
|
<h1>The finest spice shop on the internet.</h1>
|
||||||
<p>Or at the very least, what their website could look like.</p>
|
<p>Or at the very least, what their website could look like.</p>
|
||||||
|
|
||||||
<div>
|
<div className="button-row">
|
||||||
<button onClick={() => navigate('/products')}>View our Products</button>
|
<Button onClick={() => navigate('/products')}>View our Products</Button>
|
||||||
<button onClick={() => navigate('/philosophy')}>Our Philosophy</button>
|
<Button onClick={() => navigate('/philosophy')}>Our Philosophy</Button>
|
||||||
<button onClick={() => navigate('/contact')}>Contact Us</button>
|
<Button onClick={() => navigate('/contact')}>Contact Us</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,8 @@ import { useEffect, useState } from "react"
|
|||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
import { getAllProducts } from "../../util/apiUtils";
|
import { getAllProducts } from "../../util/apiUtils";
|
||||||
import { ProductModel } from "../../util/types";
|
import { ProductModel } from "../../util/types";
|
||||||
|
import Gallery from "../_ui/Gallery/Gallery";
|
||||||
|
import Page from "../_ui/Page/Page";
|
||||||
import ProductCard from "./ProductCard";
|
import ProductCard from "./ProductCard";
|
||||||
|
|
||||||
export default function AllProducts() {
|
export default function AllProducts() {
|
||||||
@@ -16,16 +18,16 @@ export default function AllProducts() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setView(
|
setView(
|
||||||
<section>
|
<Page>
|
||||||
<h1>All Products!</h1>
|
<h1>All Products!</h1>
|
||||||
<div className="product-card-list">
|
<Gallery additionalClasses="product-card-list" columns={3}>
|
||||||
{
|
{
|
||||||
productData && productData.map((data: ProductModel) => {
|
productData && productData.map((data: ProductModel) => {
|
||||||
return <ProductCard data={data} key={v4()} />
|
return <ProductCard data={data} key={v4()} />
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</Gallery>
|
||||||
</section>
|
</Page>
|
||||||
)
|
)
|
||||||
}, [productData, setProductData]);
|
}, [productData, setProductData]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { ProductCardType } from "../../util/types";
|
import { ProductCardType } from "../../util/types";
|
||||||
|
import Button from "../_ui/Button/Button";
|
||||||
|
import Card from "../_ui/Card/Card";
|
||||||
|
|
||||||
const ProductCard: ProductCardType = ({ data }) => {
|
const ProductCard: ProductCardType = ({ data }) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="product-card">
|
<Card additionalClasses="product-card">
|
||||||
<h1>{data.name}</h1>
|
<h1>{data.name}</h1>
|
||||||
<p>{data.price}</p>
|
<p>{data.price}</p>
|
||||||
<p>{data.description}</p>
|
<p>{data.description}</p>
|
||||||
|
|
||||||
<button onClick={() => navigate(`/products/${data.id}`)}>See More</button>
|
<Button onClick={() => navigate(`/products/${data.id}`)}>See More</Button>
|
||||||
</div>
|
</Card>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
|
|||||||
import { useNavigate, useParams } from "react-router-dom"
|
import { useNavigate, useParams } from "react-router-dom"
|
||||||
import { getByProductId } from "../../util/apiUtils";
|
import { getByProductId } from "../../util/apiUtils";
|
||||||
import { ProductModel } from "../../util/types";
|
import { ProductModel } from "../../util/types";
|
||||||
|
import Page from "../_ui/Page/Page";
|
||||||
|
|
||||||
export default function ProductPage() {
|
export default function ProductPage() {
|
||||||
const [productData, setProductData] = useState<ProductModel>();
|
const [productData, setProductData] = useState<ProductModel>();
|
||||||
@@ -17,12 +18,12 @@ export default function ProductPage() {
|
|||||||
if (!productData) return <h1>Product not found.</h1>
|
if (!productData) return <h1>Product not found.</h1>
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="product-page">
|
<Page additionalClasses="product-page">
|
||||||
<h1>{productData.name}</h1>
|
<h1>{productData.name}</h1>
|
||||||
<p>{productData.price}</p>
|
<p>{productData.price}</p>
|
||||||
<p>{productData.description}</p>
|
<p>{productData.description}</p>
|
||||||
|
|
||||||
<button onClick={() => navigate('/products')}>Return to Product Listing</button>
|
<button onClick={() => navigate('/products')}>Return to Product Listing</button>
|
||||||
</section>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,23 @@
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useSupabase } from "../../supabase/SupabaseContext"
|
import { useSupabase } from "../../supabase/SupabaseContext"
|
||||||
|
import Button from "../_ui/Button/Button";
|
||||||
|
import Page from "../_ui/Page/Page";
|
||||||
|
|
||||||
export default function UserProfile() {
|
export default function UserProfile() {
|
||||||
const supabase = useSupabase();
|
const supabase = useSupabase();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<Page>
|
||||||
<h1>User Profile!</h1>
|
<h1>User Profile!</h1>
|
||||||
<p>Your email is {supabase?.auth.user()?.email || "not found"}</p>
|
<p>Your email is {supabase?.auth.user()?.email || "not found"}</p>
|
||||||
|
|
||||||
<h2>Options:</h2>
|
<h2>Options:</h2>
|
||||||
<div className="user-profile-options">
|
<div className="user-profile-options">
|
||||||
<button onClick={() => navigate('/cart')}>View my Cart</button>
|
<Button onClick={() => navigate('/cart')}>View my Cart</Button>
|
||||||
<button onClick={() => navigate('/orders')}>View my Order History</button>
|
<Button onClick={() => navigate('/orders')}>View my Order History</Button>
|
||||||
<button>Manage Account Settings</button>
|
<Button onClick={() => {}}>Manage Account Settings</Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
0
client/src/components/_ui/Button/Button.scss
Normal file
0
client/src/components/_ui/Button/Button.scss
Normal file
13
client/src/components/_ui/Button/Button.tsx
Normal file
13
client/src/components/_ui/Button/Button.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { UIButtonType } from "../../../util/types"
|
||||||
|
|
||||||
|
const Button: UIButtonType = ({ onClick, children = "Button", additionalClasses = "" }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button className={`ui-button-component ${additionalClasses}`} onClick={onClick}>
|
||||||
|
{ children }
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Button;
|
||||||
0
client/src/components/_ui/Card/Card.scss
Normal file
0
client/src/components/_ui/Card/Card.scss
Normal file
11
client/src/components/_ui/Card/Card.tsx
Normal file
11
client/src/components/_ui/Card/Card.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { UICompWithChildren } from "../../../util/types"
|
||||||
|
|
||||||
|
const Card: UICompWithChildren = ({ children, additionalClasses = "" }) => {
|
||||||
|
return (
|
||||||
|
<section className={`ui-card-component ${additionalClasses}`}>
|
||||||
|
{ children }
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Card;
|
||||||
0
client/src/components/_ui/Gallery/Gallery.scss
Normal file
0
client/src/components/_ui/Gallery/Gallery.scss
Normal file
13
client/src/components/_ui/Gallery/Gallery.tsx
Normal file
13
client/src/components/_ui/Gallery/Gallery.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { UIGalleryType } from "../../../util/types"
|
||||||
|
|
||||||
|
const Gallery: UIGalleryType = ({ children, columns, additionalClasses = "" }) => {
|
||||||
|
const widthFromCols = Math.ceil(90 / columns);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={`ui-gallery-component item-width-${widthFromCols} ${additionalClasses}`}>
|
||||||
|
{ children }
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Gallery;
|
||||||
0
client/src/components/_ui/Page/Page.scss
Normal file
0
client/src/components/_ui/Page/Page.scss
Normal file
11
client/src/components/_ui/Page/Page.tsx
Normal file
11
client/src/components/_ui/Page/Page.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { UICompWithChildren } from "../../../util/types";
|
||||||
|
|
||||||
|
const Page: UICompWithChildren = ({ children, additionalClasses = "" }) => {
|
||||||
|
return (
|
||||||
|
<section className={`ui-page-component ${additionalClasses}`}>
|
||||||
|
{ children }
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Page;
|
||||||
@@ -1,8 +1,28 @@
|
|||||||
import { FC } from "react";
|
import { FC, ReactNode } from "react";
|
||||||
|
|
||||||
// component types
|
// component types
|
||||||
export type AuthFormType = FC<{ format: string }>
|
export type AuthFormType = FC<{ format: string }>
|
||||||
export type ProductCardType = FC<{ data: ProductModel }>
|
export type ProductCardType = FC<{ data: ProductModel }>
|
||||||
|
export type UIButtonType = FC<UIButtonParams>
|
||||||
|
export type UICompWithChildren = FC<UICompChildrenParams>
|
||||||
|
export type UIGalleryType = FC<UIGalleryParams>
|
||||||
|
|
||||||
|
// definitions for component params
|
||||||
|
interface UIParams {
|
||||||
|
additionalClasses?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UIButtonParams extends UIParams {
|
||||||
|
onClick: (...params: any) => any
|
||||||
|
children?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UICompChildrenParams extends UIParams { children: ReactNode }
|
||||||
|
|
||||||
|
interface UIGalleryParams extends UIParams {
|
||||||
|
children: ReactNode
|
||||||
|
columns: number
|
||||||
|
}
|
||||||
|
|
||||||
// data models
|
// data models
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user