### What problem does this PR solve? feat: Add banner #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.14.0
| "@hookform/resolvers": "^3.9.1", | "@hookform/resolvers": "^3.9.1", | ||||
| "@js-preview/excel": "^1.7.8", | "@js-preview/excel": "^1.7.8", | ||||
| "@monaco-editor/react": "^4.6.0", | "@monaco-editor/react": "^4.6.0", | ||||
| "@radix-ui/react-aspect-ratio": "^1.1.0", | |||||
| "@radix-ui/react-avatar": "^1.1.1", | "@radix-ui/react-avatar": "^1.1.1", | ||||
| "@radix-ui/react-checkbox": "^1.1.2", | "@radix-ui/react-checkbox": "^1.1.2", | ||||
| "@radix-ui/react-dropdown-menu": "^2.1.2", | "@radix-ui/react-dropdown-menu": "^2.1.2", | ||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/@radix-ui/react-aspect-ratio": { | |||||
| "version": "1.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.0.tgz", | |||||
| "integrity": "sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==", | |||||
| "dependencies": { | |||||
| "@radix-ui/react-primitive": "2.0.0" | |||||
| }, | |||||
| "peerDependencies": { | |||||
| "@types/react": "*", | |||||
| "@types/react-dom": "*", | |||||
| "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", | |||||
| "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" | |||||
| }, | |||||
| "peerDependenciesMeta": { | |||||
| "@types/react": { | |||||
| "optional": true | |||||
| }, | |||||
| "@types/react-dom": { | |||||
| "optional": true | |||||
| } | |||||
| } | |||||
| }, | |||||
| "node_modules/@radix-ui/react-avatar": { | "node_modules/@radix-ui/react-avatar": { | ||||
| "version": "1.1.1", | "version": "1.1.1", | ||||
| "resolved": "https://registry.npmmirror.com/@radix-ui/react-avatar/-/react-avatar-1.1.1.tgz", | "resolved": "https://registry.npmmirror.com/@radix-ui/react-avatar/-/react-avatar-1.1.1.tgz", |
| "@hookform/resolvers": "^3.9.1", | "@hookform/resolvers": "^3.9.1", | ||||
| "@js-preview/excel": "^1.7.8", | "@js-preview/excel": "^1.7.8", | ||||
| "@monaco-editor/react": "^4.6.0", | "@monaco-editor/react": "^4.6.0", | ||||
| "@radix-ui/react-aspect-ratio": "^1.1.0", | |||||
| "@radix-ui/react-avatar": "^1.1.1", | "@radix-ui/react-avatar": "^1.1.1", | ||||
| "@radix-ui/react-checkbox": "^1.1.2", | "@radix-ui/react-checkbox": "^1.1.2", | ||||
| "@radix-ui/react-dropdown-menu": "^2.1.2", | "@radix-ui/react-dropdown-menu": "^2.1.2", |
| 'use client'; | |||||
| import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'; | |||||
| const AspectRatio = AspectRatioPrimitive.Root; | |||||
| export { AspectRatio }; |
| import { cva, type VariantProps } from 'class-variance-authority'; | |||||
| import * as React from 'react'; | |||||
| import { cn } from '@/lib/utils'; | |||||
| const badgeVariants = cva( | |||||
| 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', | |||||
| { | |||||
| variants: { | |||||
| variant: { | |||||
| default: | |||||
| 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80', | |||||
| secondary: | |||||
| 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', | |||||
| destructive: | |||||
| 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80', | |||||
| outline: 'text-foreground', | |||||
| }, | |||||
| }, | |||||
| defaultVariants: { | |||||
| variant: 'default', | |||||
| }, | |||||
| }, | |||||
| ); | |||||
| export interface BadgeProps | |||||
| extends React.HTMLAttributes<HTMLDivElement>, | |||||
| VariantProps<typeof badgeVariants> {} | |||||
| function Badge({ className, variant, ...props }: BadgeProps) { | |||||
| return ( | |||||
| <div className={cn(badgeVariants({ variant }), className)} {...props} /> | |||||
| ); | |||||
| } | |||||
| export { Badge, badgeVariants }; |
| import { Card, CardContent } from '@/components/ui/card'; | |||||
| import { ArrowRight } from 'lucide-react'; | |||||
| function BannerCard() { | |||||
| return ( | |||||
| <Card className="w-auto border-none h-3/4"> | |||||
| <CardContent className="p-4"> | |||||
| <span className="inline-block bg-backgroundCoreWeak rounded-sm px-1 text-xs"> | |||||
| System | |||||
| </span> | |||||
| <div className="flex mt-1 gap-4"> | |||||
| <span className="text-lg truncate">Setting up your LLM</span> | |||||
| <ArrowRight /> | |||||
| </div> | |||||
| </CardContent> | |||||
| </Card> | |||||
| ); | |||||
| } | |||||
| function MyCard() { | |||||
| return ( | |||||
| <div className="w-[265px] h-[87px] pl-[17px] pr-[13px] py-[15px] bg-[#b8b5cb]/20 rounded-xl border border-[#e6e3f6]/10 backdrop-blur-md justify-between items-end inline-flex"> | |||||
| <div className="grow shrink basis-0 flex-col justify-start items-start gap-[9px] inline-flex"> | |||||
| <div className="px-1 py-0.5 bg-[#644bf7] rounded justify-center items-center gap-2 inline-flex"> | |||||
| <div className="text-white text-xs font-medium font-['IBM Plex Mono'] leading-none"> | |||||
| System | |||||
| </div> | |||||
| </div> | |||||
| <div className="self-stretch text-white text-lg font-normal font-['Inter'] leading-7"> | |||||
| Setting up your LLM | |||||
| </div> | |||||
| </div> | |||||
| <div className="w-6 h-6 relative" /> | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| export function Banner() { | |||||
| return ( | |||||
| <section className="bg-[url('@/assets/banner.png')] bg-cover h-28 rounded-2xl mx-14 my-8 flex gap-8 justify-between"> | |||||
| <div className="h-full text-3xl font-bold items-center inline-flex ml-6"> | |||||
| Welcome to RAGFlow | |||||
| </div> | |||||
| <div className="flex justify-between items-center gap-10 mr-5"> | |||||
| <BannerCard></BannerCard> | |||||
| <BannerCard></BannerCard> | |||||
| <MyCard></MyCard> | |||||
| </div> | |||||
| </section> | |||||
| ); | |||||
| } |
| import { CardWithForm } from './card'; | |||||
| import { Banner } from './banner'; | |||||
| import { HomeHeader } from './header'; | import { HomeHeader } from './header'; | ||||
| import NextBanner from './next-banner'; | |||||
| const Home = () => { | const Home = () => { | ||||
| return ( | return ( | ||||
| <div> | <div> | ||||
| <HomeHeader></HomeHeader> | <HomeHeader></HomeHeader> | ||||
| <section> | <section> | ||||
| <CardWithForm></CardWithForm> | |||||
| <Banner></Banner> | |||||
| <NextBanner></NextBanner> | |||||
| </section> | </section> | ||||
| </div> | </div> | ||||
| ); | ); |
| import { Badge } from '@/components/ui/badge'; | |||||
| import { Card, CardContent } from '@/components/ui/card'; | |||||
| import { ArrowRight, X } from 'lucide-react'; | |||||
| const guideCards = [ | |||||
| { | |||||
| badge: 'System', | |||||
| title: 'Setting up your LLM', | |||||
| }, | |||||
| { | |||||
| badge: 'Chat app', | |||||
| title: 'Configuration guides', | |||||
| }, | |||||
| { | |||||
| badge: 'Search app', | |||||
| title: 'Prompt setting guides', | |||||
| }, | |||||
| ]; | |||||
| export default function WelcomeGuide(): JSX.Element { | |||||
| return ( | |||||
| <div className="flex w-full max-w-[1800px] items-center gap-4 px-[60px] py-6 relative bg-[#223d8e0d] rounded-3xl overflow-hidden"> | |||||
| <div | |||||
| className="absolute inset-0 bg-gradient-to-r from-pink-300 via-purple-400 to-blue-500 opacity-75" | |||||
| style={{ | |||||
| backgroundSize: 'cover', | |||||
| backgroundPosition: 'center', | |||||
| }} | |||||
| /> | |||||
| <h1 className="relative flex-1 text-4xl font-bold text-white"> | |||||
| Welcome to RAGFlow | |||||
| </h1> | |||||
| <div className="inline-flex items-center gap-[22px] relative"> | |||||
| {guideCards.map((card, index) => ( | |||||
| <Card | |||||
| key={index} | |||||
| className="w-[265px] backdrop-blur-md border-colors-outline-neutral-standard" | |||||
| > | |||||
| <CardContent className="flex items-end justify-between p-[15px]"> | |||||
| <div className="flex flex-col items-start gap-[9px] flex-1"> | |||||
| <Badge | |||||
| variant="secondary" | |||||
| className="bg-colors-background-core-weak text-colors-text-neutral-strong" | |||||
| > | |||||
| {card.badge} | |||||
| </Badge> | |||||
| <p className="text-lg text-colors-text-neutral-strong"> | |||||
| {card.title} | |||||
| </p> | |||||
| </div> | |||||
| <ArrowRight className="w-6 h-6" /> | |||||
| </CardContent> | |||||
| </Card> | |||||
| ))} | |||||
| </div> | |||||
| <button className="relative p-1 hover:bg-white/10 rounded-full transition-colors"> | |||||
| <X className="w-6 h-6 text-white" /> | |||||
| </button> | |||||
| </div> | |||||
| ); | |||||
| } |
| DEFAULT: 'var(--background-core-standard)', | DEFAULT: 'var(--background-core-standard)', | ||||
| foreground: 'var(--background-core-standard-foreground)', | foreground: 'var(--background-core-standard-foreground)', | ||||
| }, | }, | ||||
| backgroundCoreWeak: { | |||||
| DEFAULT: 'var(--background-core-weak)', | |||||
| foreground: 'var(--background-core-weak-foreground)', | |||||
| }, | |||||
| }, | }, | ||||
| borderRadius: { | borderRadius: { | ||||
| lg: `var(--radius)`, | lg: `var(--radius)`, |
| --background-inverse-strong: rgba(255, 255, 255, 0.15); | --background-inverse-strong: rgba(255, 255, 255, 0.15); | ||||
| --background-inverse-strong-foreground: rgba(255, 255, 255, 1); | --background-inverse-strong-foreground: rgba(255, 255, 255, 1); | ||||
| --background-core-weak: rgb(101, 75, 248); | |||||
| --background-core-weak-foreground: rgba(255, 255, 255, 1); | |||||
| } | } | ||||
| } | } | ||||