mirror of
https://github.com/deiucanta/chatpad.git
synced 2026-03-11 09:04:31 +00:00
update homepage to show prompts
This commit is contained in:
parent
84375a0149
commit
6b592db087
4 changed files with 212 additions and 87 deletions
|
|
@ -23,7 +23,7 @@ export function App() {
|
|||
const [colorScheme, setColorScheme] = useLocalStorage<ColorScheme>({
|
||||
key: "mantine-color-scheme",
|
||||
defaultValue: prefersDark ? "dark" : "light",
|
||||
getInitialValueInEffect: true,
|
||||
getInitialValueInEffect: false,
|
||||
});
|
||||
|
||||
const toggleColorScheme = (value?: ColorScheme) =>
|
||||
|
|
|
|||
|
|
@ -80,8 +80,21 @@ export function Layout() {
|
|||
useEffect(() => {
|
||||
const dataFetch = async () => {
|
||||
const item = await detaDB.chats.get(chatId!);
|
||||
const fetchedChat = item as unknown as Chat
|
||||
|
||||
setChat(item as unknown as Chat);
|
||||
setChat(fetchedChat);
|
||||
|
||||
if (fetchedChat.private && !incognitoMode) {
|
||||
setIncognitoMode(true)
|
||||
if (colorScheme === 'light') {
|
||||
toggleColorScheme()
|
||||
}
|
||||
} else if (!(fetchedChat.private ?? false) && incognitoMode) {
|
||||
setIncognitoMode(false)
|
||||
if (colorScheme === 'dark') {
|
||||
toggleColorScheme()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (chatId) {
|
||||
|
|
|
|||
87
src/components/Welcome.tsx
Normal file
87
src/components/Welcome.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import { Container, Badge, SimpleGrid, ThemeIcon, Flex, Button, Text, useMantineTheme } from "@mantine/core";
|
||||
import {
|
||||
IconCurrencyDollar,
|
||||
IconKey,
|
||||
IconLock,
|
||||
IconNorthStar,
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
import { CreateChatButton } from "./CreateChatButton";
|
||||
import { Logo } from "./Logo";
|
||||
import { SettingsModal } from "./SettingsModal";
|
||||
import { useIncognitoMode, useSettings } from "../hooks/contexts";
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: IconCurrencyDollar,
|
||||
title: "Free and open source",
|
||||
description:
|
||||
"This app is provided for free and the source code is available on GitHub.",
|
||||
},
|
||||
{
|
||||
icon: IconLock,
|
||||
title: "Privacy focused",
|
||||
description:
|
||||
"No tracking, no cookies, no bullshit. All your data is stored locally.",
|
||||
},
|
||||
{
|
||||
icon: IconNorthStar,
|
||||
title: "Best experience",
|
||||
description:
|
||||
"Crafted with love and care to provide the best experience possible.",
|
||||
},
|
||||
];
|
||||
|
||||
export function Welcome () {
|
||||
const { settings } = useSettings()
|
||||
const theme = useMantineTheme()
|
||||
const { incognitoMode } = useIncognitoMode()
|
||||
|
||||
return (
|
||||
<Container size="sm">
|
||||
<Badge mb="lg">GPT-4 Ready</Badge>
|
||||
<Text>
|
||||
<Logo style={{ maxWidth: 240 }} color1={theme.colors[theme.primaryColor][3]} color2={theme.colors[theme.primaryColor][7]} />
|
||||
</Text>
|
||||
<Text mt={4} size="xl">
|
||||
Not just another ChatGPT user-interface!
|
||||
</Text>
|
||||
<SimpleGrid
|
||||
mt={50}
|
||||
cols={3}
|
||||
spacing={30}
|
||||
breakpoints={[{ maxWidth: "md", cols: 1 }]}
|
||||
>
|
||||
{features.map((feature) => (
|
||||
<div key={feature.title}>
|
||||
<ThemeIcon variant="outline" size={50} radius={50}>
|
||||
<feature.icon size={26} stroke={1.5} />
|
||||
</ThemeIcon>
|
||||
<Text mt="sm" mb={7}>
|
||||
{feature.title}
|
||||
</Text>
|
||||
<Text size="sm" color="dimmed" sx={{ lineHeight: 1.6 }}>
|
||||
{feature.description}
|
||||
</Text>
|
||||
</div>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
<Flex mt={50} align='center' gap='md'>
|
||||
{settings?.openAiApiKey && (
|
||||
<CreateChatButton size="md">
|
||||
{incognitoMode ? "Create a New Private Chat" : "Create a New Chat"}
|
||||
</CreateChatButton>
|
||||
)}
|
||||
<SettingsModal>
|
||||
<Button
|
||||
size="md"
|
||||
variant={settings?.openAiApiKey ? "light" : "filled"}
|
||||
leftIcon={<IconKey size={20} />}
|
||||
>
|
||||
{settings?.openAiApiKey ? "Change OpenAI Key" : "Enter OpenAI Key"}
|
||||
</Button>
|
||||
</SettingsModal>
|
||||
</Flex>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,100 +1,125 @@
|
|||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Center,
|
||||
Container,
|
||||
Flex,
|
||||
SimpleGrid,
|
||||
Text,
|
||||
ThemeIcon,
|
||||
useMantineTheme,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconCurrencyDollar,
|
||||
IconKey,
|
||||
IconLock,
|
||||
IconNorthStar,
|
||||
} from "@tabler/icons-react";
|
||||
import { Container, SimpleGrid, Flex, Button, Text, useMantineTheme, Center, Box, Tooltip, ActionIcon, Card } from "@mantine/core";
|
||||
import { useChats, useIncognitoMode, usePrompts, useSettings } from "../hooks/contexts";
|
||||
import { Welcome } from "../components/Welcome";
|
||||
import { Logo } from "../components/Logo";
|
||||
import { SettingsModal } from "../components/SettingsModal";
|
||||
import { useIncognitoMode, useSettings } from "../hooks/contexts";
|
||||
import { CreateChatButton } from "../components/CreateChatButton";
|
||||
import { SettingsModal } from "../components/SettingsModal";
|
||||
import { IconKey, IconPlayerPlay } from "@tabler/icons-react";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { Chat, detaDB, generateKey } from "../db";
|
||||
import { useNavigate } from "@tanstack/react-location";
|
||||
|
||||
|
||||
export function IndexRoute() {
|
||||
const { settings } = useSettings()
|
||||
const theme = useMantineTheme()
|
||||
const { incognitoMode } = useIncognitoMode()
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { setChats } = useChats()
|
||||
const { prompts } = usePrompts()
|
||||
|
||||
return (
|
||||
<>
|
||||
<Center py="xl" sx={{ height: "100%" }}>
|
||||
<Container size="sm">
|
||||
<Badge mb="lg">GPT-4 Ready</Badge>
|
||||
<Text>
|
||||
<Logo style={{ maxWidth: 240 }} color1={theme.colors[theme.primaryColor][3]} color2={theme.colors[theme.primaryColor][7]} />
|
||||
</Text>
|
||||
<Text mt={4} size="xl">
|
||||
Not just another ChatGPT user-interface!
|
||||
</Text>
|
||||
<SimpleGrid
|
||||
mt={50}
|
||||
cols={3}
|
||||
spacing={30}
|
||||
breakpoints={[{ maxWidth: "md", cols: 1 }]}
|
||||
>
|
||||
{features.map((feature) => (
|
||||
<div key={feature.title}>
|
||||
<ThemeIcon variant="outline" size={50} radius={50}>
|
||||
<feature.icon size={26} stroke={1.5} />
|
||||
</ThemeIcon>
|
||||
<Text mt="sm" mb={7}>
|
||||
{feature.title}
|
||||
</Text>
|
||||
<Text size="sm" color="dimmed" sx={{ lineHeight: 1.6 }}>
|
||||
{feature.description}
|
||||
</Text>
|
||||
</div>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
<Flex mt={50} align='center' gap='md'>
|
||||
{settings?.openAiApiKey && (
|
||||
<CreateChatButton size="md">
|
||||
{incognitoMode ? "Create a New Private Chat" : "Create a New Chat"}
|
||||
</CreateChatButton>
|
||||
)}
|
||||
<SettingsModal>
|
||||
<Button
|
||||
size="md"
|
||||
variant={settings?.openAiApiKey ? "light" : "filled"}
|
||||
leftIcon={<IconKey size={20} />}
|
||||
>
|
||||
{settings?.openAiApiKey ? "Change OpenAI Key" : "Enter OpenAI Key"}
|
||||
</Button>
|
||||
</SettingsModal>
|
||||
</Flex>
|
||||
</Container>
|
||||
{prompts && prompts.length > 0 ? (
|
||||
<Container size="md">
|
||||
<Text>
|
||||
<Logo style={{ maxWidth: 240 }} color1={theme.colors[theme.primaryColor][3]} color2={theme.colors[theme.primaryColor][7]} />
|
||||
</Text>
|
||||
<Text mt={4} size="xl">
|
||||
Not just another ChatGPT user-interface!
|
||||
</Text>
|
||||
<SimpleGrid
|
||||
mt={50}
|
||||
cols={3}
|
||||
spacing={10}
|
||||
breakpoints={[{ maxWidth: "lg", cols: 1 }]}
|
||||
>
|
||||
{prompts.map((prompt) => (
|
||||
<Card key={prompt.key} display="flex" padding="sm" radius="md" withBorder style={{ overflow: 'unset', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Box maw="180px">
|
||||
<Text
|
||||
weight={500}
|
||||
sx={{
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{prompt.title}
|
||||
</Text>
|
||||
<Text
|
||||
color="dimmed"
|
||||
sx={{
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{prompt.content || prompt.writingCharacter || prompt.writingTone || prompt.writingFormat || prompt.writingStyle || "No Instructions"}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Tooltip label="Start Chat From Prompt">
|
||||
<ActionIcon
|
||||
size="lg"
|
||||
onClick={async () => {
|
||||
if (!settings?.openAiApiKey) {
|
||||
notifications.show({
|
||||
title: "Error",
|
||||
color: "red",
|
||||
message: "OpenAI API Key is not defined. Please set your API Key",
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
const item = await detaDB.chats.put({
|
||||
description: prompt.title ? `New ${prompt.title} Chat` : "New Chat",
|
||||
prompt: prompt.key,
|
||||
writingInstructions: prompt.content,
|
||||
writingCharacter: prompt.writingCharacter,
|
||||
writingTone: prompt.writingTone,
|
||||
writingStyle: prompt.writingStyle,
|
||||
writingFormat: prompt.writingFormat,
|
||||
totalTokens: 0,
|
||||
createdAt: new Date().toISOString(),
|
||||
}, generateKey())
|
||||
|
||||
const chat = item as unknown as Chat
|
||||
setChats(current => ([...(current || []), chat]))
|
||||
|
||||
navigate({ to: `/chats/${chat.key}` });
|
||||
}}
|
||||
>
|
||||
<IconPlayerPlay size={20} />
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Card>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
|
||||
<Flex mt={50} align='center' gap='md'>
|
||||
{settings?.openAiApiKey && (
|
||||
<CreateChatButton size="md">
|
||||
{incognitoMode ? "Create a New Private Chat" : "Create a New Chat"}
|
||||
</CreateChatButton>
|
||||
)}
|
||||
<SettingsModal>
|
||||
<Button
|
||||
size="md"
|
||||
variant={settings?.openAiApiKey ? "light" : "filled"}
|
||||
leftIcon={<IconKey size={20} />}
|
||||
>
|
||||
{settings?.openAiApiKey ? "Change OpenAI Key" : "Enter OpenAI Key"}
|
||||
</Button>
|
||||
</SettingsModal>
|
||||
</Flex>
|
||||
</Container>
|
||||
) : (
|
||||
<Welcome />
|
||||
)}
|
||||
</Center>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: IconCurrencyDollar,
|
||||
title: "Free and open source",
|
||||
description:
|
||||
"This app is provided for free and the source code is available on GitHub.",
|
||||
},
|
||||
{
|
||||
icon: IconLock,
|
||||
title: "Privacy focused",
|
||||
description:
|
||||
"No tracking, no cookies, no bullshit. All your data is stored locally.",
|
||||
},
|
||||
{
|
||||
icon: IconNorthStar,
|
||||
title: "Best experience",
|
||||
description:
|
||||
"Crafted with love and care to provide the best experience possible.",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in a new issue