-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sa): algolia search functions, move layout to root
remove concierge mode prompt adjustments
- Loading branch information
Showing
95 changed files
with
1,539 additions
and
823 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
starters/shopify-algolia/app/(ai-browse)/_components/ai-commerce-context.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
"use client" | ||
|
||
import * as React from "react" | ||
import type { ChatRequestOptions, CreateMessage, Message } from "ai" | ||
import { useChat } from "ai/react" | ||
|
||
interface AiCommerceContextType { | ||
messages: Message[] | ||
append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined> | ||
input: string | ||
isLoading: boolean | ||
handleSubmit: (e?: { preventDefault: () => void }) => void | ||
setInput: (value: string) => void | ||
} | ||
|
||
const AiCommerceContext = React.createContext<AiCommerceContextType | undefined>(undefined) | ||
|
||
export function useAiCommerce() { | ||
const context = React.useContext(AiCommerceContext) | ||
if (!context) { | ||
throw new Error("useAiCommerce must be used within an AiCommerceProvider") | ||
} | ||
return context | ||
} | ||
|
||
interface AiCommerceProviderProps { | ||
children: React.ReactNode | ||
} | ||
|
||
export function AiCommerceProvider({ children }: AiCommerceProviderProps) { | ||
const { append, messages, input, handleSubmit, setInput, isLoading } = useChat({ | ||
api: "/api/search", | ||
maxSteps: 10, | ||
}) | ||
|
||
const value = React.useMemo( | ||
() => ({ | ||
messages, | ||
input, | ||
isLoading, | ||
handleSubmit, | ||
setInput, | ||
append, | ||
}), | ||
[messages, input, isLoading, handleSubmit, setInput] | ||
) | ||
|
||
return <AiCommerceContext.Provider value={value}>{children}</AiCommerceContext.Provider> | ||
} |
57 changes: 57 additions & 0 deletions
57
starters/shopify-algolia/app/(ai-browse)/_components/chat-suggestions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { useEffect, useState } from "react" | ||
import { motion } from "framer-motion" | ||
import { useChat } from "ai/react" | ||
import { toast } from "sonner" | ||
import { useAiCommerce } from "./ai-commerce-context" | ||
import { PromptSuggestion, PromptSuggestions } from "components/ui/prompt-suggestions" | ||
|
||
const INIT_SUGGESTIONS = ["Show me electronics under 250$", "Show me best-selling lips", "What are current products on sale?", "I'm looking for sportswear"] | ||
|
||
export function Suggestions() { | ||
const { isLoading, append, messages } = useAiCommerce() | ||
const [currentSuggestions, setCurrentSuggestions] = useState<string[]>(INIT_SUGGESTIONS) | ||
const { data: streamingData, append: appendSuggestions } = useChat({ | ||
api: "/api/suggestions", | ||
}) | ||
|
||
useEffect(() => { | ||
if (!streamingData) return | ||
|
||
const newSuggestions = streamingData.filter((message: any) => message.type === "suggestion" && message.content.content).map((message: any) => message.content.content) | ||
|
||
if (newSuggestions.length > 0) { | ||
// Start from an empty array and take up to 5 new suggestions | ||
setCurrentSuggestions(newSuggestions.slice(newSuggestions.length - 5)) | ||
} | ||
}, [streamingData]) | ||
|
||
const handleClick = (suggestion: string) => { | ||
if (isLoading) { | ||
toast.error("Please wait for the model to finish its response!") | ||
return | ||
} | ||
|
||
append({ role: "user", content: suggestion }) | ||
appendSuggestions({ | ||
role: "user", | ||
content: messages | ||
.filter((message) => message.role === "user") | ||
.map((message) => message.content) | ||
.join(""), | ||
}) | ||
// Clear current suggestions after clicking | ||
setCurrentSuggestions([]) | ||
} | ||
|
||
return ( | ||
<PromptSuggestions className="my-4"> | ||
{currentSuggestions.map((suggestion, index) => ( | ||
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: 20 }} transition={{ delay: 0.1 * index }} key={`suggestion-${index}`}> | ||
<PromptSuggestion disabled={isLoading} value={suggestion} onClick={() => handleClick(suggestion)}> | ||
{suggestion} | ||
</PromptSuggestion> | ||
</motion.div> | ||
))} | ||
</PromptSuggestions> | ||
) | ||
} |
26 changes: 26 additions & 0 deletions
26
starters/shopify-algolia/app/(ai-browse)/ai/category/clp/[slug]/[page]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { Metadata } from "next" | ||
import { CategoryView } from "components/category/category-view" | ||
|
||
export const revalidate = 86400 | ||
export const dynamic = "force-static" | ||
|
||
interface CategoryPageProps { | ||
params: Promise<{ slug: string; page: string }> | ||
} | ||
|
||
export async function generateMetadata(props: CategoryPageProps): Promise<Metadata> { | ||
const params = await props.params | ||
return { | ||
title: `${params.slug} | Enterprise Commerce`, | ||
description: "In excepteur elit mollit in.", | ||
} | ||
} | ||
|
||
export async function generateStaticParams() { | ||
return [] | ||
} | ||
|
||
export default async function CategoryPage(props: CategoryPageProps) { | ||
const params = await props.params | ||
return <CategoryView searchParams={{ page: params.page }} params={params} basePath="ai" /> | ||
} |
35 changes: 35 additions & 0 deletions
35
starters/shopify-algolia/app/(ai-browse)/ai/category/clp/[slug]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { Metadata } from "next" | ||
import { isDemoMode } from "utils/demo-utils" | ||
import { getCategories } from "lib/algolia" | ||
import { CategoryView } from "components/category/category-view" | ||
|
||
export const revalidate = 86400 | ||
export const dynamic = "force-static" | ||
|
||
interface CategoryPageProps { | ||
params: Promise<{ slug: string }> | ||
} | ||
|
||
export async function generateMetadata(props: CategoryPageProps): Promise<Metadata> { | ||
const params = await props.params | ||
return { | ||
title: `${params.slug} | Enterprise Commerce`, | ||
description: "In excepteur elit mollit in.", | ||
} | ||
} | ||
|
||
export async function generateStaticParams() { | ||
if (isDemoMode()) return [] | ||
|
||
const { hits } = await getCategories({ | ||
hitsPerPage: 50, | ||
attributesToRetrieve: ["handle"], | ||
}) | ||
|
||
return hits.map(({ handle }) => ({ slug: handle })) | ||
} | ||
|
||
export default async function CategoryPage(props: CategoryPageProps) { | ||
const params = await props.params | ||
return <CategoryView params={params} basePath="ai" /> | ||
} |
26 changes: 26 additions & 0 deletions
26
starters/shopify-algolia/app/(ai-browse)/ai/category/plp/[slug]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { Metadata } from "next" | ||
import { SearchParamsType } from "types" | ||
import { CategoryView } from "components/category/category-view" | ||
|
||
export const runtime = "nodejs" | ||
|
||
export const revalidate = 86400 | ||
|
||
interface ProductListingPageProps { | ||
searchParams: Promise<SearchParamsType> | ||
params: Promise<{ slug: string }> | ||
} | ||
|
||
export async function generateMetadata(props: ProductListingPageProps): Promise<Metadata> { | ||
const params = await props.params | ||
return { | ||
title: `${params.slug} | Enterprise Commerce`, | ||
description: "In excepteur elit mollit in.", | ||
} | ||
} | ||
|
||
export default async function ProductListingPage(props: ProductListingPageProps) { | ||
const params = await props.params | ||
const searchParams = await props.searchParams | ||
return <CategoryView params={params} searchParams={searchParams} basePath="ai" /> | ||
} |
5 changes: 5 additions & 0 deletions
5
starters/shopify-algolia/app/(ai-browse)/ai/product/[slug]/loading.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { PageSkeleton } from "components/product/page-skeleton" | ||
|
||
export default function Loading() { | ||
return <PageSkeleton /> | ||
} |
File renamed without changes.
File renamed without changes.
Oops, something went wrong.