diff --git a/packages/components/src/icons/SemanticIcons.ts b/packages/components/src/icons/SemanticIcons.ts new file mode 100644 index 0000000000..099c232d43 --- /dev/null +++ b/packages/components/src/icons/SemanticIcons.ts @@ -0,0 +1,8 @@ +import { IconDefinition, faUser, faEnvelope } from '@fortawesome/free-solid-svg-icons' + +// Semantic, shared definitions for reused icons. + +export const iconEnvelope : IconDefinition = faEnvelope; +export const iconUser : IconDefinition = faUser; + + diff --git a/packages/fakeyou/src/v2/api/user/CreateSession.ts b/packages/components/src/session/CreateSession.ts similarity index 100% rename from packages/fakeyou/src/v2/api/user/CreateSession.ts rename to packages/components/src/session/CreateSession.ts diff --git a/packages/fakeyou/src/v2/view/login/LoginFc.tsx b/packages/fakeyou/src/v2/view/login/LoginFc.tsx index 4a750471b2..6adfb6abe9 100644 --- a/packages/fakeyou/src/v2/view/login/LoginFc.tsx +++ b/packages/fakeyou/src/v2/view/login/LoginFc.tsx @@ -3,7 +3,7 @@ import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapp import { useHistory } from "react-router-dom"; import { UserIcon } from '../_icons/UserIcon'; import { EnvelopeIcon } from '../_icons/EnvelopeIcon'; -import { CreateSession, CreateSessionIsError, CreateSessionIsSuccess } from '../../api/user/CreateSession'; +import { CreateSession, CreateSessionIsError, CreateSessionIsSuccess } from '@storyteller/components/src/session/CreateSession'; interface Props { sessionWrapper: SessionWrapper, diff --git a/packages/storyteller/src/App.tsx b/packages/storyteller/src/App.tsx index 5846f38754..76dc392514 100644 --- a/packages/storyteller/src/App.tsx +++ b/packages/storyteller/src/App.tsx @@ -3,17 +3,17 @@ import './App.scss'; import React from 'react'; import { BrowserRouter, Route, Switch } from "react-router-dom"; -//import { Common } from "@storyteller/components"; -import { IndexPage } from './pages/index/IndexPage'; -import { TopNav } from './layout/TopNav'; import StreamPage from './pages/stream/StreamPage'; -import { ComingSoonPage } from './pages/coming-soon/ComingSoonPage'; -import { ObsLayerPage } from './pages/obs-layer/ObsLayerPage'; -import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper'; -import { DetectLocale, DetectLocaleIsOk } from '@storyteller/components/src/api/locale/DetectLocale'; import i18n from 'i18next'; -import { initReactI18next } from 'react-i18next'; +import { ComingSoonPage } from './pages/coming-soon/ComingSoonPage'; +import { LoginPage } from './pages/login/LoginPage'; +import { DetectLocale, DetectLocaleIsOk } from '@storyteller/components/src/api/locale/DetectLocale'; +import { IndexPage } from './pages/index/IndexPage'; +import { ObsLayerPage } from './pages/obs-layer/ObsLayerPage'; import { STORYTELLER_MERGED_TRANSLATIONS } from './_i18n/StorytellerTranslations' +import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper'; +import { TopNav } from './layout/TopNav'; +import { initReactI18next } from 'react-i18next'; i18n .use(initReactI18next) // passes i18n down to react-i18next @@ -84,6 +84,12 @@ class App extends React.Component { + + + diff --git a/packages/storyteller/src/pages/login/LoginPage.tsx b/packages/storyteller/src/pages/login/LoginPage.tsx new file mode 100644 index 0000000000..c33c631a0a --- /dev/null +++ b/packages/storyteller/src/pages/login/LoginPage.tsx @@ -0,0 +1,108 @@ +import React, { useState } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper'; +import { useHistory } from "react-router-dom"; +import { iconEnvelope, iconUser } from '@storyteller/components/src/icons/SemanticIcons'; +import { CreateSession, CreateSessionIsError, CreateSessionIsSuccess } from '@storyteller/components/src/session/CreateSession'; + +interface Props { + sessionWrapper: SessionWrapper, + querySessionAction: () => void, +} + +function LoginPage(props: Props) { + let history = useHistory(); + + const [password, setPassword] = useState('') + const [usernameOrEmail, setUsernameOrEmail] = useState('') + const [errorMessage, setErrorMessage] = useState('') + + if (props.sessionWrapper.isLoggedIn()) { + history.push('/'); + } + + const handleUsernameOrEmailChange = (ev: React.FormEvent) => { + ev.preventDefault(); + const usernameOrEmailValue = (ev.target as HTMLInputElement).value; + setUsernameOrEmail(usernameOrEmailValue); + setErrorMessage(""); + return false; + }; + + const handlePasswordChange = (ev: React.FormEvent) => { + ev.preventDefault(); + const passwordValue = (ev.target as HTMLInputElement).value; + setPassword(passwordValue); + setErrorMessage(""); + return false; + }; + + const handleFormSubmit = async (ev: React.FormEvent) : Promise => { + ev.preventDefault(); + + const request = { + username_or_email: usernameOrEmail, + password: password, + } + + const response = await CreateSession(request); + + if (CreateSessionIsError(response)) { + setErrorMessage(response.error_message); + } else if (CreateSessionIsSuccess(response)) { + console.log('querying new session'); + props.querySessionAction(); + history.push('/'); + } + + return false; + } + + let errorWarning = + if (errorMessage) { + errorWarning = ( +
+ Login Error: {errorMessage} +
+ ) + } + + return ( +
+

Login

+ + {errorWarning} + +
+
+ +
+ + + + +
+ {/*

*/} +
+ +
+ +
+ + + + +
+ {/*

*/} +
+ +
+ + + +
+
+ ) +} + +export { LoginPage };