diff --git a/.env b/.env new file mode 100644 index 0000000..22fc2ee --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +# appwrite的项目ID +VUE_APPWRITE_PROJECT_ID= diff --git a/package.json b/package.json index 9d60913..c0c3844 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "@types/lodash": "^4.17.13", "@types/react-router-dom": "^5.3.3", "axios": "^1.7.7", + "appwrite": "^16.0.2", "framer-motion": "^11.11.17", + "jotai": "^2.10.3", "lodash": "^4.17.21", "normalize.css": "^8.0.1", "react": "^18.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index caa1aa9..3bda8e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,9 +29,15 @@ importers: axios: specifier: ^1.7.7 version: 1.7.7 + appwrite: + specifier: ^16.0.2 + version: 16.0.2 framer-motion: specifier: ^11.11.17 version: 11.11.17(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + jotai: + specifier: ^2.10.3 + version: 2.10.3(@types/react@18.3.12)(react@18.3.1) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -661,6 +667,9 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + appwrite@16.0.2: + resolution: {integrity: sha512-sCMVOe9wdB8OneIz6LtoYhp797GEXoudAdygNZgezPiybGOlMPcQ8kP1c/FW1eES0ledaqgaZ0PHb+LwZia8pw==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1015,6 +1024,18 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jotai@2.10.3: + resolution: {integrity: sha512-Nnf4IwrLhNfuz2JOQLI0V/AgwcpxvVy8Ec8PidIIDeRi4KCFpwTFIpHAAcU+yCgnw/oASYElq9UY0YdUUegsSA==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=17.0.0' + react: '>=17.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2012,6 +2033,8 @@ snapshots: dependencies: color-convert: 2.0.1 + appwrite@16.0.2: {} + argparse@2.0.1: {} asynckit@0.4.0: {} @@ -2411,6 +2434,11 @@ snapshots: isexe@2.0.0: {} + jotai@2.10.3(@types/react@18.3.12)(react@18.3.1): + optionalDependencies: + '@types/react': 18.3.12 + react: 18.3.1 + js-tokens@4.0.0: {} js-yaml@4.1.0: diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..36b0b7d --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,16 @@ +import { Toast } from "@/utils/toast" +import { Account, Client, ID } from "appwrite" + +const client = new Client() + +client.setProject(import.meta.env.VUE_APPWRITE_PROJECT_ID) + +export async function register(opts: { email: string; password: string }, errText: string) { + const account = new Account(client) + try { + await account.create(ID.unique(), opts.email, opts.password) + } catch (error: any) { + Toast.error(error?.message ?? errText) + return Promise.reject(error) + } +} diff --git a/src/base/withPage.tsx b/src/base/withPage.tsx index a97f6c0..5e9f76d 100644 --- a/src/base/withPage.tsx +++ b/src/base/withPage.tsx @@ -1,5 +1,5 @@ import { FC, ReactNode } from "react" -import { LeftIn, OpacityIn } from "@/effect" +import { OpacityIn } from "@/effect" import styled from "styled-components" interface PageProps { diff --git a/src/effect/index.tsx b/src/effect/index.tsx index 3974e40..59c85af 100644 --- a/src/effect/index.tsx +++ b/src/effect/index.tsx @@ -1,5 +1,5 @@ import { motion } from "framer-motion" -import styled from "styled-components" + export function OpacityIn({ children, className }: any) { return ( diff --git a/src/layout/GlobalStyles.ts b/src/layout/GlobalStyles.ts index 56c2963..6e1d0f9 100644 --- a/src/layout/GlobalStyles.ts +++ b/src/layout/GlobalStyles.ts @@ -1,5 +1,5 @@ import { createGlobalStyle } from "styled-components" export const GlobalStyles = createGlobalStyle` - + ` diff --git a/src/layout/base.tsx b/src/layout/base.tsx index 0a9b4c3..d9e0e88 100644 --- a/src/layout/base.tsx +++ b/src/layout/base.tsx @@ -3,6 +3,9 @@ import { ReactNode, useState } from "react" import { NavLink, useHistory } from "react-router-dom" import styled from "styled-components" import { GlobalStyles } from "./GlobalStyles" +import { Notice } from "@/ui/Notice" +import { Markdown } from "@/ui/Markdown" +import { Register } from "@/ui/Register/Register" interface PageProps { children: ReactNode @@ -24,18 +27,29 @@ const ContentWrapper = styled.div` function BaseLayout(props: PageProps) { const [isOpen, setIsOpen] = useState(false) const [isOpenAbout, setIsOpenAbout] = useState(false) + const [isOpenRegister, setIsOpenRegister] = useState(false) const router = useHistory() + const about = ` +> 人生如逆水行舟,不进则退。 + + 我来自一南方小镇,不善言辞,今作此小站,聊慰平生。 + + 如有意愿,欢迎联系。 + +[Github](https://github.com/npmrun) + ` + return ( - 东风天堂 + 天涯行宫 - + + + + ) +} diff --git a/src/utils/toast.ts b/src/utils/toast.ts new file mode 100644 index 0000000..914bf28 --- /dev/null +++ b/src/utils/toast.ts @@ -0,0 +1,21 @@ +import { OverlayToaster, Position, Toaster } from "@blueprintjs/core" + +interface Toaster2 { + error: Function + success: Function + loading: Function + loadingDismiss: Function +} + +export const Toast: Toaster & Toaster2 = OverlayToaster.create({ position: Position.TOP_RIGHT }) as any +export const TToast: Toaster & Toaster2 = OverlayToaster.create({ position: Position.TOP }) as any + +Toast.loadingDismiss = (key: string) => { + TToast.dismiss(key) +} +Toast.error = (message: string) => Toast.show({ message: message, icon: "error", intent: "danger", timeout: 3000 }) +Toast.success = (message: string) => Toast.show({ message: message, intent: "success", timeout: 3000 }) +Toast.loading = (message: string) => { + const key = TToast.show({ message: message, intent: "primary", timeout: 0 }) + return key +} diff --git a/src/views/Child.tsx b/src/views/Child.tsx index 2d724d4..12144fa 100644 --- a/src/views/Child.tsx +++ b/src/views/Child.tsx @@ -1,5 +1,4 @@ -import { Button, Dialog, DialogBody, DialogFooter } from "@blueprintjs/core"; -import { useCallback, useState } from "react"; +import { Button } from "@blueprintjs/core"; function Child() { return <> diff --git a/src/views/Home/index.tsx b/src/views/Home/index.tsx index 61c01d3..7c0e9aa 100644 --- a/src/views/Home/index.tsx +++ b/src/views/Home/index.tsx @@ -1,37 +1,19 @@ import withPage from "@/base/withPage" -import { useHistory } from "react-router-dom" -import styled from "styled-components" -import ReactMarkdown from "react-markdown" -import MdText from "./index.md?raw" +import { Hero } from "@/ui/Hero" +import { ReactNode } from "react" -const Title = styled.h1` - font-size: 1.5em; - text-align: center; - color: #bf4f74; -` +interface IProps { + children: ReactNode +} -const Wrapper = styled.section` - padding: 4em; - background: papayawhip; -` - -export default withPage(function Project({ children }) { - const router = useHistory() - function toChild() { - router.push("/project/child") - } +export default withPage(function Project({}: IProps) { return ( -
- - HOME - - {MdText} -
-
- vaas -
- {children} + <> + + +
+
-
+ ) }) diff --git a/vite.config.ts b/vite.config.ts index c2f38d9..a9b62b2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,6 +4,7 @@ import react from "@vitejs/plugin-react-swc" // https://vite.dev/config/ export default defineConfig({ + base: "./", resolve: { alias: { "@": join(__dirname, "src"),