diff options
| author | Sebastian <sebasjm@gmail.com> | 2022-12-09 12:07:01 -0300 | 
|---|---|---|
| committer | Sebastian <sebasjm@gmail.com> | 2022-12-09 12:07:01 -0300 | 
| commit | 6b6f80466ee07f591203c28a724ce4e7128af85d (patch) | |
| tree | 4460721b74245625fe70443d466da677362abf1d /packages/demobank-ui/src/components | |
| parent | f2b319921c53010446e05ac4f24eef9995f65836 (diff) | |
remove unused
Diffstat (limited to 'packages/demobank-ui/src/components')
15 files changed, 0 insertions, 1584 deletions
diff --git a/packages/demobank-ui/src/components/AsyncButton.tsx b/packages/demobank-ui/src/components/AsyncButton.tsx deleted file mode 100644 index 0e1391109..000000000 --- a/packages/demobank-ui/src/components/AsyncButton.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { ComponentChildren, h, VNode } from "preact"; -import { useLayoutEffect, useRef } from "preact/hooks"; -import { useAsync } from "../hooks/async.js"; - -type Props = { -  children: ComponentChildren; -  disabled?: boolean; -  onClick?: () => Promise<void>; -  grabFocus?: boolean; -  [rest: string]: any; -}; - -export function AsyncButton({ -  onClick, -  grabFocus, -  disabled, -  children, -  ...rest -}: Props): VNode { -  const { isLoading, request } = useAsync(onClick); - -  const buttonRef = useRef<HTMLButtonElement>(null); -  useLayoutEffect(() => { -    if (grabFocus) buttonRef.current?.focus(); -  }, [grabFocus]); - -  // if (isSlow) { -  //   return <LoadingModal onCancel={cancel} />; -  // } -  if (isLoading) return <button class="button">Loading...</button>; - -  return ( -    <span data-tooltip={rest["data-tooltip"]} style={{ marginLeft: 5 }}> -      <button {...rest} ref={buttonRef} onClick={request} disabled={disabled}> -        {children} -      </button> -    </span> -  ); -} diff --git a/packages/demobank-ui/src/components/FileButton.tsx b/packages/demobank-ui/src/components/FileButton.tsx deleted file mode 100644 index d7ed52f5d..000000000 --- a/packages/demobank-ui/src/components/FileButton.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useRef, useState } from "preact/hooks"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export interface FileTypeContent { -  content: string; -  type: string; -  name: string; -} - -interface Props { -  label: string; -  onChange: (v: FileTypeContent | undefined) => void; -} -export function FileButton(props: Props): VNode { -  const fileInputRef = useRef<HTMLInputElement>(null); -  const [sizeError, setSizeError] = useState(false); -  return ( -    <div> -      <button class="button" onClick={(e) => fileInputRef.current?.click()}> -        <span>{props.label}</span> -      </button> -      <input -        ref={fileInputRef} -        style={{ display: "none" }} -        type="file" -        onChange={(e) => { -          const f: FileList | null = e.currentTarget.files; -          if (!f || f.length != 1) return props.onChange(undefined); - -          if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { -            setSizeError(true); -            return props.onChange(undefined); -          } -          setSizeError(false); -          return f[0].arrayBuffer().then((b) => { -            const content = new Uint8Array(b).reduce( -              (data, byte) => data + String.fromCharCode(byte), -              "", -            ); -            return props.onChange({ -              content, -              name: f[0].name, -              type: f[0].type, -            }); -          }); -        }} -      /> -      {sizeError && ( -        <p class="help is-danger">File should be smaller than 1 MB</p> -      )} -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/Notifications.tsx b/packages/demobank-ui/src/components/Notifications.tsx deleted file mode 100644 index 6dd3a2d50..000000000 --- a/packages/demobank-ui/src/components/Notifications.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; - -export interface Notification { -  message: string; -  description?: string | VNode; -  type: MessageType; -} - -export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS"; - -interface Props { -  notifications: Notification[]; -  removeNotification?: (n: Notification) => void; -} - -function messageStyle(type: MessageType): string { -  switch (type) { -    case "INFO": -      return "message is-info"; -    case "WARN": -      return "message is-warning"; -    case "ERROR": -      return "message is-danger"; -    case "SUCCESS": -      return "message is-success"; -    default: -      return "message"; -  } -} - -export function Notifications({ -  notifications, -  removeNotification, -}: Props): VNode { -  return ( -    <div class="block"> -      {notifications.map((n, i) => ( -        <article key={i} class={messageStyle(n.type)}> -          <div class="message-header"> -            <p>{n.message}</p> -            {removeNotification && ( -              <button -                class="delete" -                onClick={() => removeNotification && removeNotification(n)} -              /> -            )} -          </div> -          {n.description && <div class="message-body">{n.description}</div>} -        </article> -      ))} -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/fields/DateInput.tsx b/packages/demobank-ui/src/components/fields/DateInput.tsx deleted file mode 100644 index 0eeb1b2fd..000000000 --- a/packages/demobank-ui/src/components/fields/DateInput.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { format, subYears } from "date-fns"; -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; -import { DatePicker } from "../picker/DatePicker.js"; - -export interface DateInputProps { -  label: string; -  grabFocus?: boolean; -  tooltip?: string; -  error?: string; -  years?: Array<number>; -  onConfirm?: () => void; -  bind: [string, (x: string) => void]; -} - -export function DateInput(props: DateInputProps): VNode { -  const inputRef = useRef<HTMLInputElement>(null); -  useLayoutEffect(() => { -    if (props.grabFocus) inputRef.current?.focus(); -  }, [props.grabFocus]); -  const [opened, setOpened] = useState(false); - -  const value = props.bind[0] || ""; -  const [dirty, setDirty] = useState(false); -  const showError = dirty && props.error; - -  const calendar = subYears(new Date(), 30); - -  return ( -    <div class="field"> -      <label class="label"> -        {props.label} -        {props.tooltip && ( -          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> -            <i class="mdi mdi-information" /> -          </span> -        )} -      </label> -      <div class="control"> -        <div class="field has-addons"> -          <p class="control"> -            <input -              type="text" -              class={showError ? "input is-danger" : "input"} -              value={value} -              onKeyPress={(e) => { -                if (e.key === "Enter" && props.onConfirm) props.onConfirm(); -              }} -              onInput={(e) => { -                const text = e.currentTarget.value; -                setDirty(true); -                props.bind[1](text); -              }} -              ref={inputRef} -            /> -          </p> -          <p class="control"> -            <a -              class="button" -              onClick={() => { -                setOpened(true); -              }} -            > -              <span class="icon"> -                <i class="mdi mdi-calendar" /> -              </span> -            </a> -          </p> -        </div> -      </div> -      <p class="help">Using the format yyyy-mm-dd</p> -      {showError && <p class="help is-danger">{props.error}</p>} -      <DatePicker -        opened={opened} -        initialDate={calendar} -        years={props.years} -        closeFunction={() => setOpened(false)} -        dateReceiver={(d) => { -          setDirty(true); -          const v = format(d, "yyyy-MM-dd"); -          props.bind[1](v); -        }} -      /> -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/fields/EmailInput.tsx b/packages/demobank-ui/src/components/fields/EmailInput.tsx deleted file mode 100644 index 9f6624aa5..000000000 --- a/packages/demobank-ui/src/components/fields/EmailInput.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -export interface TextInputProps { -  label: string; -  grabFocus?: boolean; -  error?: string; -  placeholder?: string; -  tooltip?: string; -  onConfirm?: () => void; -  bind: [string, (x: string) => void]; -} - -export function EmailInput(props: TextInputProps): VNode { -  const inputRef = useRef<HTMLInputElement>(null); -  useLayoutEffect(() => { -    if (props.grabFocus) inputRef.current?.focus(); -  }, [props.grabFocus]); -  const value = props.bind[0]; -  const [dirty, setDirty] = useState(false); -  const showError = dirty && props.error; -  return ( -    <div class="field"> -      <label class="label"> -        {props.label} -        {props.tooltip && ( -          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> -            <i class="mdi mdi-information" /> -          </span> -        )} -      </label> -      <div class="control has-icons-right"> -        <input -          value={value} -          required -          placeholder={props.placeholder} -          type="email" -          class={showError ? "input is-danger" : "input"} -          onKeyPress={(e) => { -            if (e.key === "Enter" && props.onConfirm) props.onConfirm(); -          }} -          onInput={(e) => { -            setDirty(true); -            props.bind[1]((e.target as HTMLInputElement).value); -          }} -          ref={inputRef} -          style={{ display: "block" }} -        /> -      </div> -      {showError && <p class="help is-danger">{props.error}</p>} -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/fields/FileInput.tsx b/packages/demobank-ui/src/components/fields/FileInput.tsx deleted file mode 100644 index cc49a632d..000000000 --- a/packages/demobank-ui/src/components/fields/FileInput.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export interface FileTypeContent { -  content: string; -  type: string; -  name: string; -} - -export interface FileInputProps { -  label: string; -  grabFocus?: boolean; -  disabled?: boolean; -  error?: string; -  placeholder?: string; -  tooltip?: string; -  onChange: (v: FileTypeContent | undefined) => void; -} - -export function FileInput(props: FileInputProps): VNode { -  const inputRef = useRef<HTMLInputElement>(null); -  useLayoutEffect(() => { -    if (props.grabFocus) inputRef.current?.focus(); -  }, [props.grabFocus]); - -  const fileInputRef = useRef<HTMLInputElement>(null); -  const [sizeError, setSizeError] = useState(false); -  return ( -    <div class="field"> -      <label class="label"> -        <a class="button" onClick={(e) => fileInputRef.current?.click()}> -          <div class="icon is-small "> -            <i class="mdi mdi-folder" /> -          </div> -          <span>{props.label}</span> -        </a> -        {props.tooltip && ( -          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> -            <i class="mdi mdi-information" /> -          </span> -        )} -      </label> -      <div class="control"> -        <input -          ref={fileInputRef} -          style={{ display: "none" }} -          type="file" -          // name={String(name)} -          onChange={(e) => { -            const f: FileList | null = e.currentTarget.files; -            if (!f || f.length != 1) return props.onChange(undefined); - -            if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { -              setSizeError(true); -              return props.onChange(undefined); -            } -            setSizeError(false); -            return f[0].arrayBuffer().then((b) => { -              const b64 = btoa( -                new Uint8Array(b).reduce( -                  (data, byte) => data + String.fromCharCode(byte), -                  "", -                ), -              ); -              return props.onChange({ -                content: `data:${f[0].type};base64,${b64}`, -                name: f[0].name, -                type: f[0].type, -              }); -            }); -          }} -        /> -        {props.error && <p class="help is-danger">{props.error}</p>} -        {sizeError && ( -          <p class="help is-danger">File should be smaller than 1 MB</p> -        )} -      </div> -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/fields/ImageInput.tsx b/packages/demobank-ui/src/components/fields/ImageInput.tsx deleted file mode 100644 index 15b25f1c2..000000000 --- a/packages/demobank-ui/src/components/fields/ImageInput.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; -import emptyImage from "../../assets/empty.png"; -import { TextInputProps } from "./TextInput.js"; - -const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024; - -export function ImageInput(props: TextInputProps): VNode { -  const inputRef = useRef<HTMLInputElement>(null); -  useLayoutEffect(() => { -    if (props.grabFocus) inputRef.current?.focus(); -  }, [props.grabFocus]); - -  const value = props.bind[0]; -  // const [dirty, setDirty] = useState(false) -  const image = useRef<HTMLInputElement>(null); -  const [sizeError, setSizeError] = useState(false); -  function onChange(v: string): void { -    // setDirty(true); -    props.bind[1](v); -  } -  return ( -    <div class="field"> -      <label class="label"> -        {props.label} -        {props.tooltip && ( -          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> -            <i class="mdi mdi-information" /> -          </span> -        )} -      </label> -      <div class="control"> -        <img -          src={!value ? emptyImage : value} -          style={{ width: 200, height: 200 }} -          onClick={() => image.current?.click()} -        /> -        <input -          ref={image} -          style={{ display: "none" }} -          type="file" -          name={String(name)} -          onChange={(e) => { -            const f: FileList | null = e.currentTarget.files; -            if (!f || f.length != 1) return onChange(emptyImage); - -            if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) { -              setSizeError(true); -              return onChange(emptyImage); -            } -            setSizeError(false); -            return f[0].arrayBuffer().then((b) => { -              const b64 = btoa( -                new Uint8Array(b).reduce( -                  (data, byte) => data + String.fromCharCode(byte), -                  "", -                ), -              ); -              return onChange(`data:${f[0].type};base64,${b64}` as any); -            }); -          }} -        /> -        {props.error && <p class="help is-danger">{props.error}</p>} -        {sizeError && ( -          <p class="help is-danger">Image should be smaller than 1 MB</p> -        )} -      </div> -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/fields/NumberInput.tsx b/packages/demobank-ui/src/components/fields/NumberInput.tsx deleted file mode 100644 index 69af18c77..000000000 --- a/packages/demobank-ui/src/components/fields/NumberInput.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -export interface TextInputProps { -  label: string; -  grabFocus?: boolean; -  error?: string; -  placeholder?: string; -  tooltip?: string; -  onConfirm?: () => void; -  bind: [string, (x: string) => void]; -} - -export function PhoneNumberInput(props: TextInputProps): VNode { -  const inputRef = useRef<HTMLInputElement>(null); -  useLayoutEffect(() => { -    if (props.grabFocus) inputRef.current?.focus(); -  }, [props.grabFocus]); -  const value = props.bind[0]; -  const [dirty, setDirty] = useState(false); -  const showError = dirty && props.error; -  return ( -    <div class="field"> -      <label class="label"> -        {props.label} -        {props.tooltip && ( -          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> -            <i class="mdi mdi-information" /> -          </span> -        )} -      </label> -      <div class="control has-icons-right"> -        <input -          value={value} -          type="tel" -          placeholder={props.placeholder} -          class={showError ? "input is-danger" : "input"} -          onKeyPress={(e) => { -            if (e.key === "Enter" && props.onConfirm) props.onConfirm(); -          }} -          onInput={(e) => { -            setDirty(true); -            props.bind[1]((e.target as HTMLInputElement).value); -          }} -          ref={inputRef} -          style={{ display: "block" }} -        /> -      </div> -      {showError && <p class="help is-danger">{props.error}</p>} -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/fields/TextInput.tsx b/packages/demobank-ui/src/components/fields/TextInput.tsx deleted file mode 100644 index 5c6fe3157..000000000 --- a/packages/demobank-ui/src/components/fields/TextInput.tsx +++ /dev/null @@ -1,80 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { h, VNode } from "preact"; -import { useLayoutEffect, useRef, useState } from "preact/hooks"; - -export interface TextInputProps { -  inputType?: "text" | "number" | "multiline" | "password"; -  label: string; -  grabFocus?: boolean; -  disabled?: boolean; -  error?: string; -  placeholder?: string; -  tooltip?: string; -  onConfirm?: () => void; -  bind: [string, (x: string) => void]; -} - -const TextInputType = function ({ inputType, grabFocus, ...rest }: any): VNode { -  const inputRef = useRef<HTMLInputElement>(null); -  useLayoutEffect(() => { -    if (grabFocus) inputRef.current?.focus(); -  }, [grabFocus]); - -  return inputType === "multiline" ? ( -    <textarea {...rest} rows={5} ref={inputRef} style={{ height: "unset" }} /> -  ) : ( -    <input {...rest} type={inputType} ref={inputRef} /> -  ); -}; - -export function TextInput(props: TextInputProps): VNode { -  const value = props.bind[0]; -  const [dirty, setDirty] = useState(false); -  const showError = dirty && props.error; -  return ( -    <div class="field"> -      <label class="label"> -        {props.label} -        {props.tooltip && ( -          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}> -            <i class="mdi mdi-information" /> -          </span> -        )} -      </label> -      <div class="control has-icons-right"> -        <TextInputType -          inputType={props.inputType} -          value={value} -          grabFocus={props.grabFocus} -          disabled={props.disabled} -          placeholder={props.placeholder} -          class={showError ? "input is-danger" : "input"} -          onKeyPress={(e: any) => { -            if (e.key === "Enter" && props.onConfirm) props.onConfirm(); -          }} -          onInput={(e: any) => { -            setDirty(true); -            props.bind[1]((e.target as HTMLInputElement).value); -          }} -          style={{ display: "block" }} -        /> -      </div> -      {showError && <p class="help is-danger">{props.error}</p>} -    </div> -  ); -} diff --git a/packages/demobank-ui/src/components/menu/NavigationBar.tsx b/packages/demobank-ui/src/components/menu/NavigationBar.tsx deleted file mode 100644 index 5c57d2c95..000000000 --- a/packages/demobank-ui/src/components/menu/NavigationBar.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; - -interface Props { -  onMobileMenu: () => void; -  title: string; -} - -export function NavigationBar({ onMobileMenu, title }: Props): VNode { -  return ( -    <nav -      class="navbar is-fixed-top" -      role="navigation" -      aria-label="main navigation" -    > -      <div class="navbar-brand"> -        <span class="navbar-item" style={{ fontSize: 24, fontWeight: 900 }}> -          {title} -        </span> -      </div> - -      <div class="navbar-menu "> -        <div class="navbar-end"> -          <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}> -            {/* <LangSelector /> */} -          </div> -        </div> -      </div> -    </nav> -  ); -} diff --git a/packages/demobank-ui/src/components/menu/SideBar.tsx b/packages/demobank-ui/src/components/menu/SideBar.tsx deleted file mode 100644 index 32fe216ab..000000000 --- a/packages/demobank-ui/src/components/menu/SideBar.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; -import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; - -interface Props { -  mobile?: boolean; -} - -export function Sidebar({ mobile }: Props): VNode { -  // const config = useConfigContext(); -  const config = { version: "none" }; -  // FIXME: add replacement for __VERSION__ with the current version -  const process = { env: { __VERSION__: "0.0.0" } }; -  const { i18n } = useTranslationContext(); - -  return ( -    <aside class="aside is-placed-left is-expanded"> -      <div class="aside-tools"> -        <div class="aside-tools-label"> -          <div> -            <b>euFin bank</b> -          </div> -          <div -            class="is-size-7 has-text-right" -            style={{ lineHeight: 0, marginTop: -10 }} -          > -            Version {process.env.__VERSION__} ({config.version}) -          </div> -        </div> -      </div> -      <div class="menu is-menu-main"> -        <p class="menu-label"> -          <i18n.Translate>Bank menu</i18n.Translate> -        </p> -        <ul class="menu-list"> -          <li> -            <div class="ml-4"> -              <span class="menu-item-label"> -                <i18n.Translate>Select option1</i18n.Translate> -              </span> -            </div> -          </li> -          <li> -            <div class="ml-4"> -              <span class="menu-item-label"> -                <i18n.Translate>Select option2</i18n.Translate> -              </span> -            </div> -          </li> -        </ul> -      </div> -    </aside> -  ); -} diff --git a/packages/demobank-ui/src/components/menu/index.tsx b/packages/demobank-ui/src/components/menu/index.tsx deleted file mode 100644 index c0a845a62..000000000 --- a/packages/demobank-ui/src/components/menu/index.tsx +++ /dev/null @@ -1,135 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -import { ComponentChildren, Fragment, h, VNode } from "preact"; -import Match from "preact-router/match"; -import { useEffect, useState } from "preact/hooks"; -import { NavigationBar } from "./NavigationBar.js"; -import { Sidebar } from "./SideBar.js"; - -interface MenuProps { -  title: string; -} - -function WithTitle({ -  title, -  children, -}: { -  title: string; -  children: ComponentChildren; -}): VNode { -  useEffect(() => { -    document.title = `${title}`; -  }, [title]); -  return <Fragment>{children}</Fragment>; -} - -export function Menu({ title }: MenuProps): VNode { -  const [mobileOpen, setMobileOpen] = useState(false); - -  return ( -    <Match> -      {({ path }: { path: string }) => { -        const titleWithSubtitle = title; // title ? title : (!admin ? getInstanceTitle(path, instance) : getAdminTitle(path, instance)) -        return ( -          <WithTitle title={titleWithSubtitle}> -            <div -              class={mobileOpen ? "has-aside-mobile-expanded" : ""} -              onClick={() => setMobileOpen(false)} -            > -              <NavigationBar -                onMobileMenu={() => setMobileOpen(!mobileOpen)} -                title={titleWithSubtitle} -              /> - -              <Sidebar mobile={mobileOpen} /> -            </div> -          </WithTitle> -        ); -      }} -    </Match> -  ); -} - -interface NotYetReadyAppMenuProps { -  title: string; -  onLogout?: () => void; -} - -interface NotifProps { -  notification?: Notification; -} -export function NotificationCard({ -  notification: n, -}: NotifProps): VNode | null { -  if (!n) return null; -  return ( -    <div class="notification"> -      <div class="columns is-vcentered"> -        <div class="column is-12"> -          <article -            class={ -              n.type === "ERROR" -                ? "message is-danger" -                : n.type === "WARN" -                ? "message is-warning" -                : "message is-info" -            } -          > -            <div class="message-header"> -              <p>{n.message}</p> -            </div> -            {n.description && <div class="message-body">{n.description}</div>} -          </article> -        </div> -      </div> -    </div> -  ); -} - -export function NotYetReadyAppMenu({ -  onLogout, -  title, -}: NotYetReadyAppMenuProps): VNode { -  const [mobileOpen, setMobileOpen] = useState(false); - -  useEffect(() => { -    document.title = `Taler Backoffice: ${title}`; -  }, [title]); - -  return ( -    <div -      class="has-aside-mobile-expanded" -      // class={mobileOpen ? "has-aside-mobile-expanded" : ""} -      onClick={() => setMobileOpen(false)} -    > -      <NavigationBar -        onMobileMenu={() => setMobileOpen(!mobileOpen)} -        title={title} -      /> -      {onLogout && <Sidebar mobile={mobileOpen} />} -    </div> -  ); -} - -export interface Notification { -  message: string; -  description?: string | VNode; -  type: MessageType; -} - -export type ValueOrFunction<T> = T | ((p: T) => T); -export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS"; diff --git a/packages/demobank-ui/src/components/picker/DatePicker.tsx b/packages/demobank-ui/src/components/picker/DatePicker.tsx deleted file mode 100644 index 0a93144ec..000000000 --- a/packages/demobank-ui/src/components/picker/DatePicker.tsx +++ /dev/null @@ -1,347 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, Component } from "preact"; - -interface Props { -  closeFunction?: () => void; -  dateReceiver?: (d: Date) => void; -  initialDate?: Date; -  years?: Array<number>; -  opened?: boolean; -} -interface State { -  displayedMonth: number; -  displayedYear: number; -  selectYearMode: boolean; -  currentDate: Date; -} -const now = new Date(); - -const monthArrShortFull = [ -  "January", -  "February", -  "March", -  "April", -  "May", -  "June", -  "July", -  "August", -  "September", -  "October", -  "November", -  "December", -]; - -const monthArrShort = [ -  "Jan", -  "Feb", -  "Mar", -  "Apr", -  "May", -  "Jun", -  "Jul", -  "Aug", -  "Sep", -  "Oct", -  "Nov", -  "Dec", -]; - -const dayArr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - -const yearArr: number[] = []; - -// inspired by https://codepen.io/m4r1vs/pen/MOOxyE -export class DatePicker extends Component<Props, State> { -  closeDatePicker() { -    this.props.closeFunction && this.props.closeFunction(); // Function gets passed by parent -  } - -  /** -   * Gets fired when a day gets clicked. -   * @param {object} e The event thrown by the <span /> element clicked -   */ -  dayClicked(e: any) { -    const element = e.target; // the actual element clicked - -    if (element.innerHTML === "") return false; // don't continue if <span /> empty - -    // get date from clicked element (gets attached when rendered) -    const date = new Date(element.getAttribute("data-value")); - -    // update the state -    this.setState({ currentDate: date }); -    this.passDateToParent(date); -  } - -  /** -   * returns days in month as array -   * @param {number} month the month to display -   * @param {number} year the year to display -   */ -  getDaysByMonth(month: number, year: number) { -    const calendar = []; - -    const date = new Date(year, month, 1); // month to display - -    const firstDay = new Date(year, month, 1).getDay(); // first weekday of month -    const lastDate = new Date(year, month + 1, 0).getDate(); // last date of month - -    let day: number | null = 0; - -    // the calendar is 7*6 fields big, so 42 loops -    for (let i = 0; i < 42; i++) { -      if (i >= firstDay && day !== null) day = day + 1; -      if (day !== null && day > lastDate) day = null; - -      // append the calendar Array -      calendar.push({ -        day: day === 0 || day === null ? null : day, // null or number -        date: day === 0 || day === null ? null : new Date(year, month, day), // null or Date() -        today: -          day === now.getDate() && -          month === now.getMonth() && -          year === now.getFullYear(), // boolean -      }); -    } - -    return calendar; -  } - -  /** -   * Display previous month by updating state -   */ -  displayPrevMonth() { -    if (this.state.displayedMonth <= 0) -      this.setState({ -        displayedMonth: 11, -        displayedYear: this.state.displayedYear - 1, -      }); -    else -      this.setState({ -        displayedMonth: this.state.displayedMonth - 1, -      }); -  } - -  /** -   * Display next month by updating state -   */ -  displayNextMonth() { -    if (this.state.displayedMonth >= 11) -      this.setState({ -        displayedMonth: 0, -        displayedYear: this.state.displayedYear + 1, -      }); -    else -      this.setState({ -        displayedMonth: this.state.displayedMonth + 1, -      }); -  } - -  /** -   * Display the selected month (gets fired when clicking on the date string) -   */ -  displaySelectedMonth() { -    if (this.state.selectYearMode) this.toggleYearSelector(); -    else { -      if (!this.state.currentDate) return false; -      this.setState({ -        displayedMonth: this.state.currentDate.getMonth(), -        displayedYear: this.state.currentDate.getFullYear(), -      }); -    } -  } - -  toggleYearSelector() { -    this.setState({ selectYearMode: !this.state.selectYearMode }); -  } - -  changeDisplayedYear(e: any) { -    const element = e.target; -    this.toggleYearSelector(); -    this.setState({ -      displayedYear: parseInt(element.innerHTML, 10), -      displayedMonth: 0, -    }); -  } - -  /** -   * Pass the selected date to parent when 'OK' is clicked -   */ -  passSavedDateDateToParent() { -    this.passDateToParent(this.state.currentDate); -  } -  passDateToParent(date: Date) { -    if (typeof this.props.dateReceiver === "function") -      this.props.dateReceiver(date); -    this.closeDatePicker(); -  } - -  componentDidUpdate() { -    // if (this.state.selectYearMode) { -    //   document.getElementsByClassName('selected')[0].scrollIntoView(); // works in every browser incl. IE, replace with scrollIntoViewIfNeeded when browsers support it -    // } -  } - -  constructor(props: any) { -    super(props); - -    this.closeDatePicker = this.closeDatePicker.bind(this); -    this.dayClicked = this.dayClicked.bind(this); -    this.displayNextMonth = this.displayNextMonth.bind(this); -    this.displayPrevMonth = this.displayPrevMonth.bind(this); -    this.getDaysByMonth = this.getDaysByMonth.bind(this); -    this.changeDisplayedYear = this.changeDisplayedYear.bind(this); -    this.passDateToParent = this.passDateToParent.bind(this); -    this.toggleYearSelector = this.toggleYearSelector.bind(this); -    this.displaySelectedMonth = this.displaySelectedMonth.bind(this); - -    const initial = props.initialDate || now; - -    this.state = { -      currentDate: initial, -      displayedMonth: initial.getMonth(), -      displayedYear: initial.getFullYear(), -      selectYearMode: false, -    }; -  } - -  render() { -    const { currentDate, displayedMonth, displayedYear, selectYearMode } = -      this.state; - -    return ( -      <div> -        <div class={`datePicker ${this.props.opened && "datePicker--opened"}`}> -          <div class="datePicker--titles"> -            <h3 -              style={{ -                color: selectYearMode -                  ? "rgba(255,255,255,.87)" -                  : "rgba(255,255,255,.57)", -              }} -              onClick={this.toggleYearSelector} -            > -              {currentDate.getFullYear()} -            </h3> -            <h2 -              style={{ -                color: !selectYearMode -                  ? "rgba(255,255,255,.87)" -                  : "rgba(255,255,255,.57)", -              }} -              onClick={this.displaySelectedMonth} -            > -              {dayArr[currentDate.getDay()]},{" "} -              {monthArrShort[currentDate.getMonth()]} {currentDate.getDate()} -            </h2> -          </div> - -          {!selectYearMode && ( -            <nav> -              <span onClick={this.displayPrevMonth} class="icon"> -                <i -                  style={{ transform: "rotate(180deg)" }} -                  class="mdi mdi-forward" -                /> -              </span> -              <h4> -                {monthArrShortFull[displayedMonth]} {displayedYear} -              </h4> -              <span onClick={this.displayNextMonth} class="icon"> -                <i class="mdi mdi-forward" /> -              </span> -            </nav> -          )} - -          <div class="datePicker--scroll"> -            {!selectYearMode && ( -              <div class="datePicker--calendar"> -                <div class="datePicker--dayNames"> -                  {["S", "M", "T", "W", "T", "F", "S"].map((day, i) => ( -                    <span key={i}>{day}</span> -                  ))} -                </div> - -                <div onClick={this.dayClicked} class="datePicker--days"> -                  {/* -                  Loop through the calendar object returned by getDaysByMonth(). -                */} - -                  {this.getDaysByMonth( -                    this.state.displayedMonth, -                    this.state.displayedYear, -                  ).map((day) => { -                    let selected = false; - -                    if (currentDate && day.date) -                      selected = -                        currentDate.toLocaleDateString() === -                        day.date.toLocaleDateString(); - -                    return ( -                      <span -                        key={day.day} -                        class={ -                          (day.today ? "datePicker--today " : "") + -                          (selected ? "datePicker--selected" : "") -                        } -                        disabled={!day.date} -                        data-value={day.date} -                      > -                        {day.day} -                      </span> -                    ); -                  })} -                </div> -              </div> -            )} - -            {selectYearMode && ( -              <div class="datePicker--selectYear"> -                {(this.props.years || yearArr).map((year) => ( -                  <span -                    key={year} -                    class={year === displayedYear ? "selected" : ""} -                    onClick={this.changeDisplayedYear} -                  > -                    {year} -                  </span> -                ))} -              </div> -            )} -          </div> -        </div> - -        <div -          class="datePicker--background" -          onClick={this.closeDatePicker} -          style={{ -            display: this.props.opened ? "block" : "none", -          }} -        /> -      </div> -    ); -  } -} - -for (let i = 2010; i <= now.getFullYear() + 10; i++) yearArr.push(i); diff --git a/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx b/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx deleted file mode 100644 index db417b949..000000000 --- a/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, FunctionalComponent } from "preact"; -import { useState } from "preact/hooks"; -import { DurationPicker as TestedComponent } from "./DurationPicker.js"; - -export default { -  title: "Components/Picker/Duration", -  component: TestedComponent, -  argTypes: { -    onCreate: { action: "onCreate" }, -    goBack: { action: "goBack" }, -  }, -}; - -function createExample<Props>( -  Component: FunctionalComponent<Props>, -  props: Partial<Props>, -) { -  const r = (args: any) => <Component {...args} />; -  r.args = props; -  return r; -} - -export const Example = createExample(TestedComponent, { -  days: true, -  minutes: true, -  hours: true, -  seconds: true, -  value: 10000000, -}); - -export const WithState = () => { -  const [v, s] = useState<number>(1000000); -  return <TestedComponent value={v} onChange={s} days minutes hours seconds />; -}; diff --git a/packages/demobank-ui/src/components/picker/DurationPicker.tsx b/packages/demobank-ui/src/components/picker/DurationPicker.tsx deleted file mode 100644 index 973f2f507..000000000 --- a/packages/demobank-ui/src/components/picker/DurationPicker.tsx +++ /dev/null @@ -1,210 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2022 Taler Systems S.A. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE.  See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -import { h, VNode } from "preact"; -import { useState } from "preact/hooks"; -import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; -import "../../scss/DurationPicker.scss"; - -export interface Props { -  hours?: boolean; -  minutes?: boolean; -  seconds?: boolean; -  days?: boolean; -  onChange: (value: number) => void; -  value: number; -} - -// inspiration taken from https://github.com/flurmbo/react-duration-picker -export function DurationPicker({ -  days, -  hours, -  minutes, -  seconds, -  onChange, -  value, -}: Props): VNode { -  const ss = 1000; -  const ms = ss * 60; -  const hs = ms * 60; -  const ds = hs * 24; -  const { i18n } = useTranslationContext(); - -  return ( -    <div class="rdp-picker"> -      {days && ( -        <DurationColumn -          unit={i18n.str`days`} -          max={99} -          value={Math.floor(value / ds)} -          onDecrease={value >= ds ? () => onChange(value - ds) : undefined} -          onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined} -          onChange={(diff) => onChange(value + diff * ds)} -        /> -      )} -      {hours && ( -        <DurationColumn -          unit={i18n.str`hours`} -          max={23} -          min={1} -          value={Math.floor(value / hs) % 24} -          onDecrease={value >= hs ? () => onChange(value - hs) : undefined} -          onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined} -          onChange={(diff) => onChange(value + diff * hs)} -        /> -      )} -      {minutes && ( -        <DurationColumn -          unit={i18n.str`minutes`} -          max={59} -          min={1} -          value={Math.floor(value / ms) % 60} -          onDecrease={value >= ms ? () => onChange(value - ms) : undefined} -          onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined} -          onChange={(diff) => onChange(value + diff * ms)} -        /> -      )} -      {seconds && ( -        <DurationColumn -          unit={i18n.str`seconds`} -          max={59} -          value={Math.floor(value / ss) % 60} -          onDecrease={value >= ss ? () => onChange(value - ss) : undefined} -          onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined} -          onChange={(diff) => onChange(value + diff * ss)} -        /> -      )} -    </div> -  ); -} - -interface ColProps { -  unit: string; -  min?: number; -  max: number; -  value: number; -  onIncrease?: () => void; -  onDecrease?: () => void; -  onChange?: (diff: number) => void; -} - -function InputNumber({ -  initial, -  onChange, -}: { -  initial: number; -  onChange: (n: number) => void; -}) { -  const [value, handler] = useState<{ v: string }>({ -    v: toTwoDigitString(initial), -  }); - -  return ( -    <input -      value={value.v} -      onBlur={(e) => onChange(parseInt(value.v, 10))} -      onInput={(e) => { -        e.preventDefault(); -        const n = Number.parseInt(e.currentTarget.value, 10); -        if (isNaN(n)) return handler({ v: toTwoDigitString(initial) }); -        return handler({ v: toTwoDigitString(n) }); -      }} -      style={{ -        width: 50, -        border: "none", -        fontSize: "inherit", -        background: "inherit", -      }} -    /> -  ); -} - -function DurationColumn({ -  unit, -  min = 0, -  max, -  value, -  onIncrease, -  onDecrease, -  onChange, -}: ColProps): VNode { -  const cellHeight = 35; -  return ( -    <div class="rdp-column-container"> -      <div class="rdp-masked-div"> -        <hr class="rdp-reticule" style={{ top: cellHeight * 2 - 1 }} /> -        <hr class="rdp-reticule" style={{ top: cellHeight * 3 - 1 }} /> - -        <div class="rdp-column" style={{ top: 0 }}> -          <div class="rdp-cell" key={value - 2}> -            {onDecrease && ( -              <button -                style={{ width: "100%", textAlign: "center", margin: 5 }} -                onClick={onDecrease} -              > -                <span class="icon"> -                  <i class="mdi mdi-chevron-up" /> -                </span> -              </button> -            )} -          </div> -          <div class="rdp-cell" key={value - 1}> -            {value > min ? toTwoDigitString(value - 1) : ""} -          </div> -          <div class="rdp-cell rdp-center" key={value}> -            {onChange ? ( -              <InputNumber -                initial={value} -                onChange={(n) => onChange(n - value)} -              /> -            ) : ( -              toTwoDigitString(value) -            )} -            <div>{unit}</div> -          </div> - -          <div class="rdp-cell" key={value + 1}> -            {value < max ? toTwoDigitString(value + 1) : ""} -          </div> - -          <div class="rdp-cell" key={value + 2}> -            {onIncrease && ( -              <button -                style={{ width: "100%", textAlign: "center", margin: 5 }} -                onClick={onIncrease} -              > -                <span class="icon"> -                  <i class="mdi mdi-chevron-down" /> -                </span> -              </button> -            )} -          </div> -        </div> -      </div> -    </div> -  ); -} - -function toTwoDigitString(n: number) { -  if (n < 10) return `0${n}`; - -  return `${n}`; -}  | 
