add logo
This commit is contained in:
parent
1f67fc8793
commit
9e7e3aac4a
16
public/favicon.svg
Normal file
16
public/favicon.svg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="32" height="32" rx="8" fill="#0EA5E9"/>
|
||||||
|
<!-- Neural network nodes -->
|
||||||
|
<circle cx="10" cy="16" r="2.5" fill="white" />
|
||||||
|
<circle cx="22" cy="12" r="2.5" fill="white" />
|
||||||
|
<circle cx="22" cy="20" r="2.5" fill="white" />
|
||||||
|
<circle cx="16" cy="10" r="2.5" fill="white" />
|
||||||
|
<circle cx="16" cy="22" r="2.5" fill="white" />
|
||||||
|
|
||||||
|
<!-- Connections -->
|
||||||
|
<line x1="12" y1="16" x2="20" y2="12" stroke="white" strokeWidth="1.5"/>
|
||||||
|
<line x1="12" y1="16" x2="20" y2="20" stroke="white" strokeWidth="1.5"/>
|
||||||
|
<line x1="12" y1="16" x2="14" y2="10" stroke="white" strokeWidth="1.5"/>
|
||||||
|
<line x1="12" y1="16" x2="14" y2="22" stroke="white" strokeWidth="1.5"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 804 B |
@ -1,16 +1,24 @@
|
|||||||
import type { Metadata, Viewport } from "next";
|
import './globals.css'
|
||||||
import "./globals.css";
|
import { ThemeProvider } from '@/components/theme/ThemeProvider'
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from '@/lib/utils'
|
||||||
import { Toaster } from "@/components/ui/toaster";
|
import { Inter } from 'next/font/google'
|
||||||
import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
|
||||||
|
|
||||||
|
const inter = Inter({ subsets: ['latin'] })
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata = {
|
||||||
title: "NeuraPress",
|
title: 'NeuraPress - AI Enhanced Article Editor',
|
||||||
description: "一个现代化的内容创作平台",
|
description: 'An intelligent article editor for creating and formatting content',
|
||||||
};
|
icons: {
|
||||||
|
icon: [
|
||||||
|
{
|
||||||
|
url: '/favicon.svg',
|
||||||
|
type: 'image/svg+xml',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
export const viewport: Viewport = {
|
export const viewport = {
|
||||||
width: "device-width",
|
width: "device-width",
|
||||||
initialScale: 1,
|
initialScale: 1,
|
||||||
maximumScale: 1,
|
maximumScale: 1,
|
||||||
@ -28,15 +36,11 @@ export default function RootLayout({
|
|||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="zh-CN" className="h-full" suppressHydrationWarning>
|
<html lang="zh-CN" suppressHydrationWarning>
|
||||||
<head>
|
<head />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
||||||
<meta name="format-detection" content="telephone=no" />
|
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
|
||||||
</head>
|
|
||||||
<body className={cn(
|
<body className={cn(
|
||||||
"h-full bg-background text-foreground antialiased"
|
'min-h-screen bg-background font-sans antialiased',
|
||||||
|
inter.className
|
||||||
)}>
|
)}>
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
attribute="class"
|
attribute="class"
|
||||||
@ -45,9 +49,8 @@ export default function RootLayout({
|
|||||||
disableTransitionOnChange
|
disableTransitionOnChange
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
<Toaster />
|
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
)
|
||||||
}
|
}
|
@ -1,70 +1,8 @@
|
|||||||
import WechatEditor from '@/components/editor/WechatEditor'
|
import WechatEditor from '@/components/editor/WechatEditor'
|
||||||
import { Menu } from 'lucide-react'
|
|
||||||
import { Button } from '@/components/ui/button'
|
|
||||||
import {
|
|
||||||
Sheet,
|
|
||||||
SheetContent,
|
|
||||||
SheetTrigger,
|
|
||||||
} from "@/components/ui/sheet"
|
|
||||||
import { ThemeToggle } from '@/components/theme/ThemeToggle'
|
|
||||||
|
|
||||||
export default function WechatPage() {
|
export default function WechatPage() {
|
||||||
return (
|
return (
|
||||||
<main className="h-full bg-background flex flex-col">
|
<main className="h-full bg-background flex flex-col">
|
||||||
<header className="flex-none sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
||||||
<div className="container flex h-14 max-w-screen-2xl items-center px-4">
|
|
||||||
<div className="flex items-center flex-1 gap-2">
|
|
||||||
<div className="md:hidden">
|
|
||||||
<Sheet>
|
|
||||||
<SheetTrigger asChild>
|
|
||||||
<Button variant="ghost" size="icon" className="mr-2">
|
|
||||||
<Menu className="h-5 w-5" />
|
|
||||||
<span className="sr-only">Toggle menu</span>
|
|
||||||
</Button>
|
|
||||||
</SheetTrigger>
|
|
||||||
<SheetContent side="left" className="w-[240px] sm:w-[280px] p-0">
|
|
||||||
<nav className="flex flex-col">
|
|
||||||
<a
|
|
||||||
href="/wechat"
|
|
||||||
className="flex h-12 items-center border-b px-4 text-sm font-medium text-foreground"
|
|
||||||
>
|
|
||||||
微信编辑器
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="/xiaohongshu"
|
|
||||||
className="flex h-12 items-center border-b px-4 text-sm font-medium text-foreground/60 hover:text-foreground/80"
|
|
||||||
>
|
|
||||||
小红书编辑器
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
</SheetContent>
|
|
||||||
</Sheet>
|
|
||||||
</div>
|
|
||||||
<a className="flex items-center space-x-2" href="/">
|
|
||||||
<span className="font-bold inline-block">
|
|
||||||
NeuraPress
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<nav className="flex items-center space-x-6">
|
|
||||||
<div className="hidden md:flex items-center space-x-6 text-sm font-medium">
|
|
||||||
<a
|
|
||||||
href="/wechat"
|
|
||||||
className="transition-colors hover:text-foreground/80 text-foreground"
|
|
||||||
>
|
|
||||||
微信编辑器
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="/xiaohongshu"
|
|
||||||
className="text-foreground/60 transition-colors hover:text-foreground/80"
|
|
||||||
>
|
|
||||||
小红书编辑器
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<ThemeToggle />
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div className="flex-1 relative">
|
<div className="flex-1 relative">
|
||||||
<WechatEditor />
|
<WechatEditor />
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,9 @@ import { StyleConfigDialog } from '../StyleConfigDialog'
|
|||||||
import { ArticleList } from '../ArticleList'
|
import { ArticleList } from '../ArticleList'
|
||||||
import { type Article } from '../constants'
|
import { type Article } from '../constants'
|
||||||
import { type RendererOptions } from '@/lib/markdown'
|
import { type RendererOptions } from '@/lib/markdown'
|
||||||
|
import { ThemeToggle } from '@/components/theme/ThemeToggle'
|
||||||
|
import { Logo } from '@/components/icons/Logo'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
interface EditorToolbarProps {
|
interface EditorToolbarProps {
|
||||||
value: string
|
value: string
|
||||||
@ -42,10 +45,14 @@ export function EditorToolbar({
|
|||||||
}: EditorToolbarProps) {
|
}: EditorToolbarProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex-none border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 sticky top-0 z-20">
|
<div className="flex-none border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 sticky top-0 z-20">
|
||||||
<div className="container mx-auto">
|
<div className="px-4">
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
<div className="flex items-center justify-between gap-4">
|
||||||
<div className="flex flex-wrap items-center gap-4 w-full sm:w-auto">
|
<div className="flex items-center gap-4">
|
||||||
|
<Link href="/" className="text-xl font-bold text-primary hidden sm:flex items-center gap-2">
|
||||||
|
<Logo className="w-6 h-6" />
|
||||||
|
NeuraPress
|
||||||
|
</Link>
|
||||||
<ArticleList
|
<ArticleList
|
||||||
onSelect={onArticleSelect}
|
onSelect={onArticleSelect}
|
||||||
currentContent={value}
|
currentContent={value}
|
||||||
@ -53,7 +60,7 @@ export function EditorToolbar({
|
|||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
onClick={onNewArticle}
|
onClick={onNewArticle}
|
||||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm transition-colors w-full sm:w-auto justify-center bg-muted text-muted-foreground hover:bg-muted/90"
|
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm transition-colors justify-center bg-muted text-muted-foreground hover:bg-muted/90"
|
||||||
>
|
>
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
新建文章
|
新建文章
|
||||||
@ -62,18 +69,15 @@ export function EditorToolbar({
|
|||||||
value={selectedTemplate}
|
value={selectedTemplate}
|
||||||
onSelect={onTemplateSelect}
|
onSelect={onTemplateSelect}
|
||||||
/>
|
/>
|
||||||
<div className="hidden sm:block h-6 w-px bg-border" />
|
|
||||||
<TemplateManager onTemplateChange={onTemplateChange} />
|
<TemplateManager onTemplateChange={onTemplateChange} />
|
||||||
<div className="hidden sm:block h-6 w-px bg-border" />
|
|
||||||
<StyleConfigDialog
|
<StyleConfigDialog
|
||||||
value={styleOptions}
|
value={styleOptions}
|
||||||
onChangeAction={onStyleOptionsChange}
|
onChangeAction={onStyleOptionsChange}
|
||||||
/>
|
/>
|
||||||
<div className="hidden sm:block h-6 w-px bg-border" />
|
|
||||||
<button
|
<button
|
||||||
onClick={onPreviewToggle}
|
onClick={onPreviewToggle}
|
||||||
className={cn(
|
className={cn(
|
||||||
"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm transition-colors w-full sm:w-auto justify-center",
|
"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm transition-colors justify-center",
|
||||||
showPreview
|
showPreview
|
||||||
? "bg-primary text-primary-foreground hover:bg-primary/90"
|
? "bg-primary text-primary-foreground hover:bg-primary/90"
|
||||||
: "bg-muted text-muted-foreground hover:bg-muted/90"
|
: "bg-muted text-muted-foreground hover:bg-muted/90"
|
||||||
@ -83,14 +87,14 @@ export function EditorToolbar({
|
|||||||
{showPreview ? '编辑' : '预览'}
|
{showPreview ? '编辑' : '预览'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 w-full sm:w-auto">
|
<div className="flex items-center gap-4">
|
||||||
{isDraft && (
|
{isDraft && (
|
||||||
<span className="text-sm text-muted-foreground">未保存</span>
|
<span className="text-sm text-muted-foreground">未保存</span>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={onSave}
|
onClick={onSave}
|
||||||
className={cn(
|
className={cn(
|
||||||
"inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md text-sm transition-colors flex-1 sm:flex-none",
|
"inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md text-sm transition-colors",
|
||||||
isDraft
|
isDraft
|
||||||
? "bg-primary text-primary-foreground hover:bg-primary/90"
|
? "bg-primary text-primary-foreground hover:bg-primary/90"
|
||||||
: "bg-muted text-muted-foreground hover:bg-muted/90"
|
: "bg-muted text-muted-foreground hover:bg-muted/90"
|
||||||
@ -101,18 +105,19 @@ export function EditorToolbar({
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={onCopy}
|
onClick={onCopy}
|
||||||
className="inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md bg-muted text-muted-foreground hover:bg-muted/90 text-sm transition-colors flex-1 sm:flex-none"
|
className="inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md bg-muted text-muted-foreground hover:bg-muted/90 text-sm transition-colors"
|
||||||
>
|
>
|
||||||
<Copy className="h-4 w-4" />
|
<Copy className="h-4 w-4" />
|
||||||
<span>复制源码</span>
|
<span>复制源码</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={onCopyPreview}
|
onClick={onCopyPreview}
|
||||||
className="inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md bg-primary text-primary-foreground hover:bg-primary/90 text-sm transition-colors flex-1 sm:flex-none"
|
className="inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-md bg-primary text-primary-foreground hover:bg-primary/90 text-sm transition-colors"
|
||||||
>
|
>
|
||||||
<Copy className="h-4 w-4" />
|
<Copy className="h-4 w-4" />
|
||||||
<span>复制预览</span>
|
<span>复制预览</span>
|
||||||
</button>
|
</button>
|
||||||
|
<ThemeToggle />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
37
src/components/icons/Logo.tsx
Normal file
37
src/components/icons/Logo.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { SVGProps } from 'react'
|
||||||
|
|
||||||
|
export function Logo({ className, ...props }: SVGProps<SVGSVGElement>) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className={className}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{/* Neural network nodes */}
|
||||||
|
<circle cx="6" cy="12" r="2" fill="currentColor" />
|
||||||
|
<circle cx="18" cy="8" r="2" fill="currentColor" />
|
||||||
|
<circle cx="18" cy="16" r="2" fill="currentColor" />
|
||||||
|
<circle cx="12" cy="6" r="2" fill="currentColor" />
|
||||||
|
<circle cx="12" cy="18" r="2" fill="currentColor" />
|
||||||
|
|
||||||
|
{/* Connections */}
|
||||||
|
<line x1="8" y1="12" x2="16" y2="8" />
|
||||||
|
<line x1="8" y1="12" x2="16" y2="16" />
|
||||||
|
<line x1="8" y1="12" x2="10" y2="6" />
|
||||||
|
<line x1="8" y1="12" x2="10" y2="18" />
|
||||||
|
|
||||||
|
{/* Pen tip overlay */}
|
||||||
|
<path
|
||||||
|
d="M16 6l2 2-8 8-2-2z"
|
||||||
|
fill="currentColor"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user