mirror of
https://github.com/vercel/commerce.git
synced 2025-07-26 19:51:23 +00:00
preview bar
This commit is contained in:
15
components/agility-common/LoadingWidget.js
Normal file
15
components/agility-common/LoadingWidget.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { CgSpinner } from "react-icons/cg";
|
||||
|
||||
const Widget = ({ message }) => {
|
||||
return (
|
||||
<section
|
||||
id="loading-widget"
|
||||
className="flex flex-col items-center justify-center h-screen"
|
||||
>
|
||||
<CgSpinner className="animate-spin text-2xl mb-2" />
|
||||
<p>{message}</p>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Widget;
|
155
components/agility-common/PreviewBar.js
Normal file
155
components/agility-common/PreviewBar.js
Normal file
@@ -0,0 +1,155 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
FaInfoCircle,
|
||||
FaGithub,
|
||||
FaChevronDown,
|
||||
FaChevronUp,
|
||||
} from "react-icons/fa";
|
||||
|
||||
/**
|
||||
* This is a preview bar that is enabled by default to handle viewing content in preview & live mode, remove this for production use.
|
||||
**/
|
||||
|
||||
const PreviewBar = ({ isPreview, isDevelopmentMode }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
// handle view function to determine preview / live mode
|
||||
const handleView = () => {
|
||||
if (isDevelopmentMode) {
|
||||
alert("You are currently in Development Mode, Live Mode is unavailable.");
|
||||
} else {
|
||||
if (!isDevelopmentMode && !isPreview) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.onload = function () {
|
||||
// Process our return data
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
// What do when the request is successful
|
||||
const previewKey = xhr.responseText;
|
||||
|
||||
window.location.replace(
|
||||
`${window.location.pathname}?agilitypreviewkey=${escape(
|
||||
previewKey
|
||||
)}`
|
||||
);
|
||||
}
|
||||
};
|
||||
// Create and send a GET request
|
||||
xhr.open("GET", "/api/generatePreviewKey");
|
||||
xhr.send();
|
||||
} else {
|
||||
const exit = confirm("Would you like to exit Preview Mode?");
|
||||
if (exit === true) {
|
||||
window.location.href = `/api/exitPreview?slug=${window.location.pathname}`;
|
||||
} else return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-agility relative px-8 text-gray-200">
|
||||
<div className="flex justify-between items-center max-w-screen-xl mx-auto">
|
||||
<div className="flex items-center">
|
||||
<span className="p-2 rounded-lg mr-4">
|
||||
<a
|
||||
href="https://www.agilitycms.com"
|
||||
target="_blank"
|
||||
title="Agility CMS"
|
||||
>
|
||||
<img
|
||||
src="https://static.agilitycms.com/brand/agility-triangle-yellow.svg"
|
||||
alt="Agility CMS"
|
||||
className="w-5 h-5 block md:hidden"
|
||||
/>
|
||||
<img
|
||||
src="/assets/agility-preview-logo.svg"
|
||||
alt="Agility CMS"
|
||||
className="h-5 w-20 hidden md:block"
|
||||
/>
|
||||
</a>
|
||||
</span>
|
||||
<div className="mr-4">
|
||||
<a
|
||||
href="https://help.agilitycms.com/hc/en-us"
|
||||
target="_blank"
|
||||
title="Help Center"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<FaInfoCircle className="text-2xl mr-2" />
|
||||
<p className="hidden md:block text-sm">Help Center</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://github.com/agility/agilitycms-nextjs-starter"
|
||||
target="_blank"
|
||||
title="View on GitHub"
|
||||
className="text-2xl"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<FaGithub className="mr-2" />
|
||||
<p className="hidden md:block text-sm">View on GitHub</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`relative flex items-center ${
|
||||
open ? `bg-white ` : `bg-agility`
|
||||
} py-4`}
|
||||
>
|
||||
{isPreview ? (
|
||||
<p
|
||||
className={`hidden md:block text-sm px-2 ${
|
||||
open ? `text-agility` : `text-gray-200`
|
||||
}`}
|
||||
>
|
||||
Previewing <span className="font-bold">Latest</span> Changes
|
||||
</p>
|
||||
) : (
|
||||
<p
|
||||
className={`hidden md:block text-sm px-2 ${
|
||||
open ? `text-agility` : `text-gray-200`
|
||||
}`}
|
||||
>
|
||||
Viewing <span className="font-bold">Published</span> Content
|
||||
</p>
|
||||
)}
|
||||
<div
|
||||
className="p-2 text-gray-200 rounded-lg cursor-pointer z-50"
|
||||
onClick={() => setOpen(!open)}
|
||||
>
|
||||
{open ? (
|
||||
<FaChevronUp className="text-agility" />
|
||||
) : (
|
||||
<FaChevronDown className="text-gray-200" />
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="absolute bg-white text-white text-sm py-4 px-4 -right-0 -bottom-28 md:-bottom-16 z-50 rounded-b-lg shadow-xl md:max-w-full"
|
||||
style={{ display: open ? "block" : "none", width: "15.1rem" }}
|
||||
>
|
||||
{isPreview ? (
|
||||
<p className="mb-4 text-center md:hidden text-agility z-20">
|
||||
Previewing <span className="font-bold">Latest</span> Changes
|
||||
</p>
|
||||
) : (
|
||||
<p className="mb-4 text-center md:hidden text-agility z-20">
|
||||
Viewing <span className="font-bold">Published</span> Content
|
||||
</p>
|
||||
)}
|
||||
<button
|
||||
className="text-gray-200 bg-agility p-2 w-full rounded-md text-sm"
|
||||
onClick={() => handleView()}
|
||||
>
|
||||
{`View ${isPreview ? `Live` : `Preview`} Mode`}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PreviewBar;
|
@@ -13,122 +13,138 @@ import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
|
||||
import { Sidebar, Button, Modal, LoadingDots } from '@components/ui'
|
||||
import PaymentMethodView from '@components/checkout/PaymentMethodView'
|
||||
import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView'
|
||||
import { handlePreview } from "@agility/nextjs";
|
||||
|
||||
import LoginView from '@components/auth/LoginView'
|
||||
import s from './Layout.module.css'
|
||||
import LoadingWidget from '@components/agility-common/LoadingWidget'
|
||||
import PreviewBar from '@components/agility-common/PreviewBar'
|
||||
|
||||
const Loading = () => (
|
||||
<div className="w-80 h-80 flex items-center text-center justify-center p-3">
|
||||
<LoadingDots />
|
||||
</div>
|
||||
<div className="w-80 h-80 flex items-center text-center justify-center p-3">
|
||||
<LoadingDots />
|
||||
</div>
|
||||
)
|
||||
|
||||
const dynamicProps = {
|
||||
loading: () => <Loading />,
|
||||
loading: () => <Loading />,
|
||||
}
|
||||
|
||||
const SignUpView = dynamic(
|
||||
() => import('@components/auth/SignUpView'),
|
||||
dynamicProps
|
||||
() => import('@components/auth/SignUpView'),
|
||||
dynamicProps
|
||||
)
|
||||
|
||||
const ForgotPassword = dynamic(
|
||||
() => import('@components/auth/ForgotPassword'),
|
||||
dynamicProps
|
||||
() => import('@components/auth/ForgotPassword'),
|
||||
dynamicProps
|
||||
)
|
||||
|
||||
const FeatureBar = dynamic(
|
||||
() => import('@components/common/FeatureBar'),
|
||||
dynamicProps
|
||||
() => import('@components/common/FeatureBar'),
|
||||
dynamicProps
|
||||
)
|
||||
|
||||
interface Props {
|
||||
pageProps: {
|
||||
pages?: Page[]
|
||||
categories: Category[],
|
||||
agilityProps: any
|
||||
}
|
||||
pageProps: {
|
||||
pages?: Page[]
|
||||
categories: Category[],
|
||||
agilityProps: any
|
||||
}
|
||||
}
|
||||
|
||||
const ModalView: FC<{ modalView: string; closeModal(): any }> = ({
|
||||
modalView,
|
||||
closeModal,
|
||||
modalView,
|
||||
closeModal,
|
||||
}) => {
|
||||
return (
|
||||
<Modal onClose={closeModal}>
|
||||
{modalView === 'LOGIN_VIEW' && <LoginView />}
|
||||
{modalView === 'SIGNUP_VIEW' && <SignUpView />}
|
||||
{modalView === 'FORGOT_VIEW' && <ForgotPassword />}
|
||||
</Modal>
|
||||
)
|
||||
return (
|
||||
<Modal onClose={closeModal}>
|
||||
{modalView === 'LOGIN_VIEW' && <LoginView />}
|
||||
{modalView === 'SIGNUP_VIEW' && <SignUpView />}
|
||||
{modalView === 'FORGOT_VIEW' && <ForgotPassword />}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
const ModalUI: FC = () => {
|
||||
const { displayModal, closeModal, modalView } = useUI()
|
||||
return displayModal ? (
|
||||
<ModalView modalView={modalView} closeModal={closeModal} />
|
||||
) : null
|
||||
const { displayModal, closeModal, modalView } = useUI()
|
||||
return displayModal ? (
|
||||
<ModalView modalView={modalView} closeModal={closeModal} />
|
||||
) : null
|
||||
}
|
||||
|
||||
const SidebarView: FC<{ sidebarView: string; closeSidebar(): any }> = ({
|
||||
sidebarView,
|
||||
closeSidebar,
|
||||
sidebarView,
|
||||
closeSidebar,
|
||||
}) => {
|
||||
return (
|
||||
<Sidebar onClose={closeSidebar}>
|
||||
{sidebarView === 'CART_VIEW' && <CartSidebarView />}
|
||||
{sidebarView === 'CHECKOUT_VIEW' && <CheckoutSidebarView />}
|
||||
{sidebarView === 'PAYMENT_VIEW' && <PaymentMethodView />}
|
||||
{sidebarView === 'SHIPPING_VIEW' && <ShippingView />}
|
||||
</Sidebar>
|
||||
)
|
||||
return (
|
||||
<Sidebar onClose={closeSidebar}>
|
||||
{sidebarView === 'CART_VIEW' && <CartSidebarView />}
|
||||
{sidebarView === 'CHECKOUT_VIEW' && <CheckoutSidebarView />}
|
||||
{sidebarView === 'PAYMENT_VIEW' && <PaymentMethodView />}
|
||||
{sidebarView === 'SHIPPING_VIEW' && <ShippingView />}
|
||||
</Sidebar>
|
||||
)
|
||||
}
|
||||
|
||||
const SidebarUI: FC = () => {
|
||||
const { displaySidebar, closeSidebar, sidebarView } = useUI()
|
||||
return displaySidebar ? (
|
||||
<SidebarView sidebarView={sidebarView} closeSidebar={closeSidebar} />
|
||||
) : null
|
||||
const { displaySidebar, closeSidebar, sidebarView } = useUI()
|
||||
return displaySidebar ? (
|
||||
<SidebarView sidebarView={sidebarView} closeSidebar={closeSidebar} />
|
||||
) : null
|
||||
}
|
||||
|
||||
const Layout: FC<Props> = (props) => {
|
||||
|
||||
// set up handle preview
|
||||
const isPreviewLoading = handlePreview();
|
||||
|
||||
const {
|
||||
children,
|
||||
pageProps: { agilityProps, ...pageProps },
|
||||
} = props
|
||||
} = props
|
||||
|
||||
|
||||
const { acceptedCookies, onAcceptCookies } = useAcceptCookies()
|
||||
const { locale = 'en-US' } = useRouter()
|
||||
const { acceptedCookies, onAcceptCookies } = useAcceptCookies()
|
||||
const { locale = 'en-US' } = useRouter()
|
||||
|
||||
const categories = agilityProps?.globalData?.sitedata?.categoryLinks || []
|
||||
const categories = agilityProps?.globalData?.sitedata?.categoryLinks || []
|
||||
|
||||
const navBarlinks = categories.slice(0, 2).map((c:any) => ({
|
||||
label: c.name,
|
||||
href: `/search/${c.slug}`,
|
||||
}))
|
||||
const navBarlinks = categories.slice(0, 2).map((c: any) => ({
|
||||
label: c.name,
|
||||
href: `/search/${c.slug}`,
|
||||
}))
|
||||
|
||||
return (
|
||||
<CommerceProvider locale={locale}>
|
||||
<div className={cn(s.root)}>
|
||||
<Navbar links={navBarlinks} agilityProps={agilityProps}/>
|
||||
<main className="fit">{children}</main>
|
||||
<Footer pages={pageProps.pages} agilityProps={agilityProps} />
|
||||
<ModalUI />
|
||||
<SidebarUI />
|
||||
<FeatureBar
|
||||
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
|
||||
hide={acceptedCookies}
|
||||
action={
|
||||
<Button className="mx-5" onClick={() => onAcceptCookies()}>
|
||||
Accept cookies
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</CommerceProvider>
|
||||
)
|
||||
return (
|
||||
<CommerceProvider locale={locale}>
|
||||
|
||||
<div className={cn(s.root)}>
|
||||
|
||||
{isPreviewLoading &&
|
||||
<LoadingWidget message="Loading Preview Mode" />
|
||||
}
|
||||
{!isPreviewLoading &&
|
||||
<>
|
||||
<PreviewBar isDevelopmentMode={agilityProps.isDevelopmentMode} isPreview={agilityProps.isPreview}/>
|
||||
<Navbar links={navBarlinks} agilityProps={agilityProps} />
|
||||
<main className="fit">{children}</main>
|
||||
<Footer pages={pageProps.pages} agilityProps={agilityProps} />
|
||||
<ModalUI />
|
||||
<SidebarUI />
|
||||
<FeatureBar
|
||||
title="This site uses cookies to improve your experience. By clicking, you agree to our Privacy Policy."
|
||||
hide={acceptedCookies}
|
||||
action={
|
||||
<Button className="mx-5" onClick={() => onAcceptCookies()}>
|
||||
Accept cookies
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</CommerceProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
||||
|
Reference in New Issue
Block a user