-
-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Purchase "Create account" & "Sign in" flows and Floating label …
…input (#672)
- Loading branch information
1 parent
7f1dddf
commit f9b1526
Showing
17 changed files
with
1,079 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { FunctionComponent, Ref } from 'preact'; | ||
import { JSXInternal } from 'preact/src/jsx'; | ||
import { forwardRef } from 'preact/compat'; | ||
import { useState } from 'preact/hooks'; | ||
|
||
type Props = { | ||
id: string; | ||
type: 'text' | 'email' | 'password'; // Have no use cases for other types so far | ||
label: string; | ||
value: string; | ||
onChange: JSXInternal.GenericEventHandler<HTMLInputElement>; | ||
disabled?: boolean; | ||
className?: string; | ||
labelClassName?: string; | ||
inputClassName?: string; | ||
isInvalid?: boolean; | ||
}; | ||
|
||
export const FloatingLabelInput: FunctionComponent<Props> = forwardRef( | ||
( | ||
{ | ||
id, | ||
type, | ||
label, | ||
disabled, | ||
value, | ||
isInvalid, | ||
onChange, | ||
className = '', | ||
labelClassName = '', | ||
inputClassName = '', | ||
}, | ||
ref: Ref<HTMLInputElement> | ||
) => { | ||
const [focused, setFocused] = useState(false); | ||
|
||
const BASE_CLASSNAME = `relative bg-default`; | ||
|
||
const LABEL_CLASSNAME = `hidden absolute ${ | ||
!focused ? 'color-neutral' : 'color-info' | ||
} ${focused || value ? 'flex top-0 left-2 pt-1.5 px-1' : ''} ${ | ||
isInvalid ? 'color-dark-red' : '' | ||
} ${labelClassName}`; | ||
|
||
const INPUT_CLASSNAME = `w-full h-full ${ | ||
focused || value ? 'pt-6 pb-2' : 'py-2.5' | ||
} px-3 text-input border-1 border-solid border-gray-300 rounded placeholder-medium text-input focus:ring-info ${ | ||
isInvalid ? 'border-dark-red placeholder-dark-red' : '' | ||
} ${inputClassName}`; | ||
|
||
const handleFocus = () => setFocused(true); | ||
|
||
const handleBlur = () => setFocused(false); | ||
|
||
return ( | ||
<div className={`${BASE_CLASSNAME} ${className}`}> | ||
<label htmlFor={id} className={LABEL_CLASSNAME}> | ||
{label} | ||
</label> | ||
<input | ||
id={id} | ||
className={INPUT_CLASSNAME} | ||
placeholder={!focused ? label : ''} | ||
type={type} | ||
value={value} | ||
onChange={onChange} | ||
onFocus={handleFocus} | ||
onBlur={handleBlur} | ||
ref={ref} | ||
disabled={disabled} | ||
/> | ||
</div> | ||
); | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { WebApplication } from '@/ui_models/application'; | ||
import { AppState } from '@/ui_models/app_state'; | ||
import { PurchaseFlowPane } from '@/ui_models/app_state/purchase_flow_state'; | ||
import { observer } from 'mobx-react-lite'; | ||
import { FunctionComponent } from 'preact'; | ||
import { CreateAccount } from './panes/CreateAccount'; | ||
import { SignIn } from './panes/SignIn'; | ||
import SNLogoFull from '../../svg/ic-sn-logo-full.svg'; | ||
|
||
type PaneSelectorProps = { | ||
currentPane: PurchaseFlowPane; | ||
} & PurchaseFlowViewProps; | ||
|
||
type PurchaseFlowViewProps = { | ||
appState: AppState; | ||
application: WebApplication; | ||
}; | ||
|
||
const PurchaseFlowPaneSelector: FunctionComponent<PaneSelectorProps> = ({ | ||
currentPane, | ||
appState, | ||
application, | ||
}) => { | ||
switch (currentPane) { | ||
case PurchaseFlowPane.CreateAccount: | ||
return <CreateAccount appState={appState} application={application} />; | ||
case PurchaseFlowPane.SignIn: | ||
return <SignIn appState={appState} application={application} />; | ||
} | ||
}; | ||
|
||
export const PurchaseFlowView: FunctionComponent<PurchaseFlowViewProps> = | ||
observer(({ appState, application }) => { | ||
const { currentPane } = appState.purchaseFlow; | ||
|
||
return ( | ||
<div className="flex items-center justify-center h-full w-full absolute top-left-0 z-index-purchase-flow bg-grey-2"> | ||
<div className="relative fit-content"> | ||
<div className="relative p-12 mb-4 bg-default border-1 border-solid border-gray-300 rounded"> | ||
<SNLogoFull className="mb-5" /> | ||
<PurchaseFlowPaneSelector | ||
currentPane={currentPane} | ||
appState={appState} | ||
application={application} | ||
/> | ||
</div> | ||
<div className="flex justify-end"> | ||
<a | ||
className="mr-3 font-medium color-grey-1" | ||
href="https://standardnotes.com/privacy" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
Privacy | ||
</a> | ||
<a | ||
className="font-medium color-grey-1" | ||
href="https://standardnotes.com/help" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
Help | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}); |
33 changes: 33 additions & 0 deletions
33
app/assets/javascripts/purchaseFlow/PurchaseFlowWrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { WebApplication } from '@/ui_models/application'; | ||
import { AppState } from '@/ui_models/app_state'; | ||
import { isDesktopApplication } from '@/utils'; | ||
import { observer } from 'mobx-react-lite'; | ||
import { FunctionComponent } from 'preact'; | ||
import { PurchaseFlowView } from './PurchaseFlowView'; | ||
|
||
export type PurchaseFlowWrapperProps = { | ||
appState: AppState; | ||
application: WebApplication; | ||
}; | ||
|
||
export const loadPurchaseFlowUrl = async ( | ||
application: WebApplication | ||
): Promise<void> => { | ||
const url = await application.getPurchaseFlowUrl(); | ||
if (url) { | ||
const currentUrl = window.location.href.split('/?')[0]; | ||
const successUrl = isDesktopApplication() | ||
? `standardnotes://${currentUrl}` | ||
: currentUrl; | ||
window.location.assign(`${url}&success_url=${successUrl}`); | ||
} | ||
}; | ||
|
||
export const PurchaseFlowWrapper: FunctionComponent<PurchaseFlowWrapperProps> = | ||
observer(({ appState, application }) => { | ||
if (!appState.purchaseFlow.isOpen) { | ||
return null; | ||
} | ||
|
||
return <PurchaseFlowView appState={appState} application={application} />; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { toDirective } from '@/components/utils'; | ||
import { | ||
PurchaseFlowWrapper, | ||
PurchaseFlowWrapperProps, | ||
} from './PurchaseFlowWrapper'; | ||
|
||
export const PurchaseFlowDirective = | ||
toDirective<PurchaseFlowWrapperProps>(PurchaseFlowWrapper); |
Oops, something went wrong.