This commit is contained in:
tianyaxiang 2025-02-01 14:53:28 +08:00
parent 1f67fc8793
commit 9e7e3aac4a
5 changed files with 94 additions and 95 deletions

16
public/favicon.svg Normal file
View 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

View File

@ -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>
); )
} }

View File

@ -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>

View File

@ -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>

View 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>
)
}