mirror of
https://github.com/jnsahaj/tweakcn.git
synced 2026-09-21 12:50:29 +08:00
* Enhanced Editor (#100) * refactor: editor page to improve responsiveness * feat: add editor tab persistance to url * chore: clean up classNames * feat: enhance theme color-preview to make it responsive * feat: add ai chat tab working with local state * successful responses return a theme color-preview * error responses return a generic message * fix: invalid tabs fallback to default tab "colors" * fix: remove messages scroll animation on tabs change and remove duplicate preview * fix: minor fixes in classNames * feat: Chat starts with a default message * refactor: Enhance editor controls and toolbar buttons to disable when generating theme - Updated button components to be extendible. - Refactored buttons to utilize TooltipWrapper for consistent tooltip behavior. * fix: sync controls tabs by 'value' instead of 'defaultValue' * fix: load messages from local storage, otherwise set a default initial message * fix: editor mention list positions correctly and add a tab handler for selecting mention * fix: build errors due to unused imports * chore: improve defaults and styles for ai chat interface and editor * refactor: move AIChat state management to a zustand store * feat: preserve control tab between edit mode and traditional editor mode * feat: reset ai chat on editor reset button click * feat: load chat messages dynamically to avoid layout shifts due to local storage * fix: Use const id for default ai message to avoid re-render * fix: Use searchParams for callback url as well after auth * refactor: Remove unused getEditorConfig code * feat: Only have 1 handler per postlogin action type This was causing issues in AI Chat form. AI_GENERATE_FROM_CHAT action was being scheduled twice because of re-render (caused by lazy-loaded component) * fix: Add user message for post login action * refactor: Only use JSONContent in application state (derive textContent from it) * feat: Auto-attach current theme to prompt after 1st user message * feat: clean up AI interface and add community themes section * feat: AI entrypoint redirect to main Editor and trigger theme generation * chore: improve styles on ai page * refactor: clean up AI components components from AI page and Editor page * refactor: share repeated theme generation logic * fix: chat messages inconsistent padding and pill buttons disabled state * fix: build error * feat: remove AI Generation Dialog and related logic * feat: show agent response about the theme * refactor: simplify theme generation logic and improve error handling * refactor: transition from JSONContent to AIPromptData for theme generation * feat: add retry functionality for user messages in AI chat interface * refactor: remove unused loading fallback component and integrate loading indicator in chat messages * change position of retry button * feat: Improve system prompt * refactor: replace createCurrentThemePrompt with attachCurrentThemeMention for improved prompt handling * feat: add a placeholder for new chat and fix chat area styles * chore: hide Community themes from AI page * fix: build errors * fix: ai theme generation only happens when there is content to be sent as the prompt * feat: show AI tab in production * fix: Early return after showing error message in ai chat * feat: Attach last generated message instead of current theme for chat * Use @ mentions in example prompts * Enhance mention rendering in AI prompts and update mention styles in CSS * skip posthog on dev * Enhanced Editor (#100) * refactor: editor page to improve responsiveness * feat: add editor tab persistance to url * chore: clean up classNames * feat: enhance theme color-preview to make it responsive * feat: add ai chat tab working with local state * successful responses return a theme color-preview * error responses return a generic message * fix: invalid tabs fallback to default tab "colors" * fix: remove messages scroll animation on tabs change and remove duplicate preview * fix: minor fixes in classNames * feat: Chat starts with a default message * refactor: Enhance editor controls and toolbar buttons to disable when generating theme - Updated button components to be extendible. - Refactored buttons to utilize TooltipWrapper for consistent tooltip behavior. * fix: sync controls tabs by 'value' instead of 'defaultValue' * fix: load messages from local storage, otherwise set a default initial message * fix: editor mention list positions correctly and add a tab handler for selecting mention * fix: build errors due to unused imports * chore: improve defaults and styles for ai chat interface and editor * refactor: move AIChat state management to a zustand store * feat: preserve control tab between edit mode and traditional editor mode * feat: reset ai chat on editor reset button click * feat: load chat messages dynamically to avoid layout shifts due to local storage * fix: Use const id for default ai message to avoid re-render * fix: Use searchParams for callback url as well after auth * refactor: Remove unused getEditorConfig code * feat: Only have 1 handler per postlogin action type This was causing issues in AI Chat form. AI_GENERATE_FROM_CHAT action was being scheduled twice because of re-render (caused by lazy-loaded component) * fix: Add user message for post login action * refactor: Only use JSONContent in application state (derive textContent from it) * feat: Auto-attach current theme to prompt after 1st user message * feat: clean up AI interface and add community themes section * feat: AI entrypoint redirect to main Editor and trigger theme generation * chore: improve styles on ai page * refactor: clean up AI components components from AI page and Editor page * refactor: share repeated theme generation logic * fix: chat messages inconsistent padding and pill buttons disabled state * fix: build error * feat: remove AI Generation Dialog and related logic * feat: show agent response about the theme * refactor: simplify theme generation logic and improve error handling * refactor: transition from JSONContent to AIPromptData for theme generation * feat: add retry functionality for user messages in AI chat interface * refactor: remove unused loading fallback component and integrate loading indicator in chat messages * change position of retry button * feat: Improve system prompt * refactor: replace createCurrentThemePrompt with attachCurrentThemeMention for improved prompt handling * feat: add a placeholder for new chat and fix chat area styles * chore: hide Community themes from AI page * fix: build errors * fix: ai theme generation only happens when there is content to be sent as the prompt * feat: show AI tab in production * fix: Early return after showing error message in ai chat * feat: Attach last generated message instead of current theme for chat * Use @ mentions in example prompts * Enhance mention rendering in AI prompts and update mention styles in CSS * fix: missing fade effect on chat messages scroll area and overflow in placeholder buttons * feat: add user name from session to the chat placeholder component * feat: Improve system prompt context * chore: remove unnecessary context from example prompts * feat: Enhance mention list with auto-scroll functionality and update prompt structures in no-messages placeholder * feat: Add character limit for AI prompt input and integrate character count extension * fix: Simplify prompt data handling in AI chat component and adjust textarea behavior during AI generation * fix: Update theme state handling to include current mode in editor store * chore: improve styles for consistency * feat: add fun prompts to chat placeholder * feat: add typography demo to preview panel * feat: add responsive cards demo based on shadcn showcase * fix: typography demo scroll area * fix: build errors due to components refactor * fix: wrap typography demo in ExamplesPreviewContainer * feat: change default theme to match shadcn/ui default * chore: move some theme previews into a dropdown to keep ui clean --------- Co-authored-by: Luis Llanes <137589205+llanesluis@users.noreply.github.com> Co-authored-by: Luis Llanes <luisllaboj@gmail.com>
128 lines
4.2 KiB
TypeScript
128 lines
4.2 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect, use } from "react";
|
|
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "@/components/ui/resizable";
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
import { Theme, ThemeStyles } from "@/types/theme";
|
|
import { Sliders } from "lucide-react";
|
|
import { useEditorStore } from "@/store/editor-store";
|
|
import { ActionBar } from "./action-bar/action-bar";
|
|
import ThemeControlPanel from "./theme-control-panel";
|
|
import ThemePreviewPanel from "./theme-preview-panel";
|
|
|
|
interface EditorProps {
|
|
themePromise: Promise<Theme | null>;
|
|
}
|
|
|
|
const isThemeStyles = (styles: unknown): styles is ThemeStyles => {
|
|
return (
|
|
!!styles &&
|
|
typeof styles === "object" &&
|
|
styles !== null &&
|
|
"light" in styles &&
|
|
"dark" in styles
|
|
);
|
|
};
|
|
|
|
const Editor: React.FC<EditorProps> = ({ themePromise }) => {
|
|
const themeState = useEditorStore((state) => state.themeState);
|
|
const setThemeState = useEditorStore((state) => state.setThemeState);
|
|
|
|
const initialTheme = themePromise ? use(themePromise) : null;
|
|
|
|
const handleStyleChange = React.useCallback(
|
|
(newStyles: ThemeStyles) => {
|
|
const prev = useEditorStore.getState().themeState;
|
|
setThemeState({ ...prev, styles: newStyles });
|
|
},
|
|
[setThemeState]
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (initialTheme && isThemeStyles(initialTheme.styles)) {
|
|
const prev = useEditorStore.getState().themeState;
|
|
setThemeState({
|
|
...prev,
|
|
styles: initialTheme.styles,
|
|
preset: initialTheme.id,
|
|
});
|
|
}
|
|
}, [initialTheme, setThemeState]);
|
|
|
|
if (initialTheme && !isThemeStyles(initialTheme.styles)) {
|
|
return (
|
|
<div className="text-destructive flex h-full items-center justify-center">
|
|
Fetched theme data is invalid.
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const styles = themeState.styles;
|
|
|
|
return (
|
|
<div className="relative isolate flex flex-1 overflow-hidden">
|
|
{/* Desktop Layout */}
|
|
<div className="hidden size-full md:block">
|
|
<ResizablePanelGroup direction="horizontal" className="isolate">
|
|
<ResizablePanel
|
|
defaultSize={30}
|
|
minSize={20}
|
|
maxSize={40}
|
|
className="z-1 min-w-[max(20%,22rem)]"
|
|
>
|
|
<div className="relative isolate flex h-full flex-1 flex-col">
|
|
<ThemeControlPanel
|
|
styles={styles}
|
|
onChange={handleStyleChange}
|
|
currentMode={themeState.currentMode}
|
|
themePromise={themePromise}
|
|
/>
|
|
</div>
|
|
</ResizablePanel>
|
|
<ResizableHandle />
|
|
<ResizablePanel defaultSize={70}>
|
|
<div className="flex h-full flex-col">
|
|
<div className="flex min-h-0 flex-1 flex-col">
|
|
<ActionBar />
|
|
<ThemePreviewPanel styles={styles} currentMode={themeState.currentMode} />
|
|
</div>
|
|
</div>
|
|
</ResizablePanel>
|
|
</ResizablePanelGroup>
|
|
</div>
|
|
{/* Mobile Layout */}
|
|
<div className="h-full w-full flex-1 overflow-hidden md:hidden">
|
|
<Tabs defaultValue="controls" className="h-full">
|
|
<TabsList className="w-full rounded-none">
|
|
<TabsTrigger value="controls" className="flex-1">
|
|
<Sliders className="mr-2 h-4 w-4" />
|
|
Controls
|
|
</TabsTrigger>
|
|
<TabsTrigger value="preview" className="flex-1">
|
|
Preview
|
|
</TabsTrigger>
|
|
</TabsList>
|
|
<TabsContent value="controls" className="mt-0 h-[calc(100%-2.5rem)]">
|
|
<div className="flex h-full flex-col">
|
|
<ThemeControlPanel
|
|
styles={styles}
|
|
onChange={handleStyleChange}
|
|
currentMode={themeState.currentMode}
|
|
themePromise={themePromise}
|
|
/>
|
|
</div>
|
|
</TabsContent>
|
|
<TabsContent value="preview" className="mt-0 h-[calc(100%-2.5rem)]">
|
|
<div className="flex h-full flex-col">
|
|
<ActionBar />
|
|
<ThemePreviewPanel styles={styles} currentMode={themeState.currentMode} />
|
|
</div>
|
|
</TabsContent>
|
|
</Tabs>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Editor;
|