Skip to content

Commit

Permalink
Merge branch 'Weaverse:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-phan authored Aug 12, 2024
2 parents 214374b + 826d6ad commit c0fbafa
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 173 deletions.
1 change: 1 addition & 0 deletions app/components/Section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export let layoutInputs: InspectorGroup["inputs"] = [
unit: "px",
},
defaultValue: 0,
helpText: "Should be used in combination with background image or color",
},
];

Expand Down
2 changes: 1 addition & 1 deletion app/modules/QuickView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export function QuickView(props: { data: Jsonify<ProductData> }) {
handle={product?.handle}
selectedVariant={selectedVariant}
onSelectedVariantChange={handleSelectedVariantChange}
swatch={swatches}
swatches={swatches}
variants={variants}
hideUnavailableOptions={hideUnavailableOptions}
/>
Expand Down
9 changes: 6 additions & 3 deletions app/modules/Skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ export function Skeleton({
className?: string;
[key: string]: any;
}) {
const styles = clsx("rounded bg-primary/10", className);

return (
<Component {...props} width={width} height={height} className={styles} />
<Component
{...props}
width={width}
height={height}
className={clsx("rounded bg-body/10", className)}
/>
);
}
6 changes: 3 additions & 3 deletions app/modules/header/DesktopHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Await, Link, useLocation, useRouteLoaderData } from "@remix-run/react";
import { useThemeSettings } from "@weaverse/hydrogen";
import { Suspense, useEffect, useState } from "react";
import useWindowScroll from "react-use/esm/useWindowScroll";
import { IconMagnifyingGlass, IconSignIn, IconUser } from "~/components/Icons";
import { IconMagnifyingGlass, IconUser } from "~/components/Icons";
import { PredictiveSearch } from "~/components/predictive-search/PredictiveSearch";
import { cn } from "~/lib/cn";
import { type EnhancedMenu, useIsHomePath } from "~/lib/utils";
Expand Down Expand Up @@ -94,7 +94,7 @@ function AccountLink({ className }: { className?: string }) {

return (
<Link to="/account" className={className}>
<Suspense fallback={<IconSignIn className="w-5 h-5" />}>
<Suspense fallback={<IconUser className="w-5 h-5" />}>
<Await
resolve={isLoggedIn}
errorElement={<IconUser className="w-5 h-5" />}
Expand All @@ -103,7 +103,7 @@ function AccountLink({ className }: { className?: string }) {
isLoggedIn ? (
<IconUser className="w-5 h-5" />
) : (
<IconSignIn className="w-5 h-5" />
<IconUser className="w-5 h-5" />
)
}
</Await>
Expand Down
9 changes: 2 additions & 7 deletions app/modules/header/MobileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import { useThemeSettings } from "@weaverse/hydrogen";
import clsx from "clsx";
import { Suspense } from "react";
import useWindowScroll from "react-use/esm/useWindowScroll";
import {
IconList,
IconMagnifyingGlass,
IconSignIn,
IconUser,
} from "~/components/Icons";
import { IconList, IconMagnifyingGlass, IconUser } from "~/components/Icons";
import { useIsHomePath } from "~/lib/utils";
import type { RootLoader } from "~/root";
import { Logo } from "../Logo";
Expand Down Expand Up @@ -95,7 +90,7 @@ function AccountLink({ className }: { className?: string }) {

return (
<Link to="/account" className={className}>
<Suspense fallback={<IconSignIn className="w-5 h-5" />}>
<Suspense fallback={<IconUser className="w-5 h-5" />}>
<Await
resolve={isLoggedIn}
errorElement={<IconUser className="w-5 h-5" />}
Expand Down
53 changes: 26 additions & 27 deletions app/modules/product-form/options.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { Image } from "@shopify/hydrogen";
import type { WeaverseImage } from "@weaverse/hydrogen";
import { useThemeSettings } from "@weaverse/hydrogen";
import clsx from "clsx";
import type { SwatchesConfigs } from "~/types/weaverse-hydrogen";

interface VariantOptionProps {
selectedOptionValue: string;
onSelectOptionValue: (optionValue: string) => void;
name: string;
config?: {
type: string;
displayName: string;
size?: "sm" | "md" | "lg";
shape?: string;
};
swatches: {
imageSwatches: any[];
colorSwatches: any[];
};
values: {
isActive: boolean;
isAvailable: boolean;
Expand All @@ -39,21 +30,20 @@ let BUTTON_SIZE_MAP = {
};

export function VariantOption(props: VariantOptionProps) {
let {
name,
values,
selectedOptionValue,
onSelectOptionValue,
swatches,
config,
} = props;
let { name, values, selectedOptionValue, onSelectOptionValue } = props;
let themeSettings = useThemeSettings();
let productSwatches: SwatchesConfigs = themeSettings.productSwatches;
let { options, swatches } = productSwatches;
let optionConf = options.find((opt) => {
return opt.name.toLowerCase() === name.toLowerCase();
});

let {
displayName,
shape = "square",
size = "md",
type = "default",
} = config || {};
} = optionConf || {};

let roundedClassName =
shape === "circle" ? "rounded-full" : shape === "round" ? "rounded-md" : "";
Expand Down Expand Up @@ -83,6 +73,7 @@ export function VariantOption(props: VariantOptionProps) {
<div className="flex gap-4">
{values.map((value) => (
<button
type="button"
key={value.value}
className={clsx(
defaultButtonClassName,
Expand All @@ -102,10 +93,11 @@ export function VariantOption(props: VariantOptionProps) {
<div className="flex gap-4">
{values.map((value) => {
let swatchColor: string =
swatches.colorSwatches.find((color) => color.name === value.value)
?.value || value.value;
swatches.colors.find((c) => c.name === value.value)?.value ||
value.value;
return (
<button
type="button"
key={value.value}
className={clsx(
defaultClassName,
Expand All @@ -130,11 +122,11 @@ export function VariantOption(props: VariantOptionProps) {
{type === "custom-image" && (
<div className="flex gap-4">
{values.map((value) => {
let swatchImage: WeaverseImage =
swatches.imageSwatches.find((image) => image.name === value.value)
?.value || "";
let swatchImage =
swatches.images.find((i) => i.name === value.value)?.value || "";
return (
<button
type="button"
key={value.value}
className={clsx(
defaultClassName,
Expand All @@ -146,7 +138,14 @@ export function VariantOption(props: VariantOptionProps) {
onClick={() => onSelectOptionValue(value.value)}
>
<Image
data={swatchImage}
data={
typeof swatchImage === "object"
? swatchImage
: {
url: swatchImage,
altText: value.value,
}
}
className={clsx(
"w-full h-full object-cover",
roundedClassName,
Expand All @@ -163,6 +162,7 @@ export function VariantOption(props: VariantOptionProps) {
{values.map((value) => {
return (
<button
type="button"
key={value.value}
className={clsx(
defaultClassName,
Expand Down Expand Up @@ -196,7 +196,6 @@ export function VariantOption(props: VariantOptionProps) {
</select>
</div>
)}

{type === "default" && (
<div className="flex gap-4">
{values.map((value) => (
Expand Down
10 changes: 0 additions & 10 deletions app/modules/product-form/variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ interface ProductVariantsProps {
handle: string;
product: NonNullable<ProductQuery["product"]>;
options: NonNullable<ProductQuery["product"]>["options"];
swatch: {
configs: any[];
swatches: any;
};
hideUnavailableOptions?: boolean;
}

Expand All @@ -28,7 +24,6 @@ export function ProductVariants(props: ProductVariantsProps) {
options,
variants,
handle,
swatch,
hideUnavailableOptions,
} = props;

Expand Down Expand Up @@ -102,21 +97,16 @@ export function ProductVariants(props: ProductVariantsProps) {
.filter(Boolean);
let handleSelectOptionValue = (value: string) =>
handleSelectOption(optionName, value);
let config = swatch.configs.find((config) => {
return config.name.toLowerCase() === optionName.toLowerCase();
});
let selectedValue = selectedOptions?.find(
(opt) => opt.name === optionName,
)?.value;

return (
<VariantOption
name={optionName}
config={config}
values={values}
selectedOptionValue={selectedValue || ""}
onSelectOptionValue={handleSelectOptionValue}
swatches={swatch.swatches}
/>
);
}}
Expand Down
37 changes: 18 additions & 19 deletions app/routes/($locale).products.$productHandle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import { seoPayload } from "~/lib/seo.server";
import type { Storefront } from "~/lib/type";
import { WeaverseContent } from "~/weaverse";

export const headers = routeHeaders;
export let headers = routeHeaders;

export async function loader({ params, request, context }: LoaderFunctionArgs) {
const { productHandle } = params;
let { productHandle } = params;
invariant(productHandle, "Missing productHandle param, check route filename");

const selectedOptions = getSelectedProductOptions(request);
const { shop, product } = await context.storefront.query(PRODUCT_QUERY, {
let selectedOptions = getSelectedProductOptions(request);
let { shop, product } = await context.storefront.query(PRODUCT_QUERY, {
variables: {
handle: productHandle,
selectedOptions,
Expand All @@ -50,22 +50,22 @@ export async function loader({ params, request, context }: LoaderFunctionArgs) {
// into it's own separate query that is deferred. So there's a brief moment
// where variant options might show as available when they're not, but after
// this deferred query resolves, the UI will update.
const variants = await context.storefront.query(VARIANTS_QUERY, {
let variants = await context.storefront.query(VARIANTS_QUERY, {
variables: {
handle: productHandle,
country: context.storefront.i18n.country,
language: context.storefront.i18n.language,
},
});

const recommended = getRecommendedProducts(context.storefront, product.id);
let recommended = getRecommendedProducts(context.storefront, product.id);

// TODO: firstVariant is never used because we will always have a selectedVariant due to redirect
// Investigate if we can avoid the redirect for product pages with no search params for first variant
const firstVariant = product.variants.nodes[0];
const selectedVariant = product.selectedVariant ?? firstVariant;
let firstVariant = product.variants.nodes[0];
let selectedVariant = product.selectedVariant ?? firstVariant;

const seo = seoPayload.product({
let seo = seoPayload.product({
product,
selectedVariant,
url: request.url,
Expand Down Expand Up @@ -98,7 +98,7 @@ export async function loader({ params, request, context }: LoaderFunctionArgs) {
});
}

export const meta = ({ matches }: MetaArgs<typeof loader>) => {
export let meta = ({ matches }: MetaArgs<typeof loader>) => {
return getSeoMeta(...matches.map((match) => (match.data as any).seo));
};

Expand All @@ -107,7 +107,7 @@ export const meta = ({ matches }: MetaArgs<typeof loader>) => {
*/
let useApplyFirstVariant = () => {
let { product } = useLoaderData<typeof loader>();
const [searchParams, setSearchParams] = useSearchParams();
let [searchParams, setSearchParams] = useSearchParams();

// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
Expand All @@ -125,7 +125,7 @@ let useApplyFirstVariant = () => {

export default function Product() {
useApplyFirstVariant();
const { product } = useLoaderData<typeof loader>();
let { product } = useLoaderData<typeof loader>();
return (
<>
<WeaverseContent />
Expand Down Expand Up @@ -154,7 +154,7 @@ async function getRecommendedProducts(
storefront: Storefront,
productId: string,
) {
const products = await storefront.query<ProductRecommendationsQuery>(
let products = await storefront.query<ProductRecommendationsQuery>(
RECOMMENDED_PRODUCTS_QUERY,
{
variables: { productId, count: 12 },
Expand All @@ -163,14 +163,13 @@ async function getRecommendedProducts(

invariant(products, "No data returned from Shopify API");

const mergedProducts = (products.recommended ?? [])
let mergedProducts = (products.recommended ?? [])
.concat(products.additional.nodes)
.filter(
(value, index, array) =>
array.findIndex((value2) => value2.id === value.id) === index,
);
.filter((prod, idx, arr) => {
return arr.findIndex(({ id }) => id === prod.id) === idx;
});

const originalProduct = mergedProducts.findIndex(
let originalProduct = mergedProducts.findIndex(
(item) => item.id === productId,
);

Expand Down
24 changes: 14 additions & 10 deletions app/sections/our-team/team-members.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,25 @@ let TeamMembers = forwardRef<HTMLDivElement, HydrogenComponentProps>(
member;
return (
<div key={id} className="items-center bg-gray-50 sm:flex">
<Image
data={avatar}
sizes="auto"
className="w-full h-auto sm:w-48 sm:h-48"
aspectRatio="1/1"
width={500}
height={500}
/>
{avatar && (
<Image
data={avatar}
sizes="auto"
className="w-full h-auto sm:w-48 sm:h-48"
aspectRatio="1/1"
width={500}
height={500}
/>
)}
<div className="p-5">
<div className="text-xl font-semibold tracking-tight">
{name}
</div>
<span className="text-gray-600">{title}</span>
<p className="mt-3 mb-4 font-light text-gray-600">{bio}</p>
<ul className="flex space-x-3 sm:mt-0">
{bio && (
<p className="mt-3 mb-4 font-light text-gray-600">{bio}</p>
)}
<ul className="flex space-x-3">
{linkedin_url && (
<li>
<Link
Expand Down
Loading

0 comments on commit c0fbafa

Please sign in to comment.