add signup

This commit is contained in:
2024-11-30 09:47:34 +03:00
parent ccc92ecea0
commit 8e744cf2dd
21 changed files with 10629 additions and 2 deletions

8
src/app.tsx Normal file
View File

@@ -0,0 +1,8 @@
import React from 'react';
import Main from './container/main';
const App = () => {
return <Main />;
};
export default App;

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

38
src/container/Constant.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,36 @@
declare global {
interface Window {
Telegram: {
WebApp: any;
};
}
}
const useTelegram = () => {
const tg = window.Telegram.WebApp;
const onClose = () => {
tg.close()
}
const onToggleButton = () => {
if(tg.MainButton.isVisible) {
tg.MainButton.hide();
} else {
tg.MainButton.show();
}
}
return {
onClose,
onToggleButton,
tg,
user_id: tg.initDataUnsafe?.user?.id,
user: tg.initDataUnsafe?.user,
username: tg.initDataUnsafe?.user?.username,
queryId: tg.initDataUnsafe?.query_id
}
}
export default useTelegram;

View File

@@ -0,0 +1,28 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { getNavigationsValue } from '@brojs/cli';
const navigations: Array<{ name: string; href: string }> = [
{
name: 'Регистрация',
href: getNavigationsValue('sberhubproject.signup')
}
];
const Header = (): React.ReactElement => {
return (
<header>
<ul>
{navigations.map((item) => {
return (
<li key={item.name}>
<Link to={item.href}>{item.name}</Link>
</li>
);
})}
</ul>
</header>
);
};
export default Header;

View File

@@ -0,0 +1,16 @@
import React from 'react';
import { Outlet } from 'react-router-dom';
import Header from './header';
const Layout = (): React.ReactElement => {
return (
<>
<Header />
<main>
<Outlet />
</main>
</>
);
};
export default Layout;

View File

@@ -0,0 +1,9 @@
import React from 'react';
import { RouterProvider } from 'react-router-dom';
import { router } from './router';
const Main = (): React.ReactElement => {
return <RouterProvider router={router} />;
};
export default Main;

View File

@@ -0,0 +1,18 @@
import React from 'react';
import { createBrowserRouter } from 'react-router-dom';
import SingUpPage from '../signup';
import { getNavigationsValue } from '@brojs/cli';
import Layout from './components/layout';
export const router = createBrowserRouter([
{
path: getNavigationsValue('sberhubproject.signup'),
element: <Layout />,
children: [
{
path: getNavigationsValue('sberhubproject.signup'),
element: <SingUpPage />
}
]
}
]);

View File

@@ -0,0 +1,7 @@
.upload-input {
display: none;
}
.basic-multi-select {
width: 100%;
}

View File

@@ -0,0 +1,171 @@
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline';
import TextField from '@mui/material/TextField';
import Grid from '@mui/material/Grid';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import axios from 'axios';
import student_icon from '../../assets/images/student-icon.png';
import "./index.css";
//import useTelegram from "../hooks/useTelegram";
import Select from 'react-select';
import makeAnimated from 'react-select/animated';
import { useState } from 'react';
import { useConstant } from '../Constant';
const animatedComponents = makeAnimated();
const theme = createTheme();
const SingUpPage = (): React.ReactElement => {
const [avatarUrl, setAvatarUrl] = useState<string | null>(null);
const [selectedOption, setSelectedOption] = useState<string | null>(null);
const handleChange = (selectedOption) => {
setSelectedOption(selectedOption);
};
const { interests } = useConstant();
//const { user_id, username, onClose } = useTelegram();
/*
const handleSubmit = async (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
const form = {
id: user_id,
name: username,
fullname: data.get('lname') + ' ' + data.get('fname'),
about: data.get('about'), // Новое поле "Обо мне"
photo: image,
interests: selectedOption?.map((item) => item.value)
};
await axios.post("https://sergeymorykov-tg-web-backend-1a6e.twc1.net/users_reg", form);
//await axios.post("http://localhost:5000/users_reg", form);
delete form.photo;
window.Telegram.WebApp.sendData(JSON.stringify(form));
onClose();
};
*/
const handleAvatarClick = () => {
const fileInput = document.getElementById('avatar-input') as HTMLInputElement;
fileInput.click();
};
const handleAvatarChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = () => {
setAvatarUrl(reader.result as string);
};
reader.readAsDataURL(file);
};
return (
<ThemeProvider theme={theme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Typography component="h1" variant="h5">
Регистрация
</Typography>
<Box component="form" noValidate sx={{ mt: 3 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
required
fullWidth
id="lname"
label="Фамилия"
name="lname"
autoComplete="family-name"
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="given-name"
name="fname"
required
fullWidth
id="fname"
label="Имя"
autoFocus
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
multiline
rows={3}
id="about"
label="Обо мне"
name="about"
variant="outlined"
placeholder="Напишите о себе"
/>
</Grid>
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justifyContent="center"
sx={{ paddingTop: 7, paddingLeft: 3 }}
>
<Avatar src={avatarUrl || student_icon} onClick={handleAvatarClick} sx={{ width: 200, height: 200 }}/>
<input
type="file"
name="image"
accept="image/*"
onChange={handleAvatarChange}
style={{ display: 'none' }}
id="avatar-input"
/>
</Grid>
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justifyContent="center"
sx={{ paddingTop: 7, ml: 3 }}
>
<Select
onChange={handleChange}
closeMenuOnSelect={false}
components={animatedComponents}
isMulti
options={interests}
className="basic-multi-select"
classNamePrefix="select"
/>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2, ml: 3 }}
>
Регистрация
</Button>
</Grid>
</Box>
</Box>
</Container>
</ThemeProvider>
);
};
export default SingUpPage;

23
src/index.tsx Normal file
View File

@@ -0,0 +1,23 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './app';
export default () => <App />;
let rootElement: ReactDOM.Root;
export const mount = (Сomponent, element = document.getElementById('app')) => {
const rootElement = ReactDOM.createRoot(element);
rootElement.render(<Сomponent />);
if (module.hot) {
module.hot.accept('./app', () => {
rootElement.render(<Сomponent />);
});
}
};
export const unmount = () => {
rootElement.unmount();
};

4
src/typings/png.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module '*.png' {
const value: string;
export default value;
}