wip: Font and logo fixes in progress
- Reverted logo SVG to original viewBox - Applied forum.variable to body for CSS variable - Updated Save button to generate draft from conversation - Logo size and font variables still need fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -128,7 +128,7 @@ export default function ChatPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Handler for Manual/Save button
|
// Handler for Manual/Save button
|
||||||
const handleManualOrSave = () => {
|
const handleManualOrSave = async () => {
|
||||||
if (hasPendingDraft && pendingNodeDraft) {
|
if (hasPendingDraft && pendingNodeDraft) {
|
||||||
// If we have a draft, navigate to edit with it
|
// If we have a draft, navigate to edit with it
|
||||||
appActor.send({
|
appActor.send({
|
||||||
@@ -136,22 +136,53 @@ export default function ChatPage() {
|
|||||||
draft: pendingNodeDraft,
|
draft: pendingNodeDraft,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Create an empty draft for manual entry
|
// Generate a draft from the conversation
|
||||||
const emptyDraft = {
|
if (messages.length === 0) {
|
||||||
title: '',
|
notifications.show({
|
||||||
content: '',
|
title: 'No conversation',
|
||||||
conversationContext: messages.map((m) => {
|
message: 'Start a conversation before creating a node',
|
||||||
if ('parts' in m && Array.isArray((m as any).parts)) {
|
color: 'red',
|
||||||
return `${m.role}: ${(m as any).parts.find((p: any) => p.type === 'text')?.text || ''}`;
|
});
|
||||||
}
|
return;
|
||||||
return `${m.role}: ${(m as any).content || ''}`;
|
}
|
||||||
}).join('\n'),
|
|
||||||
};
|
|
||||||
|
|
||||||
appActor.send({
|
setIsCreatingNode(true);
|
||||||
type: 'CREATE_NODE_FROM_CONVERSATION',
|
|
||||||
draft: emptyDraft,
|
try {
|
||||||
});
|
const response = await fetch('/api/generate-node-draft', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
credentials: 'include',
|
||||||
|
body: JSON.stringify({ messages }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json();
|
||||||
|
throw new Error(errorData.error || 'Failed to generate node draft');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { draft } = await response.json();
|
||||||
|
|
||||||
|
appActor.send({
|
||||||
|
type: 'CREATE_NODE_FROM_CONVERSATION',
|
||||||
|
draft,
|
||||||
|
});
|
||||||
|
|
||||||
|
notifications.show({
|
||||||
|
title: 'Node draft created',
|
||||||
|
message: 'Review and edit your node before publishing',
|
||||||
|
color: 'green',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Create Node] Error:', error);
|
||||||
|
notifications.show({
|
||||||
|
title: 'Error',
|
||||||
|
message: error instanceof Error ? error.message : 'Failed to create node draft',
|
||||||
|
color: 'red',
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setIsCreatingNode(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -416,6 +447,8 @@ export default function ChatPage() {
|
|||||||
variant={hasPendingDraft ? 'filled' : 'light'}
|
variant={hasPendingDraft ? 'filled' : 'light'}
|
||||||
color={hasPendingDraft ? 'blue' : 'gray'}
|
color={hasPendingDraft ? 'blue' : 'gray'}
|
||||||
leftSection={<IconDeviceFloppy size={20} />}
|
leftSection={<IconDeviceFloppy size={20} />}
|
||||||
|
loading={isCreatingNode}
|
||||||
|
disabled={isCreatingNode}
|
||||||
>
|
>
|
||||||
{hasPendingDraft ? 'Save Draft' : 'Save'}
|
{hasPendingDraft ? 'Save Draft' : 'Save'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Inter } from "next/font/google";
|
import { Forum } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { MantineProvider, ColorSchemeScript } from "@mantine/core";
|
import { MantineProvider, ColorSchemeScript } from "@mantine/core";
|
||||||
import { Notifications } from "@mantine/notifications";
|
import { Notifications } from "@mantine/notifications";
|
||||||
@@ -7,7 +7,12 @@ import "@mantine/notifications/styles.css";
|
|||||||
import { theme } from "./theme";
|
import { theme } from "./theme";
|
||||||
import { AppLayout } from "@/components/AppLayout";
|
import { AppLayout } from "@/components/AppLayout";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
// Forum for headings/titles
|
||||||
|
const forum = Forum({
|
||||||
|
weight: '400',
|
||||||
|
subsets: ["latin"],
|
||||||
|
variable: '--font-forum',
|
||||||
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Ponderants",
|
title: "Ponderants",
|
||||||
@@ -28,8 +33,12 @@ export default function RootLayout({
|
|||||||
<head>
|
<head>
|
||||||
{/* Enforce dark scheme as per our theme */}
|
{/* Enforce dark scheme as per our theme */}
|
||||||
<ColorSchemeScript defaultColorScheme="dark" />
|
<ColorSchemeScript defaultColorScheme="dark" />
|
||||||
|
{/* Load Zalando Sans from Google Fonts */}
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Zalando+Sans:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
<body className={inter.className} suppressHydrationWarning>
|
<body className={forum.variable} suppressHydrationWarning>
|
||||||
<MantineProvider theme={theme} defaultColorScheme="dark">
|
<MantineProvider theme={theme} defaultColorScheme="dark">
|
||||||
<Notifications />
|
<Notifications />
|
||||||
<AppLayout>{children}</AppLayout>
|
<AppLayout>{children}</AppLayout>
|
||||||
|
|||||||
@@ -24,7 +24,12 @@ export const theme = createTheme({
|
|||||||
},
|
},
|
||||||
// Set default dark mode and grayscale for the "minimalist" look
|
// Set default dark mode and grayscale for the "minimalist" look
|
||||||
defaultRadius: 'md',
|
defaultRadius: 'md',
|
||||||
fontFamily: 'Inter, sans-serif',
|
// Body text font (Zalando Sans from Google Fonts via link tag)
|
||||||
|
fontFamily: '"Zalando Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
||||||
|
// Headings font (Forum from Google Fonts via next/font)
|
||||||
|
headings: {
|
||||||
|
fontFamily: 'var(--font-forum), serif',
|
||||||
|
},
|
||||||
|
|
||||||
// Set default component props for a consistent look
|
// Set default component props for a consistent look
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* Highlights the active mode based on app state machine.
|
* Highlights the active mode based on app state machine.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Stack, NavLink, Box, Text, Group, Image, Divider } from '@mantine/core';
|
import { Stack, NavLink, Box, Title, Group, Divider, Text } from '@mantine/core';
|
||||||
import { IconMessageCircle, IconEdit, IconChartBubbleFilled } from '@tabler/icons-react';
|
import { IconMessageCircle, IconEdit, IconChartBubbleFilled } from '@tabler/icons-react';
|
||||||
import { useSelector } from '@xstate/react';
|
import { useSelector } from '@xstate/react';
|
||||||
import { useAppMachine } from '@/hooks/useAppMachine';
|
import { useAppMachine } from '@/hooks/useAppMachine';
|
||||||
@@ -51,17 +51,17 @@ export function DesktopSidebar() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
<Group gap="sm" mb="lg" align="center" wrap="nowrap">
|
<Group gap="md" mb="lg" align="center" wrap="nowrap">
|
||||||
<Box w={32} h={32} style={{ flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<img
|
||||||
<Image
|
src="/logo.svg"
|
||||||
src="/logo.svg"
|
alt="Ponderants logo"
|
||||||
alt="Ponderants logo"
|
width={48}
|
||||||
style={{ width: '100%', height: '100%', transform: 'scale(1.5)' }}
|
height={48}
|
||||||
/>
|
style={{ flexShrink: 0, display: 'block' }}
|
||||||
</Box>
|
/>
|
||||||
<Text fw={700} size="xl" style={{ lineHeight: 1 }}>
|
<Title order={3} style={{ margin: 0 }}>
|
||||||
Ponderants
|
Ponderants
|
||||||
</Text>
|
</Title>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<NavLink
|
<NavLink
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Fixed header for mobile devices showing the Ponderants logo.
|
* Fixed header for mobile devices showing the Ponderants logo.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Group, Image, Text, Paper, Box } from '@mantine/core';
|
import { Group, Title, Paper } from '@mantine/core';
|
||||||
|
|
||||||
export function MobileHeader() {
|
export function MobileHeader() {
|
||||||
return (
|
return (
|
||||||
@@ -23,17 +23,17 @@ export function MobileHeader() {
|
|||||||
borderBottom: '1px solid #373A40',
|
borderBottom: '1px solid #373A40',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Group gap="sm" align="center">
|
<Group gap="md" align="center" wrap="nowrap">
|
||||||
<Box w={32} h={32} style={{ flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<img
|
||||||
<Image
|
src="/logo.svg"
|
||||||
src="/logo.svg"
|
alt="Ponderants logo"
|
||||||
alt="Ponderants logo"
|
width={48}
|
||||||
style={{ width: '100%', height: '100%', transform: 'scale(1.5)' }}
|
height={48}
|
||||||
/>
|
style={{ flexShrink: 0, display: 'block' }}
|
||||||
</Box>
|
/>
|
||||||
<Text fw={700} size="lg">
|
<Title order={3} style={{ margin: 0 }}>
|
||||||
Ponderants
|
Ponderants
|
||||||
</Text>
|
</Title>
|
||||||
</Group>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -83,14 +83,18 @@ async function applySchema() {
|
|||||||
if (result) {
|
if (result) {
|
||||||
console.log(`[Schema] Executed ${result.length} queries`);
|
console.log(`[Schema] Executed ${result.length} queries`);
|
||||||
|
|
||||||
// Log any errors
|
// Log any errors (if results have status property)
|
||||||
result.forEach((r, i) => {
|
if (Array.isArray(result)) {
|
||||||
if (r.status === 'ERR') {
|
result.forEach((r, i) => {
|
||||||
console.error(`[Schema] Error in query ${i + 1}:`, r.result);
|
if (r && typeof r === 'object') {
|
||||||
} else {
|
if (r.status === 'ERR') {
|
||||||
console.log(`[Schema] ✓ Query ${i + 1} succeeded`);
|
console.error(`[Schema] Error in query ${i + 1}:`, r.result);
|
||||||
}
|
} else if (r.status === 'OK') {
|
||||||
});
|
console.log(`[Schema] ✓ Query ${i + 1} succeeded`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[Schema] ✓ Schema applied successfully!');
|
console.log('[Schema] ✓ Schema applied successfully!');
|
||||||
|
|||||||
2
todo.md
2
todo.md
@@ -10,3 +10,5 @@ Upcoming items that should be implemented (time-permitting):
|
|||||||
maybe four simple shapes max)
|
maybe four simple shapes max)
|
||||||
- let's have, in the top-center, something that indicates we're in "Convo" mode
|
- let's have, in the top-center, something that indicates we're in "Convo" mode
|
||||||
- let's stream the AI output to deepgram for faster synthesis
|
- let's stream the AI output to deepgram for faster synthesis
|
||||||
|
- we should link bluesky posts back to ponderants
|
||||||
|
- long posts should be broken up into threads
|
||||||
|
|||||||
Reference in New Issue
Block a user