From c3dcb9c827df6d80ad1b0b1a7c6155561527b39d Mon Sep 17 00:00:00 2001 From: l3wdfut4pwr Date: Tue, 30 Dec 2025 13:46:39 +0200 Subject: init --- src/components/footer/Footer.tsx | 24 +++++++++ src/components/footer/index.ts | 1 + src/components/header/Header.tsx | 10 ++++ src/components/header/NavBar.tsx | 75 +++++++++++++++++++++++++++++ src/components/header/ProfileOrLogin.tsx | 25 ++++++++++ src/components/header/SubNav.tsx | 43 +++++++++++++++++ src/components/header/index.ts | 4 ++ src/components/ui/button.tsx | 57 ++++++++++++++++++++++ src/components/ui/index.ts | 2 + src/components/ui/input.tsx | 9 ++++ src/components/ui/switch.tsx | 30 ++++++++++++ src/components/upload/Dropzone.tsx | 45 +++++++++++++++++ src/components/upload/SourceInput.tsx | 20 ++++++++ src/components/upload/TagsInput.tsx | 83 ++++++++++++++++++++++++++++++++ src/components/upload/UploadMenu.tsx | 11 +++++ src/components/upload/index.ts | 4 ++ 16 files changed, 443 insertions(+) create mode 100644 src/components/footer/Footer.tsx create mode 100644 src/components/footer/index.ts create mode 100644 src/components/header/Header.tsx create mode 100644 src/components/header/NavBar.tsx create mode 100644 src/components/header/ProfileOrLogin.tsx create mode 100644 src/components/header/SubNav.tsx create mode 100644 src/components/header/index.ts create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/index.ts create mode 100644 src/components/ui/input.tsx create mode 100644 src/components/ui/switch.tsx create mode 100644 src/components/upload/Dropzone.tsx create mode 100644 src/components/upload/SourceInput.tsx create mode 100644 src/components/upload/TagsInput.tsx create mode 100644 src/components/upload/UploadMenu.tsx create mode 100644 src/components/upload/index.ts (limited to 'src/components') diff --git a/src/components/footer/Footer.tsx b/src/components/footer/Footer.tsx new file mode 100644 index 0000000..9b2a3f2 --- /dev/null +++ b/src/components/footer/Footer.tsx @@ -0,0 +1,24 @@ +import Logo from '@icons/logo.svg'; +import ArtberryIcon from '@icons/artberry.svg'; + +export function Footer() { + return ( + + ); +} diff --git a/src/components/footer/index.ts b/src/components/footer/index.ts new file mode 100644 index 0000000..ddcc5a9 --- /dev/null +++ b/src/components/footer/index.ts @@ -0,0 +1 @@ +export * from './Footer'; diff --git a/src/components/header/Header.tsx b/src/components/header/Header.tsx new file mode 100644 index 0000000..b096bdb --- /dev/null +++ b/src/components/header/Header.tsx @@ -0,0 +1,10 @@ +import { NavBar, SubNav } from '.'; + +export function Header() { + return ( +
+ + +
+ ); +} diff --git a/src/components/header/NavBar.tsx b/src/components/header/NavBar.tsx new file mode 100644 index 0000000..f186904 --- /dev/null +++ b/src/components/header/NavBar.tsx @@ -0,0 +1,75 @@ +//import { ShuffleIcon } from 'lucide-react'; +import ShuffleIcon from '@icons/ShuffleIcon.svg'; +import Image from 'next/image'; +import { Button, Input } from '../ui'; +import { ProfileOrLogin } from './ProfileOrLogin'; +import Link from 'next/link'; +import DiscordIcon from '@icons/discord.svg'; +import { Switch } from '@/components/ui/switch'; +export function NavBar() { + return ( +
+
+ + ARTBERRY + +
+ + +
+
+ AI + +
+
+ NSFW + +
+
+
+
+ + +
+ + + + +
+
+ ); +} + +function Search() { + return ( +
+
+ + +
+
+ ); +} + +function Sections() { + return ( +
+ ); +} diff --git a/src/components/header/ProfileOrLogin.tsx b/src/components/header/ProfileOrLogin.tsx new file mode 100644 index 0000000..38c1eb1 --- /dev/null +++ b/src/components/header/ProfileOrLogin.tsx @@ -0,0 +1,25 @@ +'use client'; + +import Image from 'next/image'; +import { useUser } from '../../lib/contexts'; +import { Button } from '../ui'; +import Link from 'next/link'; + +export function ProfileOrLogin() { + const user = useUser(); + + if (!user) { + return ; + } + + return ( + + + + ); +} diff --git a/src/components/header/SubNav.tsx b/src/components/header/SubNav.tsx new file mode 100644 index 0000000..a446ff0 --- /dev/null +++ b/src/components/header/SubNav.tsx @@ -0,0 +1,43 @@ +import Link from 'next/link'; +import { Button } from '../ui'; +import React from 'react'; +import { cn } from '@/lib/utils'; + +export function SubNav() { + return ( +
+ + ТЕГИ + + + КАТЕГОРИИ + + + ПЕРСОНАЖИ + + + КОЛЛЕКЦИИ + +
+ ); +} + +function SectionLink({ + children, + href, + className, +}: React.PropsWithChildren & { href: string; className?: string }) { + return ( + + ); +} diff --git a/src/components/header/index.ts b/src/components/header/index.ts new file mode 100644 index 0000000..3a75160 --- /dev/null +++ b/src/components/header/index.ts @@ -0,0 +1,4 @@ +export * from './Header'; +export * from './ProfileOrLogin'; +export * from './NavBar'; +export * from './SubNav'; diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..65c1e84 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { Slot } from '@radix-ui/react-slot'; +import { cva, type VariantProps } from 'class-variance-authority'; + +import { cn } from '@/lib/utils'; + +const buttonVariants = cva( + 'inline-flex items-center justify-center gap-2 whitespace-nowrap transition-colors duration-200 ease-out', + { + variants: { + variant: { + default: 'bg-violet rounded-4xl hover:bg-light-violet', + outline: '', + ghost: '', + link: 'hover:text-light-violet', + icon: 'bg-violet hover:bg-light-violet rounded-[10px] cursor-pointer', + menu: 'w-[350px] hover:bg-light-violet active:bg-violet active:border-violet rounded-4xl border-2 border-light-violet justify-start', + }, + size: { + sm: 'py-1.75 px-3.75', + default: 'py-2.5 px-7.5', + lg: 'py-2.5 px-7.5 w-full', + icon: 'size-12.5 p-3.75', + text: '', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, + }, +); + +function Button({ + className, + variant = 'default', + size = 'default', + asChild = false, + ...props +}: React.ComponentProps<'button'> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot : 'button'; + + return ( + + ); +} + +export { Button, buttonVariants }; diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts new file mode 100644 index 0000000..4d2a1a0 --- /dev/null +++ b/src/components/ui/index.ts @@ -0,0 +1,2 @@ +export * from './input'; +export * from './button'; diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 0000000..0424772 --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,9 @@ +import { cn } from '@/lib/utils'; +import React from 'react'; + +export function Input({ + className, + ...props +}: React.InputHTMLAttributes) { + return ; +} diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx new file mode 100644 index 0000000..26fe2c3 --- /dev/null +++ b/src/components/ui/switch.tsx @@ -0,0 +1,30 @@ +'use client'; + +import * as React from 'react'; +import * as SwitchPrimitive from '@radix-ui/react-switch'; + +import { cn } from '@/lib/utils'; + +function Switch({ + className, + ...props +}: React.ComponentProps) { + return ( + + {' '} + + ); +} +export { Switch }; diff --git a/src/components/upload/Dropzone.tsx b/src/components/upload/Dropzone.tsx new file mode 100644 index 0000000..6980f5c --- /dev/null +++ b/src/components/upload/Dropzone.tsx @@ -0,0 +1,45 @@ +'use client'; + +import Dropzone from 'react-dropzone'; +import UploadIcon from '@icons/upload.svg'; +import { Button } from '@/components/ui'; +import { useRef, useState } from 'react'; + +export function FileDropzone() { + // const [files, setFiles] = useState([]); + const hiddenInputRef = useRef(null); + return ( + { + // setFiles((prev) => [...prev, ...acceptedFiles]); + }} + > + {({ getRootProps, getInputProps }) => ( +
+ + + +
+ + + Выбери файлы на компьютере или перетащи сюда. JPG, + PNG до 20MB. + + + {hiddenInputRef.current?.files?.length ?? 0} + +
+ +
+ )} +
+ ); +} diff --git a/src/components/upload/SourceInput.tsx b/src/components/upload/SourceInput.tsx new file mode 100644 index 0000000..c93c4b6 --- /dev/null +++ b/src/components/upload/SourceInput.tsx @@ -0,0 +1,20 @@ +'use client'; +import { Input } from '@/components/ui'; + +export function SourceInput() { + return ( +
+ ИСТОЧНИК + { + if (e.key === 'Enter') { + e.preventDefault(); + } + }} + className="w-full h-10 py-2.5 px-5 border rounded-4xl" + type="text" + /> +
+ ); +} diff --git a/src/components/upload/TagsInput.tsx b/src/components/upload/TagsInput.tsx new file mode 100644 index 0000000..1b88fa2 --- /dev/null +++ b/src/components/upload/TagsInput.tsx @@ -0,0 +1,83 @@ +'use client'; + +import React, { useState } from 'react'; +import { Tag, WithContext } from 'react-tag-input'; +import ExclamationIcon from '@icons/exclamation.svg'; +import XIcon from '@icons/x.svg'; +import { Button } from '@/components/ui'; + +export function TagsInput() { + const [tags, setTags] = useState([]); + + return ( +
+
+ ТЕГИ + {tags.length}/50 + + Введите минимум 5 тегов через пробел + +
+
+ tag.id)} + /> + { + setTags((prev) => { + return [...prev, tag]; + }); + }} + handleDelete={(index: number, e) => { + setTags(tags.filter((_, i) => i !== index)); + }} + handleDrag={(tag: Tag, currPos: number, newPos: number) => { + const newTags = tags.slice(); + + newTags.splice(currPos, 1); + newTags.splice(newPos, 0, tag); + + setTags(newTags); + }} + inputFieldPosition="inline" + classNames={{ + tagInputField: 'outline-none text-light-violet', + tag: 'bg-violet px-2.5 py-1.25 flex gap-1.25 rounded-[10px] w-fit items-center', + selected: 'flex gap-2.5 flex-wrap items-center', + }} + removeComponent={RemoveTag} + /> +
+
+ ); +} + +class RemoveTag extends React.Component { + render(): React.ReactNode { + // @ts-expect-error ... + const { className, onRemove } = this.props; + return ( + + ); + } +} diff --git a/src/components/upload/UploadMenu.tsx b/src/components/upload/UploadMenu.tsx new file mode 100644 index 0000000..22ebafd --- /dev/null +++ b/src/components/upload/UploadMenu.tsx @@ -0,0 +1,11 @@ +'use client'; + +import { Button } from '@/components/ui'; + +export function UploadMenu() { + return ( +
+ +
+ ); +} diff --git a/src/components/upload/index.ts b/src/components/upload/index.ts new file mode 100644 index 0000000..022fe11 --- /dev/null +++ b/src/components/upload/index.ts @@ -0,0 +1,4 @@ +export * from './UploadMenu'; +export * from './Dropzone'; +export * from './TagsInput'; +export * from './SourceInput'; -- cgit v1.3-3-g829e