Moved frontend to separate folder, added basic user context and user page

This commit is contained in:
2020-11-28 20:01:35 +05:00
parent da8a37dfbd
commit 452518f898
27 changed files with 382 additions and 50 deletions

View File

@ -0,0 +1,20 @@
import React from "react";
import { IRouteCard } from "types/user";
import { formatTimeLength } from "utils";
const RouteCard: React.FC<IRouteCard> = ({ route }) => {
return (
<div>
<h2>{route.name}</h2>
<p>
Данный квесты вы сможете пройти за {formatTimeLength(route.averageTime)}
</p>
<p>Длинна маршрута: {route.length} м</p>
<p>Примерное время прохождения: {route.averageTime}</p>
<p>Точка старта:</p>
</div>
);
};
export default RouteCard;

View File

@ -0,0 +1,16 @@
import React from "react";
import { IRouteView } from "types/user";
import RouteCard from "./RouteCard";
const RouteView: React.FC<IRouteView> = ({ header, routes }) => {
return (
<>
<h1>{header}</h1>
{routes.map((route) => (
<RouteCard key={route.id} route={route} />
))}
</>
);
};
export default RouteView;

View File

@ -0,0 +1,28 @@
import React from "react";
import Link from "next/link";
import { IHeaderProps } from "types/user";
const Header: React.FC<IHeaderProps> = ({ points }) => {
return (
<header>
<div>Очки: {points}</div>
<nav>
<ul>
<li>
<Link href="/profile">
<a>Профиль</a>
</Link>
</li>
<li>
<Link href="/achivements">
<a>Ачивки</a>
</Link>
</li>
</ul>
</nav>
</header>
);
};
export default Header;

View File

@ -0,0 +1,26 @@
import React, { useMemo, useState } from "react";
import { UserContextT, UserT } from "types/userContext";
const UserContext = React.createContext<UserContextT>(null);
const initialContext: UserT = {
username: "",
email: "",
points: 0,
id: 0,
};
const UserProvider: React.FC = ({ children }) => {
const [state, setState] = useState<UserT>(initialContext);
const value = useMemo(() => ({ userState: state, setUserState: setState }), [
state,
]);
return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
};
export { UserProvider, UserContext };
export type { UserT, UserContextT } from "../../types/userContext";

8
front/jsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"module": "esnext",
"target": "es5",
"baseUrl": "."
},
"exclude": ["node_modules", ".next"]
}

View File

@ -0,0 +1,7 @@
import React from "react";
const EmptyLayout: React.FC = ({ children }) => {
return <>{children}</>;
};
export default EmptyLayout;

View File

@ -0,0 +1,14 @@
import React from "react";
import styles from "styles/layout.module.css";
import { UserProvider } from "context/user";
const Layout: React.FC = ({ children }) => {
return (
<UserProvider>
<div className={styles.content}>{children}</div>
</UserProvider>
);
};
export default Layout;

View File

@ -0,0 +1,16 @@
import React, { useContext } from "react";
import Header from "components/User/header";
import { UserContext } from "context/user";
const UserLayout: React.FC = ({ children }) => {
const { userState } = useContext(UserContext);
return (
<>
<Header points={userState.points} />
<main>{children}</main>
</>
);
};
export default UserLayout;

2
front/next-env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

23
front/package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "ugra-hackathon_frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"format": "prettier --write \"**/*.+(js|jsx|json|css|md)\""
},
"dependencies": {
"next": "10.0.3",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-yandex-maps": "^4.4.0"
},
"devDependencies": {
"@types/node": "^14.14.10",
"@types/react": "^17.0.0",
"prettier": "^2.2.0",
"typescript": "^4.1.2"
}
}

18
front/pages/_app.tsx Normal file
View File

@ -0,0 +1,18 @@
import React from "react";
import "styles/globals.css";
import Layout from "layouts/MainLayout";
import EmptyLayout from "layouts/EmptyLayout";
function MyApp({ Component, pageProps }) {
const ComponentLayout = Component.Layout || EmptyLayout;
return (
<Layout>
<ComponentLayout>
<Component {...pageProps} />
</ComponentLayout>
</Layout>
);
}
export default MyApp;

View File

@ -0,0 +1,39 @@
import React from "react";
import { YMaps, Map, Placemark } from "react-yandex-maps";
import { RouteT } from "types/main";
const route: RouteT = {
id: 0,
length: 10,
name: "Тест",
averageTime: 10,
startCoordinates: {
latitude: 10,
longitude: 10,
},
};
const Route: React.FC = () => {
return (
<YMaps>
<Map
defaultState={{
center: [
route.startCoordinates.latitude,
route.startCoordinates.longitude,
],
zoom: 14,
}}
>
<Placemark
geometry={[
route.startCoordinates.latitude,
route.startCoordinates.longitude,
]}
/>
</Map>
</YMaps>
);
};
export default Route;

31
front/pages/user.tsx Normal file
View File

@ -0,0 +1,31 @@
import UserLayout from "layouts/UserLayout";
import { UserContext } from "context/user";
import React, { useContext } from "react";
import RouteView from "components/User/RouteView";
import { RouteT } from "types/main";
const routes: RouteT[] = [
{
id: 0,
name: "Пешком",
length: 100,
averageTime: 100,
startCoordinates: {
latitude: 60.977313,
longitude: 69.039326,
},
},
];
const User = () => {
const { userState, setUserState } = useContext(UserContext);
return (
<>
<RouteView header={"Новые маршруты"} routes={routes} />
</>
);
};
User.Layout = UserLayout;
export default User;

BIN
front/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

4
front/public/vercel.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

0
front/styles/globals.css Normal file
View File

View File

View File

20
front/tsconfig.json Normal file
View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": "."
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

16
front/types/main.ts Normal file
View File

@ -0,0 +1,16 @@
type RouteT = {
id: number;
name: string;
length: number;
averageTime?: number;
userTime?: number;
startCoordinates?: CoordinatesT;
coordinates?: CoordinatesT[];
};
type CoordinatesT = {
latitude: number;
longitude: number;
};
export type { RouteT, CoordinatesT };

16
front/types/user.ts Normal file
View File

@ -0,0 +1,16 @@
import { RouteT } from "./main";
interface IHeaderProps {
points: number;
}
interface IRouteView {
header: string;
routes: RouteT[];
}
interface IRouteCard {
route: RouteT;
}
export type { IHeaderProps, IRouteView, IRouteCard };

View File

@ -0,0 +1,13 @@
import { Dispatch, SetStateAction } from "react";
export type UserT = {
username: string;
email: string;
id: number;
points: number;
};
export type UserContextT = {
userState: UserT;
setUserState: Dispatch<SetStateAction<UserT>>;
};

5
front/utils/index.ts Normal file
View File

@ -0,0 +1,5 @@
const formatTimeLength = (minutes: number) =>
(Math.floor(minutes / 60) > 0 ? `${Math.floor(minutes / 60)} ч. ` : "") +
(minutes % 60 > 0 ? `${minutes % 60} мин.` : "");
export { formatTimeLength };

4138
front/yarn.lock Normal file

File diff suppressed because it is too large Load Diff