update homepage to show prompts

This commit is contained in:
BetaHuhn 2023-09-04 19:01:40 +02:00
parent 84375a0149
commit 6b592db087
4 changed files with 212 additions and 87 deletions

View file

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

View file

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

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

View file

@ -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.",
},
];