1
0
mirror of https://github.com/lencx/ChatGPT.git synced 2024-10-01 01:06:13 -04:00

chore: dashboard

This commit is contained in:
lencx 2022-12-13 19:10:42 +08:00
parent 430d6e4af2
commit 8363ff234d
18 changed files with 169 additions and 141 deletions

2
.gitattributes vendored
View File

@ -1,3 +1,3 @@
*.js linguist-vendored
*.tsx linguist-vendored
*.css linguist-vendored
*.scss linguist-vendored

View File

@ -1,5 +1,5 @@
<p align="center">
<img width="180" src="./logo.png" alt="ChatGPT">
<img width="180" src="./public/logo.png" alt="ChatGPT">
<h1 align="center">ChatGPT</h1>
</p>

View File

@ -30,18 +30,22 @@
"url": "https://github.com/lencx/ChatGPT"
},
"dependencies": {
"@tauri-apps/api": "^1.2.0",
"antd": "^5.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@tauri-apps/api": "^1.2.0"
"react-router-dom": "^6.4.5"
},
"devDependencies": {
"@tauri-apps/cli": "^1.2.2",
"@tauri-release/cli": "^0.2.3",
"@types/node": "^18.7.10",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^3.0.0",
"typescript": "^4.6.4",
"sass": "^1.56.2",
"typescript": "^4.9.4",
"vite": "^4.0.0",
"@tauri-apps/cli": "^1.2.2",
"@tauri-release/cli": "^0.2.3"
"vite-tsconfig-paths": "^4.0.2"
}
}

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -48,6 +48,10 @@ pub fn init(context: &Context<EmbeddedAssets>) -> Menu {
let preferences_menu = Submenu::new(
"Preferences",
Menu::with_items([
CustomMenuItem::new("dashboard".to_string(), "Dashboard")
.accelerator("CmdOrCtrl+D")
.into(),
MenuItem::Separator.into(),
Submenu::new(
"Theme",
Menu::new()
@ -165,6 +169,7 @@ pub fn menu_handler(event: WindowMenuEvent<tauri::Wry>) {
match menu_id {
// Preferences
"dashboard" => app.get_window("main").unwrap().show().unwrap(),
"restart" => tauri::api::process::restart(&app.env()),
"inject_script" => open(&app, script_path),
"go_conf" => utils::open_file(utils::chat_root()),

View File

@ -36,10 +36,15 @@ fn main() {
.on_window_event(|event| {
// https://github.com/tauri-apps/tauri/discussions/2684
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
// TODO: https://github.com/tauri-apps/tauri/issues/3084
// event.window().hide().unwrap();
// https://github.com/tauri-apps/tao/pull/517
event.window().minimize().unwrap();
let win = event.window();
if win.label() == "main" {
win.hide().unwrap();
} else {
// TODO: https://github.com/tauri-apps/tauri/issues/3084
// event.window().hide().unwrap();
// https://github.com/tauri-apps/tao/pull/517
event.window().minimize().unwrap();
}
api.prevent_close();
}
})

View File

@ -2,7 +2,7 @@
"build": {
"beforeDevCommand": "npm run dev:fe",
"beforeBuildCommand": "npm run build:fe",
"devPath": "http://localhost:1420/",
"devPath": "http://localhost:1420",
"distDir": "../dist"
},
"package": {
@ -68,6 +68,7 @@
{
"label": "main",
"url": "index.html",
"title": "ChatGPT",
"visible": false
}
]

View File

@ -1,7 +0,0 @@
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafb);
}

11
src/App.tsx vendored
View File

@ -1,11 +0,0 @@
import "./App.css";
function App() {
return (
<div className="container">
ChatGPT
</div>
);
}
export default App;

13
src/layout/index.scss vendored Normal file
View File

@ -0,0 +1,13 @@
.chat-logo {
text-align: center;
padding: 5px 0;
img {
width: 48px;
height: 48px;
}
}
.chat-container {
padding: 20px;
}

57
src/layout/index.tsx vendored Normal file
View File

@ -0,0 +1,57 @@
import { FC, useState } from 'react';
import {
DesktopOutlined,
BulbOutlined
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
import { Layout, Menu } from 'antd';
import './index.scss';
const { Content, Footer, Sider } = Layout;
type MenuItem = Required<MenuProps>['items'][number];
function getItem(
label: React.ReactNode,
key: React.Key,
icon?: React.ReactNode,
children?: MenuItem[],
): MenuItem {
return {
key,
icon,
children,
label,
} as MenuItem;
}
const items: MenuItem[] = [
getItem('General', 'general', <DesktopOutlined />),
getItem('ChatGPT Prompts', 'chatgpt-prompts', <BulbOutlined />),
];
interface ChatLayoutProps {
children: React.ReactNode;
}
const ChatLayout: FC<ChatLayoutProps> = ({ children }) => {
const [collapsed, setCollapsed] = useState(false);
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider theme="light" collapsible collapsed={collapsed} onCollapse={(value) => setCollapsed(value)}>
<div className="chat-logo"><img src="/logo.png" /></div>
<Menu defaultSelectedKeys={['1']} mode="inline" items={items} />
</Sider>
<Layout className="chat-layout">
<Content className="chat-container">
{children}
</Content>
<Footer style={{ textAlign: 'center' }}>
<a href="https://github.com/lencx/chatgpt" target="_blank">ChatGPT Desktop Application</a> ©2022 Created by lencx</Footer>
</Layout>
</Layout>
);
};
export default ChatLayout;

20
src/main.scss vendored Normal file
View File

@ -0,0 +1,20 @@
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #2a2a2a;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
html, body {
padding: 0;
margin: 0;
}

21
src/main.tsx vendored
View File

@ -1,11 +1,16 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { StrictMode, Suspense } from 'react';
import { BrowserRouter } from 'react-router-dom';
import ReactDOM from 'react-dom/client';
import App from "./App";
import "./style.css";
import Routes from './routes';
import './main.scss';
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<StrictMode>
<Suspense fallback={null}>
<BrowserRouter>
<Routes />
</BrowserRouter>
</Suspense>
</StrictMode>
);

22
src/routes.tsx vendored Normal file
View File

@ -0,0 +1,22 @@
import { useLayoutEffect } from 'react';
import { useLocation, useRoutes } from 'react-router-dom';
import type { RouteObject } from 'react-router-dom';
import App from '@view/App';
const routes: RouteObject[] = [
{
path: '/',
element: <App />
}
];
export default () => {
const location = useLocation();
const pathname = location.pathname;
useLayoutEffect(() => {
const name = pathname.substring(1).replace(/\//gi, '_');
document.body.className = `${name ? name : 'main'}_screen`
}, [pathname]);
return useRoutes(routes);
};

View File

@ -1,102 +0,0 @@
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
}

9
src/view/App.tsx vendored Normal file
View File

@ -0,0 +1,9 @@
import Layout from "@layout/index";
export default function Dashboard() {
return (
<Layout>
Hello
</Layout>
)
}

View File

@ -14,7 +14,13 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"@view/*": ["src/view/*"],
"@comps/*": ["src/components/*"],
"@layout/*": ["src/layout/*"],
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]

View File

@ -1,9 +1,10 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [tsconfigPaths(), react()],
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
// prevent vite from obscuring rust errors