Adds screens for basic onboarding and login

This commit is contained in:
Chris Anderson 2023-03-04 23:32:44 -06:00
parent 732d8d1f12
commit 8967fe1bf6
10 changed files with 136 additions and 3 deletions

View file

@ -80,7 +80,7 @@ function createProjectEntityPath<T, C = Omit<T, OmitFields>, U = Omit<T, OmitFie
const api = {
login() {
window.location.href = env.api.baseURL + '/auth/login?r=' + encodeURIComponent(window.location.href)
window.location.href = `/login?r=${encodeURIComponent(window.location.href)}`
},
async logout() {

View file

@ -125,6 +125,7 @@ label.hide-label {
}
label .label-subtitle {
color: var(--color-primary-soft);
font-weight: 400;
font-size: 14px;
}

View file

@ -42,7 +42,7 @@
--color-grey-soft: #252b3a;
--color-primary: var(--color-white);
--color-primary-soft: #F9FAFB;
--color-primary-soft: #e8ebed;
--color-background: var(--color-black);
--color-background-soft: var(--color-grey-soft);

View file

@ -0,0 +1,26 @@
.auth {
background: var(--color-background-soft);
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
flex-direction: column;
gap: 15px;
padding: 40px 0;
}
.auth .logo svg {
height: 40px;
}
.auth-step {
max-width: 600px;
background: var(--color-background);
border: 1px solid var(--color-grey-soft);
border-radius: var(--border-radius-outer);
padding: 40px;
}
.auth-step h1 {
margin: 0;
}

View file

@ -0,0 +1,25 @@
import { ReactComponent as Logo } from '../../assets/logo.svg'
import { env } from '../../config/env'
import Button from '../../ui/Button'
import './Auth.css'
export default function Login() {
const handleRedirect = () => {
const urlParams = new URLSearchParams(window.location.search)
window.location.href = `${env.api.baseURL}/auth/login?r=${urlParams.get('r')}`
}
return (
<div className="auth login">
<div className="logo">
<Logo />
</div>
<div className="auth-step">
<h1>Welcome!</h1>
<p>Please use the button below to authenticate.</p>
<Button onClick={handleRedirect}>Login</Button>
</div>
</div>
)
}

View file

@ -0,0 +1,16 @@
import { Outlet } from 'react-router-dom'
import './Auth.css'
import { ReactComponent as Logo } from '../../assets/logo.svg'
export default function Onboarding() {
return (
<div className="auth onboarding">
<div className="logo">
<Logo />
</div>
<div className="auth-step">
<Outlet />
</div>
</div>
)
}

View file

@ -0,0 +1,11 @@
import ProjectForm from '../project/ProjectForm'
export default function OnboardingProject() {
return (
<>
<h1>Project Setup</h1>
<p>At Parcelvoy, projects represent a single workspace for sending messages. You can use them for creating staging environments, isolating different clients, etc. Let&apos;s create your first one to get you started!</p>
<ProjectForm />
</>
)
}

View file

@ -0,0 +1,11 @@
import { LinkButton } from '../../ui/Button'
export default function Onboarding() {
return (
<>
<h1>Welcome!</h1>
<p>Looks like everything is working with the installation! Now let&apos;s get you setup and ready to run some campaigns!</p>
<LinkButton to="/onboarding/project">Get Started</LinkButton>
</>
)
}

View file

@ -3,10 +3,19 @@ import api from '../../api'
import TextField from '../../ui/form/TextField'
import { ProjectCreate } from '../../types'
import FormWrapper from '../../ui/form/FormWrapper'
import { SelectField } from '../../ui/form/SelectField'
// eslint-disable-next-line @typescript-eslint/no-namespace
export declare namespace Intl {
type Key = 'calendar' | 'collation' | 'currency' | 'numberingSystem' | 'timeZone' | 'unit'
function supportedValuesOf(input: Key): string[]
}
export default function ProjectForm() {
const navigate = useNavigate()
const timeZones = Intl.supportedValuesOf('timeZone')
return (
<FormWrapper<ProjectCreate>
onSubmit={async project => {
@ -18,7 +27,19 @@ export default function ProjectForm() {
form => (
<>
<TextField form={form} name="name" required />
<TextField form={form} name="description" />
<TextField form={form} name="description" textarea />
<TextField form={form}
name="locale"
label="Default Locale"
subtitle="This locale will be used as the default when creating campaigns and when a users locale does not match any available ones."
required />
<SelectField.Field
form={form}
options={timeZones}
name="timezone"
label="Timezone"
required
/>
</>
)
}

View file

@ -32,6 +32,10 @@ import JourneyEditor from './journey/JourneyEditor'
import ProjectSettings from './settings/ProjectSettings'
import Integrations from './settings/Integrations'
import Tags from './settings/Tags'
import Login from './auth/Login'
import OnboardingStart from './auth/OnboardingStart'
import Onboarding from './auth/Onboarding'
import OnboardingProject from './auth/OnboardingProject'
export const route = (path: string, includeProject = true) => {
const { projectId = '' } = useParams()
@ -57,6 +61,24 @@ export const useRoute = (includeProject = true) => {
}
export const router = createBrowserRouter([
{
path: '/login',
element: <Login />,
},
{
path: '/onboarding',
element: <Onboarding />,
children: [
{
index: true,
element: <OnboardingStart />,
},
{
path: 'project',
element: <OnboardingProject />,
},
],
},
{
path: '*',
errorElement: <ErrorPage />,