Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(preferences): 2FA activation dialog with mocked state #605

Merged
merged 14 commits into from
Jul 27, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/assets/icons/ic-info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions app/assets/javascripts/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { FunctionComponent } from 'preact';

const base = `rounded px-4 py-1.75 font-bold text-sm fit-content cursor-pointer`;

const normal = `${base} bg-default color-text border-solid border-gray-300 border-1 \
antsgar marked this conversation as resolved.
Show resolved Hide resolved
focus:bg-contrast hover:bg-contrast`;
const primary = `${base} no-border bg-info color-info-contrast hover:brightness-130 \
focus:brightness-130`;

export const Button: FunctionComponent<{
className?: string;
type: 'normal' | 'primary';
label: string;
onClick: () => void;
}> = ({ type, label, className = '', onClick }) => {
const buttonClass = type === 'primary' ? primary : normal;
return (
<button
className={`${buttonClass} ${className}`}
onClick={(e) => {
onClick();
e.preventDefault();
}}
>
{label}
</button>
);
};
38 changes: 38 additions & 0 deletions app/assets/javascripts/components/CircleProgress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FunctionComponent } from 'preact';

export const CircleProgress: FunctionComponent<{
percent: number;
className?: string;
}> = ({ percent, className = '' }) => {
const size = 16;
const ratioStrokeRadius = 0.25;
const outerRadius = size / 2;

const radius = outerRadius * (1 - ratioStrokeRadius);
const stroke = outerRadius - radius;

const circumference = radius * 2 * Math.PI;
const offset = circumference - (percent / 100) * circumference;

const transition = `transition: 0.35s stroke-dashoffset;`;
const transform = `transform: rotate(-90deg);`;
const transformOrigin = `transform-origin: 50% 50%;`;
const dasharray = `stroke-dasharray: ${circumference} ${circumference};`;
const dashoffset = `stroke-dashoffset: ${offset};`;
const style = `${transition} ${transform} ${transformOrigin} ${dasharray} ${dashoffset}`;
return (
<div className="h-5 w-5 min-w-5 min-h-5">
<svg viewBox={`0 0 ${size} ${size}`}>
<circle
stroke="#086DD6"
stroke-width={stroke}
fill="transparent"
r={radius}
cx="50%"
cy="50%"
style={style}
/>
</svg>
</div>
);
};
4 changes: 2 additions & 2 deletions app/assets/javascripts/components/DecoratedInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export const DecoratedInput: FunctionalComponent<Props> = ({
const classes = `${base} ${stateClasses} ${className}`;

return (
<div className={classes}>
<div className={`${classes} focus-within:ring-info`}>
{left}
<div className="flex-grow">
<input
type="text"
className="w-full no-border color-black"
className="w-full no-border color-black focus:shadow-none"
disabled={disabled}
value={text}
/>
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import ThemesIcon from '../../icons/ic-themes.svg';
import UserIcon from '../../icons/ic-user.svg';
import CopyIcon from '../../icons/ic-copy.svg';
import DownloadIcon from '../../icons/ic-download.svg';
import InfoIcon from '../../icons/ic-info.svg';

import { toDirective } from './utils';
import { FunctionalComponent } from 'preact';
Expand Down Expand Up @@ -56,6 +57,7 @@ const ICONS = {
user: UserIcon,
copy: CopyIcon,
download: DownloadIcon,
info: InfoIcon,
};

export type IconType = keyof typeof ICONS;
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/components/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const IconButton: FunctionComponent<Props> = ({
};
return (
<button
className={`no-border bg-transparent hover:brightness-130 p-0 ${
className={`no-border cursor-pointer bg-transparent hover:brightness-130 p-0 ${
className ?? ''
}`}
onClick={click}
Expand Down
19 changes: 0 additions & 19 deletions app/assets/javascripts/preferences/PreferencesMenu.tsx

This file was deleted.

53 changes: 36 additions & 17 deletions app/assets/javascripts/preferences/PreferencesView.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
import { RoundIconButton } from '@/components/RoundIconButton';
import { TitleBar, Title } from '@/components/TitleBar';
import { FunctionComponent } from 'preact';
import { Preferences } from './models/preferences';
import { PreferencesMenu } from './PreferencesMenu';
import { HelpAndFeedback } from './panes/HelpFeedback';
import { HelpAndFeedback, Security } from './panes';
import { observer } from 'mobx-react-lite';
import { Security } from './panes/Security';

interface PreferencesViewProps {
close: () => void;
}
import { MenuItem } from './components';
import { PreferencesMenu } from './preferences-menu';

const PaneSelector: FunctionComponent<{
prefs: Preferences;
}> = observer(({ prefs }) => {
switch (prefs.selectedPaneId) {
prefs: PreferencesMenu;
}> = observer(({ prefs: menu }) => {
switch (menu.selectedPaneId) {
case 'general':
return null;
case 'account':
return null;
case 'appearance':
return null;
case 'security':
return <Security prefs={prefs} />;
return <Security />;
case 'listed':
return null;
case 'shortcuts':
Expand All @@ -37,19 +32,27 @@ const PaneSelector: FunctionComponent<{
});

const PreferencesCanvas: FunctionComponent<{
preferences: Preferences;
preferences: PreferencesMenu;
}> = observer(({ preferences: prefs }) => (
<div className="flex flex-row flex-grow min-h-0 justify-between">
<PreferencesMenu preferences={prefs}></PreferencesMenu>
<PreferencesMenuView menu={prefs}></PreferencesMenuView>
<PaneSelector prefs={prefs} />
</div>
));

const PreferencesView: FunctionComponent<PreferencesViewProps> = observer(
const blockPropagation = (e: MouseEvent) => {
e.stopPropagation();
};

const PreferencesView: FunctionComponent<{ close: () => void }> = observer(
({ close }) => {
const prefs = new Preferences();
const prefs = new PreferencesMenu();

return (
<div className="sn-full-screen flex flex-col bg-contrast z-index-preferences">
<div
onClick={blockPropagation}
antsgar marked this conversation as resolved.
Show resolved Hide resolved
className="sn-full-screen flex flex-col bg-contrast z-index-preferences"
>
<TitleBar className="items-center justify-between">
{/* div is added so flex justify-between can center the title */}
<div className="h-8 w-8" />
Expand Down Expand Up @@ -79,3 +82,19 @@ export const PreferencesViewWrapper: FunctionComponent<PreferencesWrapperProps>
<PreferencesView close={() => appState.preferences.closePreferences()} />
);
});

export const PreferencesMenuView: FunctionComponent<{
menu: PreferencesMenu;
}> = observer(({ menu }) => (
<div className="min-w-55 overflow-y-auto flex flex-col px-3 py-6">
{menu.menuItems.map((pref) => (
<MenuItem
key={pref.id}
iconType={pref.icon}
label={pref.label}
selected={pref.selected}
onClick={() => menu.selectPane(pref.id)}
/>
))}
</div>
));
14 changes: 6 additions & 8 deletions app/assets/javascripts/preferences/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ export const Text: FunctionComponent = ({ children }) => (
<p className="text-xs">{children}</p>
);

export const Button: FunctionComponent<{ label: string; link: string }> = ({
const buttonClasses = `block bg-default color-text rounded border-solid \
border-1 border-gray-300 px-4 py-1.75 font-bold text-sm fit-content mt-3 \
focus:bg-contrast hover:bg-contrast `;

export const LinkButton: FunctionComponent<{ label: string; link: string }> = ({
label,
link,
}) => (
<a
target="_blank"
className="block bg-default color-text rounded border-solid border-1
border-gray-300 px-4 py-2 font-bold text-sm fit-content mt-3
focus:bg-contrast hover:bg-contrast "
href={link}
>
<a target="_blank" className={buttonClasses} href={link}>
{label}
</a>
);
2 changes: 0 additions & 2 deletions app/assets/javascripts/preferences/models/index.ts

This file was deleted.

81 changes: 0 additions & 81 deletions app/assets/javascripts/preferences/models/two-factor-auth.ts

This file was deleted.

11 changes: 5 additions & 6 deletions app/assets/javascripts/preferences/panes/HelpFeedback.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { FunctionComponent } from 'preact';
import {} from '../components';
import {
Title,
Subtitle,
Text,
Button,
LinkButton,
PreferencesGroup,
PreferencesPane,
PreferencesSegment,
Expand Down Expand Up @@ -53,7 +52,7 @@ export const HelpAndFeedback: FunctionComponent = () => (
</PreferencesSegment>
<PreferencesSegment>
<Subtitle>Can’t find your question here?</Subtitle>
<Button label="Open FAQ" link="https://standardnotes.com/help" />
<LinkButton label="Open FAQ" link="https://standardnotes.com/help" />
</PreferencesSegment>
</PreferencesGroup>
<PreferencesGroup>
Expand All @@ -68,7 +67,7 @@ export const HelpAndFeedback: FunctionComponent = () => (
</a>{' '}
before advocating for a feature request.
</Text>
<Button
<LinkButton
label="Go to the forum"
link="https://forum.standardnotes.org/"
/>
Expand All @@ -82,7 +81,7 @@ export const HelpAndFeedback: FunctionComponent = () => (
Want to share your feedback with us? Join the Standard Notes Slack
group for discussions on security, themes, editors and more.
</Text>
<Button
<LinkButton
link="https://standardnotes.com/slack"
label="Join our Slack group"
/>
Expand All @@ -94,7 +93,7 @@ export const HelpAndFeedback: FunctionComponent = () => (
<Text>
Send an email to [email protected] and we’ll sort it out.
</Text>
<Button link="mailto: [email protected]" label="Email us" />
<LinkButton link="mailto: [email protected]" label="Email us" />
</PreferencesSegment>
</PreferencesGroup>
</PreferencesPane>
Expand Down
14 changes: 5 additions & 9 deletions app/assets/javascripts/preferences/panes/Security.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { PreferencesPane } from '../components';
import { Preferences } from '../models';
import { TwoFactorAuthComponent } from './TwoFactorAuth';
import { TwoFactorAuthWrapper } from './two-factor-auth';

export const Security: FunctionComponent<{ prefs: Preferences }> = observer(
({ prefs }) => (
<PreferencesPane>
<TwoFactorAuthComponent tfAuth={prefs.twoFactorAuth} />
</PreferencesPane>
)
export const Security: FunctionComponent = () => (
<PreferencesPane>
<TwoFactorAuthWrapper />
</PreferencesPane>
);
Loading