Skip to content

Commit

Permalink
merge pnpm lock
Browse files Browse the repository at this point in the history
  • Loading branch information
RohinBhargava committed Nov 8, 2024
2 parents befe5ac + a53dffd commit 28a122c
Show file tree
Hide file tree
Showing 22 changed files with 534 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function createAlgoliaRecords({
const collector = FernNavigation.NodeCollector.collect(root);

if (process.env.KV_REST_API_URL && process.env.KV_REST_API_TOKEN) {
await kv.set(domain, root.roles, { ex: 60 * 60 * 24 });
await kv.set(domain, root.roles ?? [], { ex: 60 * 60 * 24 });
}

const roleIndexes = createRoleIndexes(root.roles ?? []);
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/fern-docs-search-ui/.depcheckrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"ignores": ["autoprefixer", "postcss"],
"ignore-patterns": ["dist"]
}
11 changes: 10 additions & 1 deletion packages/ui/fern-docs-search-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"type": "module",
"scripts": {
"dev": "next dev --turbo",
"dev": "next dev",
"dev:build": "next build",
"dev:start": "next start",
"dev:lint": "next lint"
Expand All @@ -17,7 +17,9 @@
"devDependencies": {
"@types/react": "^18.0.20",
"@types/react-dom": "^18.2.18",
"autoprefixer": "^10.4.16",
"next": "^14",
"postcss": "^8.4.33",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"swr": "^2.2.5",
Expand All @@ -27,19 +29,26 @@
"dependencies": {
"@ai-sdk/anthropic": "^0.0.56",
"@date-fns/tz": "^1.1.2",
"@fern-ui/chatbot": "workspace:*",
"@fern-ui/fern-docs-search-server": "workspace:*",
"@fern-ui/fern-http-method-tag": "workspace:*",
"@vercel/kv": "^2.0.0",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-slot": "^1.1.0",
"ai": "^3.4.33",
"algoliasearch": "^5.10.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.4",
"date-fns": "^2.30.0",
"es-toolkit": "^1.24.0",
"instantsearch.css": "8.5.1",
"instantsearch.js": "4.75.3",
"lucide-react": "^0.378.0",
"react-instantsearch": "7.13.3",
"react-instantsearch-nextjs": "0.3.16",
"server-only": "^0.0.1",
"tailwind-merge": "^2.3.0",
"ts-essentials": "^10.0.1",
"zod": "^3.23.8"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ export async function POST(request: Request): Promise<Response> {
const records: string[] = [];

for (const { objectID, ...hit } of allHits.values()) {
records.push(`* ObjectID=\`${objectID}\`, Record=\`${JSON.stringify(toContent(hit))}\``);
records.push(`${objectID}, ${JSON.stringify(toContent(hit))}`);
}

const { object } = await generateObject({
model: smallModel,
system: "You are a reference extractor.",
Expand All @@ -114,6 +115,7 @@ export async function POST(request: Request): Promise<Response> {
${text}
## Records
ObjectID, Record
${records.join("\n")}`,
});

Expand Down
16 changes: 15 additions & 1 deletion packages/ui/fern-docs-search-ui/src/app/client-component.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"use client";

import { DesktopInstantSearch } from "@/components/desktop/DesktopInstantSearch";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { useInitialResults } from "@/hooks/useInitialResults";
import { ReactElement } from "react";
import { ChatbotModal } from "@fern-ui/chatbot";
import { ReactElement, useState } from "react";
import useSWR from "swr";

export function DesktopInstantSearchClient({ appId, domain }: { appId: string; domain: string }): ReactElement | false {
const [isChatOpen, setIsChatOpen] = useState(false);

const handleSubmit = (path: string) => {
window.open(`https://${domain}${path}`, "_blank", "noopener,noreferrer");
};
Expand All @@ -20,6 +24,10 @@ export function DesktopInstantSearchClient({ appId, domain }: { appId: string; d

const { initialResults } = useInitialResults(domain);

const chatStream = async (_message: string, _conversationId: string) => {
return [undefined, new AbortController()] as const;
};

if (!apiKey) {
return false;
}
Expand All @@ -39,9 +47,15 @@ export function DesktopInstantSearchClient({ appId, domain }: { appId: string; d
appId={appId}
apiKey={apiKey}
onSubmit={handleSubmit}
onAskAI={() => setIsChatOpen(true)}
// disabled={isLoading || initialResultsLoading || !apiKey}
initialResults={initialResults}
/>
<Dialog open={isChatOpen} onOpenChange={setIsChatOpen}>
<DialogContent>
<ChatbotModal chatStream={chatStream} />
</DialogContent>
</Dialog>
</>
);
}
14 changes: 8 additions & 6 deletions packages/ui/fern-docs-search-ui/src/app/component.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"use client";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useRouter, useSearchParams } from "next/navigation";
import { useState, type ReactElement } from "react";
import { useFormStatus } from "react-dom";
Expand Down Expand Up @@ -31,15 +33,15 @@ export function DesktopInstantSearchWrapper({ appId }: { appId: string }): React
}
}}
>
<input
<Input
name="domain"
className="border rounded-md p-2 dark:bg-black flex-1"
className="border rounded-md p-2 bg-white dark:bg-black flex-1"
placeholder="yourdocs.docs.buildwithfern.com"
defaultValue={selectedDomain}
/>
<button type="submit" className="border rounded-md p-2">
<Button type="submit" className="border rounded-md p-2">
Set Domain
</button>
</Button>
</form>
<form action={() => handleReindex(selectedDomain)}>
<SubmitButton />
Expand All @@ -56,8 +58,8 @@ export function DesktopInstantSearchWrapper({ appId }: { appId: string }): React
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending} className="border rounded-md p-2 disabled:opacity-50">
<Button type="submit" disabled={pending} className="border rounded-md p-2 disabled:opacity-50">
Reindex
</button>
</Button>
);
}
88 changes: 75 additions & 13 deletions packages/ui/fern-docs-search-ui/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,23 +1,85 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "@fern-ui/chatbot/src/index.scss";

:root {
--background: #ffffff;
--foreground: #171717;
body {
font-family:
-apple-system,
blinkmacsystemfont,
segoe ui,
roboto,
oxygen,
ubuntu,
cantarell,
open sans,
helvetica neue,
sans-serif;
}

@media (prefers-color-scheme: dark) {
@layer base {
:root {
--background: #0a0a0a;
--foreground: #ededed;
--background: 108 100% 99%;
--foreground: 120 33% 5%;
--card: 108 100% 99%;
--card-foreground: 120 33% 5%;
--popover: 108 100% 99%;
--popover-foreground: 120 33% 5%;
--primary: 127 72% 37%;
--primary-foreground: 0 0% 98%;
--secondary: 108 20% 95%;
--secondary-foreground: 0 0% 9%;
--muted: 108 20% 95%;
--muted-foreground: 0 0% 45.1%;
--accent: 108 20% 95%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 127 72% 37%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
}
.dark {
--background: 120 33% 5%;
--foreground: 0 0% 98%;
--card: 120 33% 5%;
--card-foreground: 0 0% 98%;
--popover: 120 33% 5%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 120 34% 12%;
--secondary-foreground: 0 0% 98%;
--muted: 120 34% 12%;
--muted-foreground: 0 0% 63.9%;
--accent: 120 34% 12%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 120 34% 12%;
--input: 120 34% 12%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}

body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

@layer components {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/fern-docs-search-ui/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DesktopInstantSearchWrapper } from "./component";

export default async function Home(): Promise<ReactElement> {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
<Suspense fallback={<div>Loading...</div>}>
<DesktopInstantSearchWrapper appId={algoliaAppId()} />
Expand Down
27 changes: 27 additions & 0 deletions packages/ui/fern-docs-search-ui/src/components/chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use client";

import { useChat } from "ai/react";
import { ReactElement } from "react";

export default function Chat(): ReactElement {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<div className="flex flex-col w-full max-w-md py-24 mx-auto stretch">
{messages.map((m) => (
<div key={m.id} className="whitespace-pre-wrap">
{m.role === "user" ? "User: " : "AI: "}
{m.content}
</div>
))}

<form onSubmit={handleSubmit}>
<input
className="fixed bottom-0 w-full max-w-md p-2 mb-8 border border-gray-300 rounded shadow-xl"
value={input}
placeholder="Say something..."
onChange={handleInputChange}
/>
</form>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { InitialResultsResponse } from "@/server/browse-results";
import { AlgoliaRecord } from "@fern-ui/fern-docs-search-server/types";
import { Command } from "cmdk";
import { FileText, History, MessageCircle } from "lucide-react";
import { ReactElement, useDeferredValue } from "react";
import { useHits, useSearchBox } from "react-instantsearch";
import { MarkRequired } from "ts-essentials";
import { RegularCalendarIcon } from "../icons/RegularCalendarIcon";
import { RegularFileLinesIcon } from "../icons/RegularFileLinesIcon";
import { RemoteIcon } from "../icons/RemoteIcon";
import { HitContent } from "../shared/HitContent";
import { generateHits } from "../shared/hits";
Expand All @@ -17,10 +16,12 @@ export function DesktopCommand({
initialResults,
placeholder,
onSubmit,
onAskAI,
}: {
initialResults: InitialResultsResponse;
placeholder?: string;
onSubmit: (path: string) => void;
onAskAI?: () => void;
}): ReactElement {
const { query, refine } = useSearchBox();
const { items: rawHits } = useHits<AlgoliaRecord>();
Expand All @@ -43,22 +44,32 @@ export function DesktopCommand({
No results found
</Command.Empty>
<Command.List className="mb-3">
<Command.Group className="mt-3">
<Command.Item value="ai-chat" className="flex gap-2 cursor-default" onSelect={() => onAskAI?.()}>
<MessageCircle className={ICON_CLASS} />
<span>
Ask AI
{query.trimStart().length > 0 && (
<>
<span className="ms-1">&ldquo;</span>
<span className="font-semibold">{query}</span>
<span>&rdquo;</span>
</>
)}
</span>
</Command.Item>
</Command.Group>

{groups.map((group, index) => (
<Command.Group key={group.title ?? index} heading={group.title} className="mt-3">
<Command.Group key={group.title ?? index} heading={group.title ?? "Results"} className="mt-3">
{group.hits.map((hit) => (
<Command.Item
key={hit.path}
value={hit.path}
onSelect={() => onSubmit(hit.path)}
className="flex gap-2 cursor-default"
>
{hit.icon != null ? (
<RemoteIcon icon={hit.icon} className={ICON_CLASS} />
) : hit.record?.type === "changelog" ? (
<RegularCalendarIcon className={ICON_CLASS} />
) : (
<RegularFileLinesIcon className={ICON_CLASS} />
)}
<Icon icon={hit.icon} type={hit.record?.type} />
{hit.record != null && (
<HitContent hit={hit.record as MarkRequired<AlgoliaRecordHit, "type">} />
)}
Expand All @@ -71,3 +82,15 @@ export function DesktopCommand({
</Command>
);
}

function Icon({ icon, type }: { icon: string | undefined; type: string | undefined }): ReactElement {
if (icon) {
return <RemoteIcon icon={icon} className={ICON_CLASS} />;
}

if (type === "changelog") {
return <History className={ICON_CLASS} />;
}

return <FileText className={ICON_CLASS} />;
}
Loading

0 comments on commit 28a122c

Please sign in to comment.