diff --git a/.cspell.json b/.cspell.json index 8aecb8a..64183de 100644 --- a/.cspell.json +++ b/.cspell.json @@ -7,7 +7,8 @@ "rebackk", "chatbots", "repobeats", - "octocat" + "octocat", + "zustand" ], "flagWords": [], "ignorePaths": [ diff --git a/.github/workflows/prs.yaml b/.github/workflows/prs.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3974428..de4c4f6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,18 +16,16 @@ Please review our [Code of Conduct](./CODE_OF_CONDUCT.md). By participating, you ## :bulb: Asking Questions -If you have any question that does not relate to a bug or a feature request, please use [GitHub Discussions](https://github.com/ghUserName/packageName/discussions) instead of GitHub issues. +If you have any question that does not relate to a bug or a feature request, please use [GitHub Discussions](https://github.com/RebackkHQ/NextJSRAG/discussions) instead of GitHub issues. ## :inbox_tray: How can I Contribute? **GitHub issues** -If you encounter a problem with this library or if you have a new feature you'd like to see in this project, please create [a new issue](https://github.com/Rebackk-Team/pocketbase-adapter/issues/new/choose). +If you encounter a problem with this library or if you have a new feature you'd like to see in this project, please create [a new issue](https://github.com/RebackkHQ/NextJSRAG/issues/new/choose). **GitHub Pull requests** Please leverage the repository's own tools to make sure the code is aligned with our standards: -1. Run all check commands before submitting the PR (`type:check`, `lint:check`, `test:coverage` and `spell:check`) -2. Please commit your changes and run a `setup` command so you can actually check how would the template look like once cleaned up -3. Always leverage the `cz` command to create a commit. We heavily rely on this for automatic releases. \ No newline at end of file +1. Run all check commands before submitting the PR (`type:check`, `lint:check`, `test:coverage` and `spell:check`) \ No newline at end of file diff --git a/biome.json b/biome.json index 48364f8..d2848d4 100644 --- a/biome.json +++ b/biome.json @@ -7,7 +7,10 @@ }, "files": { "ignoreUnknown": false, - "ignore": [] + "ignore": [ + "node_modules", + ".next" + ] }, "formatter": { "enabled": true, @@ -19,7 +22,7 @@ "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": false } }, "javascript": { diff --git a/components.json b/components.json new file mode 100644 index 0000000..7a63543 --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..337c6bb --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +version: '3.8' + +services: + ollama: + build: + context: . + dockerfile: ./docker/Dockerfile.ollama + ports: [ "11434:11434" ] + volumes: + - ollama_data:/root/.ollama + networks: + - net + +volumes: + ollama_data: + driver: local + +networks: + net: + driver: bridge diff --git a/docker/Dockerfile.ollama b/docker/Dockerfile.ollama new file mode 100644 index 0000000..7a4b629 --- /dev/null +++ b/docker/Dockerfile.ollama @@ -0,0 +1,17 @@ +# Use the Ollama base image as the builder stage +FROM ollama/ollama as builder + +# Copy the setup script from the local 'scripts' directory to the root of the container +COPY ./scripts/setup-ollama.sh ./setup-ollama.sh + +# Execute the setup script to configure the Ollama environment +RUN bash ./setup-ollama.sh + +# Start a new stage from the Ollama base image to create the final image +FROM ollama/ollama + +# Copy the configured Ollama setup from the builder stage to the final image +COPY --from=builder /root/.ollama /root/.ollama + +# Expose port 11434 for external access to the application +EXPOSE 11434 \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..64fc567 --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,20 @@ +import createMDX from "@next/mdx"; + +/** + * @type {import('next').NextConfig} + */ +const nextConfig = { + pageExtensions: ["mdx", "ts", "tsx"], + eslint: { + ignoreDuringBuilds: true, + }, + typescript: { + ignoreBuildErrors: true, + }, +}; + +const withMDX = createMDX({ + extension: /\.mdx?$/, +}); + +export default withMDX(nextConfig); diff --git a/next.config.ts b/next.config.ts deleted file mode 100644 index f40a6f9..0000000 --- a/next.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { NextConfig } from "next"; - -const nextConfig: NextConfig = { - eslint: { - ignoreDuringBuilds: true, - }, - typescript: { - ignoreBuildErrors: true, - }, -}; - -export default nextConfig; diff --git a/package.json b/package.json index 0d92858..5904c8b 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "test", + "name": "@rebackk/nextjs-rag", "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev --turbopack", + "dev": "next dev", "build": "next build", "start": "next start", "lint": "biome lint", @@ -13,12 +13,66 @@ "spell:check": "cspell \"{README.md,CODE_OF_CONDUCT.md,CONTRIBUTING.md,.github/*.md,src/**/*.ts}\"" }, "dependencies": { - "next": "15.0.1", - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021" + "@hookform/resolvers": "^3.9.0", + "@mdx-js/loader": "^3.1.0", + "@mdx-js/react": "^3.1.0", + "@next/mdx": "^15.0.1", + "@radix-ui/react-accordion": "^1.2.1", + "@radix-ui/react-alert-dialog": "^1.1.2", + "@radix-ui/react-aspect-ratio": "^1.1.0", + "@radix-ui/react-avatar": "^1.1.1", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-collapsible": "^1.1.1", + "@radix-ui/react-context-menu": "^2.2.2", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-hover-card": "^1.1.2", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-menubar": "^1.1.2", + "@radix-ui/react-navigation-menu": "^1.2.1", + "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-progress": "^1.1.0", + "@radix-ui/react-radio-group": "^1.2.1", + "@radix-ui/react-scroll-area": "^1.2.0", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slider": "^1.2.1", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-tabs": "^1.1.1", + "@radix-ui/react-toast": "^1.2.2", + "@radix-ui/react-toggle": "^1.1.0", + "@radix-ui/react-toggle-group": "^1.1.0", + "@radix-ui/react-tooltip": "^1.1.3", + "@types/mdx": "^2.0.13", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "cmdk": "1.0.0", + "date-fns": "^4.1.0", + "embla-carousel-react": "^8.3.0", + "immer": "^10.1.1", + "input-otp": "^1.2.4", + "lucide-react": "^0.453.0", + "next": "14.2.14", + "next-themes": "^0.3.0", + "react": "18.3.1", + "react-day-picker": "8.10.1", + "react-dom": "18.3.1", + "react-hook-form": "^7.53.1", + "react-resizable-panels": "^2.1.4", + "recharts": "^2.13.0", + "shadcn-ui": "^0.9.2", + "sonner": "^1.5.0", + "tailwind-merge": "^2.5.4", + "tailwindcss-animate": "^1.0.7", + "vaul": "^1.1.0", + "zod": "^3.23.8", + "zustand": "^5.0.0" }, "devDependencies": { "@biomejs/biome": "1.9.4", + "@tailwindcss/typography": "^0.5.15", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/src/app/favicon.ico b/public/favicon.ico similarity index 100% rename from src/app/favicon.ico rename to public/favicon.ico diff --git a/public/file.svg b/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..3e9098b --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/scripts/setup-ollama.sh b/scripts/setup-ollama.sh new file mode 100644 index 0000000..a4948e2 --- /dev/null +++ b/scripts/setup-ollama.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# This line indicates that the script should be run using the Bash shell. +# It uses /usr/bin/env to locate Bash in the user's environment. + +# Start the Ollama server in the background +ollama serve & + +# Pause the script for 10 seconds to allow the server to initialize +sleep 10 + +# Pull the 'orca-mini' model from the Ollama repository +ollama pull qwen2.5:1.5b \ No newline at end of file diff --git a/src/ mdx-components.tsx b/src/ mdx-components.tsx new file mode 100644 index 0000000..e253f9b --- /dev/null +++ b/src/ mdx-components.tsx @@ -0,0 +1,14 @@ +import type { MDXComponents } from "mdx/types"; + +export function useMDXComponents(components: MDXComponents): MDXComponents { + console.log("components", components); + return { + ...components, + h1: (props) =>

, + h2: (props) =>

, + h3: (props) =>

, + h4: (props) =>

, + h5: (props) =>

, + h6: (props) =>
, + }; +} diff --git a/src/app/(chat)/knowledge-base/add/page.tsx b/src/app/(chat)/knowledge-base/add/page.tsx new file mode 100644 index 0000000..0e5cf5f --- /dev/null +++ b/src/app/(chat)/knowledge-base/add/page.tsx @@ -0,0 +1,20 @@ +import { ContentLayout } from "@/components/admin-panel/content-layout"; +import Image from "next/image"; + +export default function AddToKnowledgeBase() { + return ( + +
+ Rebackk Logo +

+ Rebackk RAG Demo | Add To Knowledge Base +

+

+ Add a new knowledge base entry to the Rebackk RAG Demo. The entry will + be used to train the model and improve the generation of responses + tailored to the user's input. +

+
+
+ ); +} \ No newline at end of file diff --git a/src/app/(chat)/knowledge-base/list/page.tsx b/src/app/(chat)/knowledge-base/list/page.tsx new file mode 100644 index 0000000..881704f --- /dev/null +++ b/src/app/(chat)/knowledge-base/list/page.tsx @@ -0,0 +1,25 @@ +import { ContentLayout } from "@/components/admin-panel/content-layout"; +import Image from "next/image"; + +export default function ListKnowledgeBase() { + return ( + +
+ Rebackk Logo +

+ Rebackk RAG Demo | Knowledge Base List +

+

+ View the knowledge base entries in the Rebackk RAG Demo. The entries + are used to train the model and improve the generation of responses + tailored to the user's input. +

+
+
+ ); +} diff --git a/src/app/(chat)/knowledge-base/remove/page.tsx b/src/app/(chat)/knowledge-base/remove/page.tsx new file mode 100644 index 0000000..c7bfbfa --- /dev/null +++ b/src/app/(chat)/knowledge-base/remove/page.tsx @@ -0,0 +1,25 @@ +import { ContentLayout } from "@/components/admin-panel/content-layout"; +import Image from "next/image"; + +export default function RemoveFromKnowledgeBase() { + return ( + +
+ Rebackk Logo +

+ Rebackk RAG Demo | Remove From Knowledge Base +

+

+ Remove a knowledge base entry from the Rebackk RAG Demo. The entry will + be removed from the training data and will no longer be used to generate + responses tailored to the user's input. +

+
+
+ ); +} diff --git a/src/app/(chat)/layout.tsx b/src/app/(chat)/layout.tsx new file mode 100644 index 0000000..c4b9f0d --- /dev/null +++ b/src/app/(chat)/layout.tsx @@ -0,0 +1,37 @@ +import { AdminPanelLayout } from "@/components/admin-panel/admin-panel-layout"; // Import the AdminPanelLayout component for structuring the admin panel layout. +import "@/styles/globals.css"; // Import global CSS styles for the application. +import type { Metadata } from "next"; // Import the Metadata type from Next.js for defining page metadata. + +export const metadata: Metadata = { + title: "RAG Demo | Rebackk", // Title of the page, displayed in the browser tab. + description: + "Retrieval Augmented Generation Demo using Next.js, OLLAMA and VercelAI. For The Community, By Rebackk.", // Brief description of the page's content for SEO and sharing purposes. +}; + +/** + * RootLayout component serves as the main layout for the application. + * It wraps all pages and components with a consistent structure and styling. + * + * @param {Readonly<{ children: React.ReactNode }>} props - The component props containing children elements. + * @returns {JSX.Element} The rendered layout containing the admin panel structure and the main content. + */ +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; // The content to be rendered within the layout, passed as children props. +}>) { + return ( + + {/* Sets the language of the document to English for accessibility and SEO. */} + + + {/* Wraps the main content with the AdminPanelLayout for consistent styling and structure. */} +
+ {/* Main content area with horizontal padding. */} + {children} +
+
+ + + ); +} diff --git a/src/app/(chat)/page.tsx b/src/app/(chat)/page.tsx new file mode 100644 index 0000000..3fbef84 --- /dev/null +++ b/src/app/(chat)/page.tsx @@ -0,0 +1,22 @@ +import { ContentLayout } from "@/components/admin-panel/content-layout"; +import Image from "next/image"; + +export default function Home() { + return ( + +
+ Rebackk Logo +

Welcome to Rebackk

+

+ Retrieval Augmented Generation Demo using Next.js, OLLAMA and + VercelAI. For The Community, By Rebackk. +

+
+
+ ); +} diff --git a/src/app/(content)/about/page.tsx b/src/app/(content)/about/page.tsx new file mode 100644 index 0000000..0d784d4 --- /dev/null +++ b/src/app/(content)/about/page.tsx @@ -0,0 +1,11 @@ +"use client"; + +import AboutContent from "@/content/about.mdx"; + +export default function About() { + return ( +
+ +
+ ); +} diff --git a/src/app/(content)/contributing/page.tsx b/src/app/(content)/contributing/page.tsx new file mode 100644 index 0000000..e0f25a5 --- /dev/null +++ b/src/app/(content)/contributing/page.tsx @@ -0,0 +1,11 @@ +"use client"; + +import AboutContent from "@/content/contributing.mdx"; + +export default function ContributingGuide() { + return ( +
+ +
+ ); +} diff --git a/src/app/(content)/layout.tsx b/src/app/(content)/layout.tsx new file mode 100644 index 0000000..2c2b93f --- /dev/null +++ b/src/app/(content)/layout.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import "@/styles/globals.css"; +import { ContentNavbar } from "@/components/content/navbar"; +import { Footer } from "@/components/admin-panel/footer"; + +export default function MarketingLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + +
+ +
+
+ {children} +
+
+
+ + ); +} diff --git a/src/app/fonts/GeistMonoVF.woff b/src/app/fonts/GeistMonoVF.woff deleted file mode 100644 index f2ae185..0000000 Binary files a/src/app/fonts/GeistMonoVF.woff and /dev/null differ diff --git a/src/app/fonts/GeistVF.woff b/src/app/fonts/GeistVF.woff deleted file mode 100644 index 1b62daa..0000000 Binary files a/src/app/fonts/GeistVF.woff and /dev/null differ diff --git a/src/app/globals.css b/src/app/globals.css deleted file mode 100644 index 6b717ad..0000000 --- a/src/app/globals.css +++ /dev/null @@ -1,21 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a36cde0..a50e97f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,22 +1,37 @@ -import type { Metadata } from "next"; -import localFont from "next/font/local"; -import "./globals.css"; +import "@/styles/globals.css"; +import { Poppins, Roboto, Fira_Code, Lato } from "next/font/google"; +import { ToastProvider } from "@/components/ui/toast"; +import { Metadata } from "next"; -const geistSans = localFont({ - src: "./fonts/GeistVF.woff", - variable: "--font-geist-sans", - weight: "100 900", +export const metadata: Metadata = { + title: "RAG Demo | Rebackk", // Title of the page, displayed in the browser tab. + description: + "Retrieval Augmented Generation Demo using Next.js, OLLAMA and VercelAI. For The Community, By Rebackk.", // Brief description of the page's content for SEO and sharing purposes. +}; + +const poppins = Poppins({ + subsets: ["latin"], + weight: ["400", "700"], + variable: "--font-poppins", }); -const geistMono = localFont({ - src: "./fonts/GeistMonoVF.woff", - variable: "--font-geist-mono", - weight: "100 900", + +const roboto = Roboto({ + subsets: ["latin"], + weight: ["400", "500", "700"], + variable: "--font-roboto", }); -export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", -}; +const firaCode = Fira_Code({ + subsets: ["latin"], + weight: ["400", "500", "700"], + variable: "--font-fira-code", +}); + +const lato = Lato({ + subsets: ["latin"], + weight: ["400", "700"], + variable: "--font-lato", +}); export default function RootLayout({ children, @@ -25,10 +40,14 @@ export default function RootLayout({ }>) { return ( - - {children} + + +
+ {children} +
+
); diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 3eee014..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import Image from "next/image"; - -export default function Home() { - return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - src/app/page.tsx - - . -
  2. -
  3. Save and see your changes instantly.
  4. -
- - -
- -
- ); -} diff --git a/src/components/admin-panel/admin-panel-layout.tsx b/src/components/admin-panel/admin-panel-layout.tsx new file mode 100644 index 0000000..55fcf61 --- /dev/null +++ b/src/components/admin-panel/admin-panel-layout.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { Footer } from "@/components/admin-panel/footer"; +import { Sidebar } from "@/components/admin-panel/sidebar"; +import { useSidebar } from "@/hooks/use-sidebar"; +import { useStore } from "@/hooks/use-store"; +import { cn } from "@/lib/utils"; + +export function AdminPanelLayout({ + children +}: { + children: React.ReactNode; +}) { + const sidebar = useStore(useSidebar, (x) => x); + if (!sidebar) return null; + const { getOpenState, settings } = sidebar; + return ( + <> + +
+ {children} +
+