Skip to content

Commit

Permalink
Update product type and mobile UI
Browse files Browse the repository at this point in the history
  • Loading branch information
vpodk committed Jan 29, 2024
1 parent f7b8dbb commit f9f8d59
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 49 deletions.
4 changes: 2 additions & 2 deletions src/app/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { SearchForm } from "./search";

export default function Header() {
return (
<header className="flex py-8">
<a href="/" className="flex items-center">
<header className="lg:flex py-8">
<a href="/" className="flex px-4 lg:px-0 mb-6 lg:mb-0 items-center">
<Image
src="/wiseblend-logo.svg"
width={173}
Expand Down
10 changes: 5 additions & 5 deletions src/app/components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ const heading = Playfair_Display({ subsets: ["latin"] });

export default function Hero() {
return (
<div className="hero relative mt-12">
<h1 className={`font-semibold ${heading.className}`}>
<div className="hero relative mt-6 lg:mt-12">
<h1 className={`text-6xl text-center lg:text-left font-semibold ${heading.className}`}>
Blend Smart
<br />
Spend Wise
</h1>
<div className="my-8 text-xl">Never overspend on skincare again!</div>
<div className={`banner text-white font-semibold p-6 w-3/5 rounded-l-3xl ${font.className}`}>
<div className="my-8 text-xl text-center lg:text-left">Never overspend on skincare again!</div>
<div className={`banner text-white font-semibold p-6 lg:w-3/5 rounded-l-3xl ${font.className}`}>
Use AI to find cheaper alternatives with
<br />
the same function!
</div>
<div className="image absolute top-0 bg-no-repeat"></div>
<div className="image static lg:absolute max-w-full lg:max-w-none top-0 bg-no-repeat -z-10 lg:z-10 opacity-50 lg:opacity-100"></div>
</div>
);
}
32 changes: 29 additions & 3 deletions src/app/components/search/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,35 @@

import { useContext, useRef } from "react";
import { SearchContext } from "./context";
import { Product } from "./types";

const API_ENDPOINT = "/search.json?url=";

const parse = (data: any) => {
if (Array.isArray(data)) {
return data.map((product) => {
return {
id: product.id || product.dupe_product_id,
name: product.name || product.dupe_product,
description: product.description || product.dupe_product_description,
image: product.image || product.dupe_product_image,
brand: product.brand || product.brand_name,
price: product.price || product.dupe_price_in_dollar,
size: product.size || product.dupe_size_without_unit,
units: product.units || product.dupe_unit_of_size,
link: product.link || product.dupe_shopping_link,
ingredients: product.ingredients || product.key_ingredient_benefits,
videos: product.videos || [
product.dupe_video_reference_link_1,
product.dupe_video_reference_link_2,
product.dupe_video_reference_link_3,
],
};
}) as Product[];
}
return [];
};

export default function SearchForm() {
const inputRef = useRef<HTMLInputElement>(null);
const { setProducts } = useContext(SearchContext);
Expand All @@ -16,23 +42,23 @@ export default function SearchForm() {
fetch(API_ENDPOINT + encodeURIComponent(input.value.trim()))
.then((res) => res.json())
.then((data) => {
setProducts(data);
setProducts(parse(data));
input.value = "";
});
input.value = "Loading...";
}
};

return (
<form className="flex grow ml-5" action={search}>
<form className="flex grow px-4 lg:px-0 lg:ml-5" action={search}>
<input
ref={inputRef}
type="url"
required
className="grow px-4 rounded-l-2xl"
placeholder="Enter product URL"
/>
<button type="submit" className="rounded-r-2xl">&nbsp;</button>
<button type="submit" className="rounded-r-2xl"></button>
</form>
);
}
46 changes: 15 additions & 31 deletions src/app/components/search/results.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
"use client";

import {
Dispatch,
ReactNode,
SetStateAction,
useContext,
useState,
} from "react";
import { Dispatch, SetStateAction, useContext, useState } from "react";
import { Playfair_Display } from "next/font/google";
import { Card } from "../card";
import { SearchContext } from "./context";
Expand All @@ -23,27 +17,22 @@ export default function SearchResults() {
<div className="flex gap-x-8">
<div
className="bg-white border border-gray-300 rounded-lg bg-contain bg-no-repeat bg-center grow basis-full"
style={{ backgroundImage: `url(${product.dupe_product_image})` }}
style={{ backgroundImage: `url(${product.image})` }}
></div>
<div className="grow basis-full">
<h2 className={`text-6xl font-semibold ${heading.className}`}>
{product.brand_name}
{product.brand}
</h2>
<h3 className="text-xl font-normal mt-4 mb-6">
{product.dupe_product}
</h3>
<p className="text-base font-normal">
{product.dupe_product_description}
</p>
<h3 className="text-xl font-normal mt-4 mb-6">{product.name}</h3>
<p className="text-base font-normal">{product.description}</p>
<div className="columns-2 mt-6 flex items-center">
<div className="text-orange-600 text-3xl font-bold">
${product.dupe_price_in_dollar} /{product.dupe_size_without_unit}{" "}
{product.dupe_unit_of_size}
${product.price} /{product.size} {product.units}
</div>
<div className="ml-6">
<a
className="p-4 rounded-md bg-cyan-500 text-white text-base font-semibold"
href={product.dupe_shopping_link}
href={product.link}
target="_blank"
>
Buy Now
Expand All @@ -59,7 +48,7 @@ export default function SearchResults() {
</div>

<Card title="Active Ingredients">
<div>{product.key_ingredient_benefits}</div>
<div>{product.ingredients}</div>
</Card>

<SocialMedia product={product} />
Expand All @@ -68,16 +57,12 @@ export default function SearchResults() {
}

const SocialMedia = ({ product }: { product: Product }) => {
const videos = [
product.dupe_video_reference_link_1,
product.dupe_video_reference_link_2,
product.dupe_video_reference_link_3,
]
const videos = product.videos
.map((url) => {
if (url && url.startsWith("http")) {
try {
// "https://www.youtube.com/shorts/qwerty",
let videoId = url.split("/shorts/")[1];
let videoId: string | null = url.split("/shorts/")[1];
if (!videoId) {
// "https://www.youtube.com/watch?v=aaa&pp=bbb"
videoId = new URLSearchParams(url.split("?")[1]).get("v");
Expand Down Expand Up @@ -120,9 +105,9 @@ const ProductAlternatives: any = ({
<strong>Other Great Alternatives</strong>
<div className="mt-3 flex gap-x-4">
{products.map((alternative) =>
alternative.dupe_product_id !== product.dupe_product_id ? (
alternative.id !== product.id ? (
<ProductAlternative
key={alternative.dupe_product_id}
key={alternative.id}
product={alternative}
setProduct={setProduct}
/>
Expand All @@ -139,7 +124,7 @@ const ProductAlternative = ({
product: Product;
setProduct: Dispatch<SetStateAction<Product>>;
}) => {
const inlineStyle = { backgroundImage: `url(${product.dupe_product_image})` };
const inlineStyle = { backgroundImage: `url(${product.image})` };
return (
<div
className="bg-white border border-gray-300 outline outline-0 hover:border-transparent hover:outline-2 hover:outline-cyan-500 rounded-lg px-3 py-5 flex grow basis-full cursor-pointer items-center"
Expand All @@ -152,10 +137,9 @@ const ProductAlternative = ({
style={inlineStyle}
></div>
<div className="py-5 grow">
<h3 className="text-xl font-semibold">{product.brand_name}</h3>
<h3 className="text-xl font-semibold">{product.brand}</h3>
<div className="text-orange-600 text-xl font-bold">
${product.dupe_price_in_dollar} /{product.dupe_size_without_unit}{" "}
{product.dupe_unit_of_size}
${product.price} /{product.size} {product.units}
</div>
</div>
</div>
Expand Down
15 changes: 13 additions & 2 deletions src/app/components/search/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@

export type Product = {
[key: string]: any;
id: number; // product.dupe_product_id,
name: string; //product.dupe_product,
description: string; //product.dupe_product_description,
image: string; //product.dupe_product_image,
brand: string; //product.brand_name,
price: number; // product.dupe_price_in_dollar,
size: number; // product.dupe_size_without_unit,
units: string; //product.dupe_unit_of_size,
link: string; //product.dupe_shopping_link,
ingredients: string; //product.key_ingredient_benefits,
videos: string[]; // [dupe_video_reference_link_1, dupe_video_reference_link_2]

// [key: string]: any;
};
16 changes: 11 additions & 5 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;

html, body {
width: 100%;
}

/* :root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
Expand All @@ -27,6 +31,7 @@ body {

background-image: url('/background.svg');
background-size: cover;
width: 100%;
}

header form input,
Expand All @@ -48,11 +53,6 @@ header form [type='submit'] {
width: 54px;
}

.hero h1 {
font-size: 85px;
line-height: .95em;
}

.hero .banner {
background: linear-gradient(90deg, rgba(202, 135, 255, 0.7) 0%, rgba(246, 160, 129, 0.7) 96.92%);
box-shadow: 0px 4px 13px 3px rgba(48, 65, 87, 0.15);
Expand All @@ -67,13 +67,19 @@ header form [type='submit'] {
}

@media only screen and (min-width: 1024px) {
.hero h1 {
font-size: 85px;
line-height: .95em;
}

.hero .banner {
position: relative;
left: -25px;
}
.hero .image {
right: -55px;
}

}

@layer utilities {
Expand Down
2 changes: 1 addition & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function Home() {
const { products } = useContext(SearchContext);

return (
<div className="flex flex-col max-w-5xl min-h-screen mx-auto">
<div className="flex flex-col max-w-full lg:max-w-5xl min-h-screen mx-auto">
<Header />
<main>{products.length ? <SearchResults /> : <Hero />}</main>
{products.length ? <Footer /> : null}
Expand Down

0 comments on commit f9f8d59

Please sign in to comment.