diff --git a/config.yaml b/config.yaml index 60549ecb..8c5cf39c 100644 --- a/config.yaml +++ b/config.yaml @@ -19,6 +19,9 @@ user: # a session is created when user login to im.dev, this session will be expired after X seconds session_expire: 259200 +ui: + # base ui domain + domain: "http://localhost:4004" #################################### Paths ############################## # Path to where im.dev can store temp files, sessions, and the sqlite3 db (if that is used) diff --git a/configs/config.ts b/configs/config.ts index e6ef4e5b..ffdbeb14 100644 --- a/configs/config.ts +++ b/configs/config.ts @@ -2,6 +2,7 @@ import { requestApi } from "../src/utils/axios/request" export let config = { appName: "im.dev", + uiDomain: "http://localhost:4004", commonMaxlen: 255, posts: { titleMaxLen: 128, diff --git a/layouts/nav/nav.tsx b/layouts/nav/nav.tsx index 5e5bbca6..0440ef69 100644 --- a/layouts/nav/nav.tsx +++ b/layouts/nav/nav.tsx @@ -92,7 +92,7 @@ function HeaderContent() { variant="ghost" color="current" _focus={null} - display={{ base: "none", md: "block" }} + display={{ base: "none", md: "flex" }} icon={} /> diff --git a/pages/login.tsx b/pages/login.tsx index f4f922b4..4bef5aa7 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { useState } from "react" import { Text, Box, @@ -7,20 +7,34 @@ import { Image, useColorModeValue, Link, - Center + Center, + Flex, + IconButton, + HStack, + Modal, + ModalOverlay, + ModalContent, + ModalBody, + useDisclosure, + Input, + useToast } from "@chakra-ui/react" import Logo from "components/logo" -import { FaGithub } from "react-icons/fa" +import { FaEnvelope, FaGithub } from "react-icons/fa" import { requestApi } from "utils/axios/request" import { saveToken } from "utils/axios/getToken" import storage from "utils/localStorage" import { useRouter } from "next/router" +import { validateEmail } from "utils/user" const LoginPage = () => { + const { isOpen, onOpen, onClose } = useDisclosure() + const toast = useToast() const router = useRouter() - const login = async () => { - const res = await requestApi.post("/user/login") + const [email,setEmail] = useState('') + const login = async (email:string) => { + const res = await requestApi.post("/user/login",{email: email}) saveToken(res.data.token) storage.set('session', res.data) const oldPage = storage.get('current-page') @@ -32,10 +46,25 @@ const LoginPage = () => { } } + const onEmailLogin = async () => { + const err = await validateEmail(email,false) + if (err) { + toast({ + description: err, + status: "error", + duration: 2000, + isClosable: true, + }) + return + } + + login(email) + } + return ( - + 欢迎加入im.dev,一起打造全世界最好的开发者社区 @@ -53,11 +82,26 @@ const LoginPage = () => { - + + + OR + } onClick={onOpen}/> + 如果继续,则表示你同意im.dev的服务条款和隐私政策 {/* */} - + + + + + + Sign in using a secure link + setEmail(e.currentTarget.value)} placeholder="enter your email address" _focus={null}> + + + + + ) } diff --git a/pages/settings/org/members.tsx b/pages/settings/org/members.tsx deleted file mode 100644 index a14a3caf..00000000 --- a/pages/settings/org/members.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import { Text, Box, Heading, Image, Center, Button, Flex, VStack, Divider, useToast, FormControl, FormLabel, FormHelperText, Input, FormErrorMessage, HStack, Wrap, useMediaQuery, Avatar, Textarea, } from "@chakra-ui/react" -import Card from "components/card" -import Nav from "layouts/nav/nav" -import PageContainer from "layouts/page-container" -import Sidebar from "layouts/sidebar/sidebar" -import React, { useEffect, useState } from "react" -import { adminLinks, orgSettingLinks, settingLinks } from "src/data/links" -import { requestApi } from "utils/axios/request" -import { useRouter } from "next/router" -import { Field, Form, Formik } from "formik" -import { config } from "configs/config" -import Tags from "components/tags/tags" -var validator = require('validator'); - -const UserProfilePage = () => { - const [user, setUser] = useState(null) - const [skills, setSkills] = useState([]) - const [isLargerThan1280] = useMediaQuery("(min-width: 768px)") - useEffect(() => { - requestApi.get("/user/self").then(res => setUser(res.data)) - }, []) - const router = useRouter() - const toast = useToast() - - const submitUser = async (values, _) => { - await requestApi.post(`/user/update`, values) - setUser(values) - toast({ - description: "更新成功", - status: "success", - duration: 2000, - isClosable: true, - }) - } - - function validateNickname(value) { - let error - if (!value?.trim()) { - error = "昵称不能为空" - } - - if (value?.length > config.user.nicknameMaxLen) { - error = `长度不能超过${config.user.nicknameMaxLen}` - } - - return error - } - - function validateEmail(value) { - let email = value?.trim() - let error - - if (email?.length > config.user.usernameMaxLen) { - error = `长度不能超过${config.user.usernameMaxLen}` - return error - } - - if (email) { - if (!validator.isEmail(email)) { - error = "Email格式不合法" - return error - } - } - return error - } - - - function validateUrl(value, canBeEmpty = true) { - let url = value?.trim() - let error - if (!canBeEmpty) { - if (!url) { - error = "url不能为空" - return error - } - } - - if (url) { - if (!validator.isURL(value)) { - error = "URL格式不合法" - return error - } - } - - return error - } - - function validateLen(value) { - let error - if (value?.length > config.commonMaxlen) { - error = `长度不能超过${config.commonMaxlen}` - } - - return error - } - - const Layout = isLargerThan1280 ? HStack : VStack - return ( - <> - - - - {user && - - {(props) => ( -
- - - - - 基本信息 - - {({ field, form }) => ( - - 用户昵称 - - {form.errors.nickname} - - - )} - - - {({ field, form }) => ( - - 联系邮箱 - - {form.errors.email} - - - )} - - validateUrl(v, false)}> - {({ field, form }) => ( - - 头像设置 - - {form.errors.avatar} - {user.avatar && } - - - )} - - validateUrl(v, true)}> - {({ field, form }) => ( - - 封面图片 - - {form.errors.cover} - {user.cover && } - - - )} - - - - - About You - - {({ field, form }) => ( - - 一句话描述自己 - - {form.errors.tagline} - - )} - - - {({ field, form }) => ( - - Location - - {form.errors.location} - - )} - - - {({ field, form }) => ( - - Available for -