diff --git a/README.md b/README.md index 90b9b50..9df0b5f 100644 --- a/README.md +++ b/README.md @@ -25,31 +25,30 @@ This is the portal website of [Callgent](https://callgent.com), gratefully forke 1. "node": ">=18.17.0" 2. checkout the repository: - ```bash - - ``` - + ```bash + + ``` + 3. rename `.env.example` to `.env` 4. Start the Service - - Development Environment + - Development Environment - ```bash - # Modify the API_SITE_URL on line 7 of your package.json file to set your development server. - npm i -g pnpm - pnpm install - pnpm run start - ``` + ```bash + # Modify the API_SITE_URL on line 7 of your package.json file to set your development server. + npm i -g pnpm + pnpm install + pnpm run start + ``` - - Production Environment + - Production Environment - ```bash - # Modify the API_SITE_URL in your .env file to set your production environment server. - pnpm install - pnpm run build - pnpm run serve - ``` - + ```bash + # Modify the API_SITE_URL in your .env file to set your production environment server. + pnpm install + pnpm run build + pnpm run serve + ``` ## Contributing diff --git a/docs/advanced-topics/_category_.json b/docs/advanced-topics/_category_.json index 5110fa4..9984c54 100644 --- a/docs/advanced-topics/_category_.json +++ b/docs/advanced-topics/_category_.json @@ -1,6 +1,6 @@ { "label": "Advanced Topics", - "position": 3, + "position": 4, "link": { "type": "generated-index" } diff --git a/docs/developers/_category_.json b/docs/developers/_category_.json index 15e31ca..3668aba 100644 --- a/docs/developers/_category_.json +++ b/docs/developers/_category_.json @@ -1,6 +1,6 @@ { "label": "Developers Guide", - "position": 4, + "position": 5, "link": { "type": "generated-index", "description": "Service as a Callable Agent. Encapsulate every user and system service the same way as a Callgent, seamlessly integrate them anywhere." diff --git a/docs/quick-start/call-the-callgent.mdx b/docs/quick-start/call-the-callgent.mdx index 73fc8be..a487c98 100644 --- a/docs/quick-start/call-the-callgent.mdx +++ b/docs/quick-start/call-the-callgent.mdx @@ -7,7 +7,7 @@ tags: [Demo, Getting started] # Call the Callgent import App from "@site/docs/app" -import CreateCallgent from "./components/CreateCallgent" +import CreateCallgent from "./components/create-callgent" import Email from "./components/email" import RestApi from "./components/restApi" diff --git a/docs/quick-start/components/CreateCallgent.tsx b/docs/quick-start/components/create-callgent.tsx similarity index 96% rename from docs/quick-start/components/CreateCallgent.tsx rename to docs/quick-start/components/create-callgent.tsx index cecee35..1d01c61 100644 --- a/docs/quick-start/components/CreateCallgent.tsx +++ b/docs/quick-start/components/create-callgent.tsx @@ -53,7 +53,7 @@ const CreateCallgent = () => {

Please  - Sign In + Sign up  first.

diff --git a/docs/quick-start/components/email.tsx b/docs/quick-start/components/email.tsx index 65bb6c7..be956d7 100644 --- a/docs/quick-start/components/email.tsx +++ b/docs/quick-start/components/email.tsx @@ -4,7 +4,7 @@ import { DocType } from '@site/src/types/user'; import React, { useEffect, useRef, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; const Email = () => { - // 打包之后必须使用@docusaurus/useIsBrowser来限制浏览器渲染 + const isBrowser = useIsBrowser(); if (!isBrowser) { return null; @@ -17,12 +17,11 @@ const Email = () => { useEffect(() => { // dispatch(setCallgent()); }, []) - // 邮件操作 + // Mail Operations const pushRouter = () => { if (callgent?.uuid) { window.location.href = `mailto:callgent+${callgent.uuid}@c.callgent.com`; } else { - // 元素在mdx中,无法使用ref const element = document.querySelector('#create-the-callgent'); if (element instanceof HTMLElement) { window.scrollTo({ diff --git a/docs/quick-start/components/index.module.css b/docs/quick-start/components/index.module.css index 73e3eab..90163a6 100644 --- a/docs/quick-start/components/index.module.css +++ b/docs/quick-start/components/index.module.css @@ -1,11 +1,17 @@ /* CreateCallgent */ -.form{ +.form { display: flex; flex-wrap: wrap; } + @keyframes fadeInBackground { - from {opacity: 0;} - to {opacity: 1;} + from { + opacity: 0; + } + + to { + opacity: 1; + } } .modal { @@ -16,32 +22,44 @@ top: 0; width: 100%; height: 100%; - background-color: rgb(0,0,0); - background-color: rgba(0,0,0,0.4); - /* 添加动画 */ + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.4); animation: fadeInBackground 0.2s forwards; } + @keyframes fadeIn { - from {opacity: 0;} - to {opacity: 1;} + from { + opacity: 0; + } + + to { + opacity: 1; + } } + @keyframes shake { - 0%, 100% { + + 0%, + 100% { transform: translateX(0); } + 25% { transform: translateX(-5px); } + 75% { transform: translateX(5px); } } -.please{ + +.please { color: red; line-height: 50px; margin-left: 20px; animation: shake 0.3s ease-in-out 2; } + .modalContent { width: 270px; height: 80px; @@ -49,29 +67,40 @@ border-radius: 10px; background-color: #fefefe; color: black; - margin: 200px auto; /* 位于页面中心 */ + margin: 200px auto; border: 1px solid #888; text-align: center; user-select: none; - /* 添加动画 */ animation: fadeIn 0.2s forwards; } + +.resForm { + display: flex; + flex-direction: column; + justify-content: space-around; + padding: 10px; +} + /* RestApi */ -.copy{ +.copy { color: green; } -.pre{ + +.pre { position: relative; } -.copyButton{ + +.copyButton { position: absolute; right: 15px; cursor: pointer; } + /* email */ -.emailSvg{ +.emailSvg { margin-bottom: -5px; } + .emailPush { color: #428555; cursor: pointer; diff --git a/docs/quick-start/components/register.tsx b/docs/quick-start/components/register.tsx new file mode 100644 index 0000000..7c49ed6 --- /dev/null +++ b/docs/quick-start/components/register.tsx @@ -0,0 +1,47 @@ +import useIsBrowser from '@docusaurus/useIsBrowser'; +import styles from './index.module.css'; +import { DocType } from '@site/src/types/user'; +import React, { useRef, useState } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; + +const CreateCallgent = () => { + const isBrowser = useIsBrowser(); + if (!isBrowser) { + return null; + } + const { sendConfirmEmail } = require('@site/src/store/thunk'); + const [state, setState] = useState(null); + const dispatch = useDispatch(); + const onEmailSubmit = (event: React.FormEvent) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const email = formData.get('email') as string; + dispatch(sendConfirmEmail({ email })) + .then((req) => { + if (req.payload !== "Failed to send confirmation email") { + setState('success'); + } else { + setState('error'); + } + }); + }; + return ( + <> +
onEmailSubmit(e)} className={styles.form}> + + +
+ {state === 'success' &&
Please check your email to confirm registration!
} + {state === 'error' &&
Failed to send confirmation email. Please try again later.
} + + ); +}; +export default CreateCallgent; \ No newline at end of file diff --git a/docs/quick-start/create-a-new-callgent.mdx b/docs/quick-start/create-a-new-callgent.mdx index 04923cd..ed49ff8 100644 --- a/docs/quick-start/create-a-new-callgent.mdx +++ b/docs/quick-start/create-a-new-callgent.mdx @@ -7,7 +7,7 @@ tags: [Demo, Getting started] # Create a New Callgent import App from "@site/docs/app" -import CreateCallgent from "./components/CreateCallgent" +import CreateCallgent from "./components/create-callgent" Now you can create your own callgents, to encapsulate any of your system serivces, and embed them into any scenarios. diff --git a/docs/quick-start/register-an-account.mdx b/docs/quick-start/register-an-account.mdx index 268dd07..c085a2b 100644 --- a/docs/quick-start/register-an-account.mdx +++ b/docs/quick-start/register-an-account.mdx @@ -4,15 +4,10 @@ sidebar_position: 1 # Register an Account -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import IconExternalLink from '@theme/Icon/ExternalLink'; -export const SignupLink = () => { - const { siteConfig } = useDocusaurusContext(); - return ( - sign-up page - ); -}; +import App from "@site/docs/app" +import SignupLink from "./components/register" -Firstly register an account from the . +Firstly register an Account +
 
Once you have registered, you can go to [Create the First Callgent](create-a-new-callgent) page. diff --git a/docs/user-as-a-service/_category_.json b/docs/user-as-a-service/_category_.json new file mode 100644 index 0000000..c329b5a --- /dev/null +++ b/docs/user-as-a-service/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "User as a Service", + "position": 3, + "link": { + "type": "generated-index", + "description": "Now, let's encapsulate a user as a REST-API service. By default, the user may respond to invocations by email. And user can respond from Slack channels and other scenarios easily." + } +} diff --git a/docs/user-as-a-service/define-user-api.md b/docs/user-as-a-service/define-user-api.md new file mode 100644 index 0000000..130c69e --- /dev/null +++ b/docs/user-as-a-service/define-user-api.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +title: Define the user API +description: Callgent is yet another AI programming tool besides Copilot, UI generator, and bug fixer, etc. +keywords: [user as a service] +--- diff --git a/docs/user-as-a-service/import-user-api-into-callgent.md b/docs/user-as-a-service/import-user-api-into-callgent.md new file mode 100644 index 0000000..3045922 --- /dev/null +++ b/docs/user-as-a-service/import-user-api-into-callgent.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 2 +title: Import API definition into Callgent +description: . +keywords: [user as a service] +--- diff --git a/docs/user-as-a-service/invoke-user-callgent-by-rest-api.md b/docs/user-as-a-service/invoke-user-callgent-by-rest-api.md new file mode 100644 index 0000000..bc0c484 --- /dev/null +++ b/docs/user-as-a-service/invoke-user-callgent-by-rest-api.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 3 +title: Invoke the User Callgent by REST API +description: . +keywords: [user as a service] +--- diff --git a/docs/user-as-a-service/user-responds-through-other-channels.md b/docs/user-as-a-service/user-responds-through-other-channels.md new file mode 100644 index 0000000..07876c5 --- /dev/null +++ b/docs/user-as-a-service/user-responds-through-other-channels.md @@ -0,0 +1,6 @@ +--- +sidebar_position: 4 +title: User responds through other channels +description: . +keywords: [user as a service] +--- diff --git a/src/store/slices/userSlice.ts b/src/store/slices/userSlice.ts index 4cb89f1..5da132c 100644 --- a/src/store/slices/userSlice.ts +++ b/src/store/slices/userSlice.ts @@ -9,7 +9,7 @@ const userSlice = createSlice({ userData: {}, callgent: {}, status: {}, - token: getCookie('jwt'), + token: getCookie('x-callgent-jwt'), fetchState: {}, } as userSliceType, reducers: { @@ -26,22 +26,17 @@ const userSlice = createSlice({ }, }, extraReducers: (builder) => { - // 注册接口 builder.addCase(fetchCreateCallgent.fulfilled, (state, action) => { - // console.log(action.payload.data); - state.callgent = action.payload.data }); builder.addCase(fetchCreateCallgent.pending, (state, action) => { // state.loading = true; }); - // 用户详情 builder.addCase(fetchUserInfo.fulfilled, (state, action) => { - // console.log('用户详情', action); }); }, }); -export const { setStatus, setCallgent,setFetchState } = userSlice.actions; +export const { setStatus, setCallgent, setFetchState } = userSlice.actions; export default userSlice.reducer; \ No newline at end of file diff --git a/src/store/thunk/user/index.ts b/src/store/thunk/user/index.ts index 668876a..14e7bba 100644 --- a/src/store/thunk/user/index.ts +++ b/src/store/thunk/user/index.ts @@ -20,12 +20,12 @@ export const fetchCreateCallgent = createAsyncThunk>( 'users/fetchUserInfo', async (user, thunkAPI) => { try { - + const { data } = await axios.get('/api/users/info'); if (data?.data) { localStorage.setItem('userinfo', JSON.stringify(data.data)); @@ -38,3 +38,20 @@ export const fetchUserInfo = createAsyncThunk>( } } ); + +// Send a confirmation email +export const sendConfirmEmail = createAsyncThunk, { email: string }>( + 'users/sendConfirmEmail', + async (emailData, thunkAPI) => { + try { + const { data } = await axios.post('/api/users/send-confirm-email', { + email: emailData.email, + create: true, + resetPwd: true, + }); + return data; + } catch (error) { + return thunkAPI.rejectWithValue('Failed to send confirmation email'); + } + } +); \ No newline at end of file diff --git a/src/util/axios/index.ts b/src/util/axios/index.ts index b5f2354..c8df514 100644 --- a/src/util/axios/index.ts +++ b/src/util/axios/index.ts @@ -10,14 +10,14 @@ const axios = axioshead.create({ }); axios.interceptors.request.use( (config) => { - const token = getCookie('jwt'); + const token = getCookie('x-callgent-jwt'); if (token) { config.headers.Authorization = 'Bearer ' + token; } return config; }, (error) => { - console.error('错误:', error); + console.error('error', error); return error }, ); @@ -27,11 +27,8 @@ axios.interceptors.response.use( }, async error => { if (error.response && error.response.status === 401) { - deleteCookie('jwt') - console.error('401错误:请重新登录。'); - // window.location.href = '/login'; + deleteCookie('x-callgent-jwt') } else { - console.error('其他错误:', error); } return Promise.reject(error); }