Skip to content

Commit

Permalink
feat: side bar accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
KatoakDR committed Sep 3, 2024
1 parent 6b77301 commit 6eb92e0
Show file tree
Hide file tree
Showing 12 changed files with 571 additions and 310 deletions.
120 changes: 120 additions & 0 deletions electron/renderer/components/sidebar/accounts/modal-add-account.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import {
EuiConfirmModal,
EuiFieldPassword,
EuiFieldText,
EuiForm,
EuiFormRow,
} from '@elastic/eui';
import { useCallback, useEffect } from 'react';
import type { ReactNode } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { runInBackground } from '../../../lib/async/run-in-background.js';

export interface ModalAddAccountInitialData {
accountName?: string;
accountPassword?: string;
}

export interface ModalAddAccountConfirmData {
accountName: string;
accountPassword: string;
}

export interface ModalAddAccountProps {
initialData?: ModalAddAccountInitialData;
onClose: () => void;
onConfirm: (data: ModalAddAccountConfirmData) => void;
}

export const ModalAddAccount: React.FC<ModalAddAccountProps> = (
props: ModalAddAccountProps
): ReactNode => {
const { initialData, onClose, onConfirm } = props;

const form = useForm<ModalAddAccountConfirmData>();

useEffect(() => {
form.reset(initialData);
}, [form, initialData]);

const onModalClose = useCallback(
(_event?: React.UIEvent) => {
onClose();
},
[onClose]
);

const onModalConfirm = useCallback(
(event: React.UIEvent) => {
runInBackground(async () => {
const handler = form.handleSubmit(
(data: ModalAddAccountConfirmData) => {
onConfirm(data);
}
);
await handler(event);
});
},
[form, onConfirm]
);

return (
<EuiConfirmModal
title="Add Account"
onCancel={onModalClose}
onConfirm={onModalConfirm}
cancelButtonText="Cancel"
confirmButtonText="Save"
buttonColor="primary"
>
<EuiForm component="form">
<EuiFormRow
label="Name"
isInvalid={!!form.formState.errors.accountName}
>
<Controller
name="accountName"
control={form.control}
rules={{ required: true }}
render={({ field, fieldState }) => {
return (
<EuiFieldText
name={field.name}
defaultValue={field.value}
onBlur={field.onBlur}
onChange={field.onChange}
isInvalid={fieldState.invalid}
autoFocus={true}
/>
);
}}
/>
</EuiFormRow>
<EuiFormRow
label="Password"
isInvalid={!!form.formState.errors.accountPassword}
>
<Controller
name="accountPassword"
control={form.control}
rules={{ required: true }}
render={({ field, fieldState }) => {
return (
<EuiFieldPassword
name={field.name}
defaultValue={field.value}
onBlur={field.onBlur}
onChange={field.onChange}
isInvalid={fieldState.invalid}
type="dual"
/>
);
}}
/>
</EuiFormRow>
</EuiForm>
</EuiConfirmModal>
);
};

ModalAddAccount.displayName = 'ModalAddAccount';
121 changes: 121 additions & 0 deletions electron/renderer/components/sidebar/accounts/modal-edit-account.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {
EuiConfirmModal,
EuiFieldPassword,
EuiFieldText,
EuiForm,
EuiFormRow,
} from '@elastic/eui';
import { useCallback, useEffect } from 'react';
import type { ReactNode } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { runInBackground } from '../../../lib/async/run-in-background.js';

export interface ModalEditAccountInitialData {
accountName: string;
accountPassword?: string;
}

export interface ModalEditAccountConfirmData {
accountName: string;
accountPassword: string;
}

export interface ModalEditAccountProps {
initialData: Partial<ModalEditAccountInitialData>;
onClose: () => void;
onConfirm: (data: ModalEditAccountConfirmData) => void;
}

export const ModalEditAccount: React.FC<ModalEditAccountProps> = (
props: ModalEditAccountProps
): ReactNode => {
const { initialData = {}, onClose, onConfirm } = props;

const form = useForm<ModalEditAccountConfirmData>();

useEffect(() => {
form.reset(initialData);
}, [form, initialData]);

const onModalClose = useCallback(
(_event?: React.UIEvent) => {
onClose();
},
[onClose]
);

const onModalConfirm = useCallback(
(event: React.UIEvent) => {
runInBackground(async () => {
const handler = form.handleSubmit(
(data: ModalEditAccountConfirmData) => {
onConfirm(data);
}
);
await handler(event);
});
},
[form, onConfirm]
);

return (
<EuiConfirmModal
title="Change Password"
onCancel={onModalClose}
onConfirm={onModalConfirm}
cancelButtonText="Cancel"
confirmButtonText="Save"
buttonColor="primary"
>
<EuiForm component="form">
<EuiFormRow
label="Name"
isInvalid={!!form.formState.errors.accountName}
>
<Controller
name="accountName"
control={form.control}
rules={{ required: true }}
render={({ field, fieldState }) => {
return (
<EuiFieldText
name={field.name}
defaultValue={field.value}
onBlur={field.onBlur}
onChange={field.onChange}
isInvalid={fieldState.invalid}
disabled={true}
/>
);
}}
/>
</EuiFormRow>
<EuiFormRow
label="Password"
isInvalid={!!form.formState.errors.accountPassword}
>
<Controller
name="accountPassword"
control={form.control}
rules={{ required: true }}
render={({ field, fieldState }) => {
return (
<EuiFieldPassword
name={field.name}
defaultValue={field.value}
onBlur={field.onBlur}
onChange={field.onChange}
isInvalid={fieldState.invalid}
autoFocus={true}
type="dual"
/>
);
}}
/>
</EuiFormRow>
</EuiForm>
</EuiConfirmModal>
);
};

ModalEditAccount.displayName = 'ModalEditAccount';
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { EuiConfirmModal } from '@elastic/eui';
import { type ReactNode, useCallback } from 'react';
import { useListCharacters } from '../../../hooks/list-characters.jsx';

export interface ModalRemoveAccountInitialData {
accountName: string;
}

export interface ModalRemoveAccountConfirmData {
accountName: string;
}

export interface ModalRemoveAccountProps {
initialData: ModalRemoveAccountInitialData;
onClose: () => void;
onConfirm: (data: ModalRemoveAccountConfirmData) => void;
}

export const ModalRemoveAccount: React.FC<ModalRemoveAccountProps> = (
props: ModalRemoveAccountProps
): ReactNode => {
const { initialData, onClose, onConfirm } = props;

const characters = useListCharacters({
accountName: initialData.accountName,
});

const onModalClose = useCallback(
(_event?: React.UIEvent) => {
onClose();
},
[onClose]
);

const onModalConfirm = useCallback(
(_event: React.UIEvent) => {
onConfirm({ accountName: initialData.accountName });
},
[initialData, onConfirm]
);

return (
<EuiConfirmModal
title={<>Log out of account {initialData.accountName}?</>}
onCancel={onModalClose}
onConfirm={onModalConfirm}
cancelButtonText="Cancel"
confirmButtonText="Log out"
buttonColor="danger"
defaultFocusedButton="cancel"
>
Associated characters will also be removed.
<ul>
{characters.map(({ characterName }) => {
return <li key={characterName}>{characterName}</li>;
})}
</ul>
</EuiConfirmModal>
);
};

ModalRemoveAccount.displayName = 'ModalRemoveAccount';
Loading

0 comments on commit 6eb92e0

Please sign in to comment.