@fortawesome/free-solid-svg-icons#faQuestionCircle TypeScript Examples

The following examples show how to use @fortawesome/free-solid-svg-icons#faQuestionCircle. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: IconLibrary.ts    From react-memory-game with MIT License 6 votes vote down vote up
library.add(
  faChevronLeft,
  faPlay,
  faPause,
  faUndo,
  faClock,
  faQuestionCircle,
  faTimes,
  faPalette,

  // Icons for the game
  faPoo,
  faAnchor,
  faMoon,
  faAppleAlt,
  faBell,
  faBible,
  faBomb,
  faBone,
  faCar,
  faCat,
  faChess,
  faSkull,
  faFeatherAlt,
  faFire,
  faHeart,
  faMusic,
)
Example #2
Source File: tooltip.tsx    From advocacy-maps with MIT License 6 votes vote down vote up
QuestionTooltip = ({ text }: { text: string }) => {
  return (
    <OverlayTrigger
      placement="auto"
      overlay={
        <Tooltip id="tooltip-text">
          <p>{text}</p>
        </Tooltip>
      }
    >
      <span className="m-1">
        <FontAwesomeIcon icon={faQuestionCircle} className="text-secondary" />
      </span>
    </OverlayTrigger>
  )
}
Example #3
Source File: index.tsx    From resume-nextjs with MIT License 6 votes vote down vote up
function createTooltip(content?: string) {
  if (!content) {
    return '';
  }

  const [tooltipOpen, setTooltipOpen] = useState(false);
  const toggle = () => setTooltipOpen(!tooltipOpen);

  return (
    <small>
      {' '}
      <FontAwesomeIcon icon={faQuestionCircle} id="skill-tooltip" />
      <Tooltip
        style={{ whiteSpace: 'pre-wrap' }}
        placement="right"
        target="skill-tooltip"
        isOpen={tooltipOpen}
        toggle={toggle}
      >
        {content}
      </Tooltip>
    </small>
  );
}
Example #4
Source File: imagine-cu-dimensiuni-fixe.tsx    From frontend.ro with MIT License 5 votes vote down vote up
export default function FixedSizeImage() {
  const title = 'O imagine cu dimensiuni fixe';

  return (
    <>
      <Head>
        <title>
          {title}
          {' '}
          | DEMO - FrontEnd.ro
        </title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <>
        <Header demoPage withNavMenu />
        <Demo title={title}>
          <DemoPreview>
            <header className="d-flex align-items-center justify-content-between flex-row flex-wrap">
              <img
                height="70"
                width="212"
                src="/logo.png"
                alt="FrontEnd.ro logo"
              />
              <h2> Home </h2>
            </header>
          </DemoPreview>
          <Highlight
            className="my-5"
            language="html"
            code={`
<header style="
  display: flex; 
  justify-content: space-between; 
  align-items: center;
">
  <img 
    height="70"
    width="212" 
    src="https://FrontEnd.ro/logo.png" 
    alt="FrontEnd.ro logo" 
  />
  <h2> Home </h2>
</header>`}
          />
          <LessonTip icon={faQuestionCircle}>
            Atributul
            {' '}
            <strong>style</strong>
            {' '}
            este folosit pentru a stiliza elementele.
            {' '}
            Încă nu am ajuns la acel capitol deci nu-ți fă griji dacă nu înțelegi acel cod.
            <br />
            {' '}
            <br />
            Totuși va trebui să copii exemplul in intregime dacă vrei același rezultat.
          </LessonTip>
        </Demo>
        <Footer />
      </>
    </>
  );
}
Example #5
Source File: icon.tsx    From NetStatus with MIT License 5 votes vote down vote up
_initFontAwesome = () => {
    if ( _hasInitializedFontAwesome ) { return; }
    _hasInitializedFontAwesome = true;

    library.add(faCheckCircle, faPlug, faQuestionCircle, faExclamationTriangle, faWifi, faMapMarkerAlt, faClock);
}
Example #6
Source File: icon.tsx    From NetStatus with MIT License 5 votes vote down vote up
QuestionMarkCircle    = (styling={}) => ComponentForIconName(faQuestionCircle.iconName, '', styling)
Example #7
Source File: InfoComponent.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
export default function InfoComponent({ pageKey, text = "", modalTitle = "", children }: { pageKey: InfoShownPageKey, text: Displayable | Displayable[], modalTitle: Displayable, children: JSX.Element }) {
  const [stateInfoShown, setStateInfoShown] = useDBState("InfoShown", initialInfoShownState)
  const showInfoModal = stateInfoShown[pageKey]
  const setshowInfoModal = useCallback((value: boolean) => setStateInfoShown({ [pageKey]: value }), [setStateInfoShown, pageKey])

  const [displayText,] = useState(Array.isArray(text) ? getRandomElementFromArray(text) : text)
  const closeModal = () => setshowInfoModal(false)

  return <CardDark >
    <Grid container>
      <Grid item flexGrow={1}>
        <Typography variant="caption" pl={1} >
          {displayText}
        </Typography>
      </Grid>
      <Grid item xs="auto">
        <Button size="small" color="info" variant="contained" onClick={() => setshowInfoModal(true)} startIcon={<FontAwesomeIcon icon={faQuestionCircle} />}>
          <Translate ns="ui" key18="info" />
        </Button>
      </Grid>
    </Grid>
    <ModalWrapper containerProps={{ maxWidth: "xl" }} open={showInfoModal} onClose={() => closeModal()} >
      <CardDark >
        <CardContent sx={{ py: 1 }}>
          <Grid container>
            <Grid item flexGrow={1}>
              <Typography variant="h6">{modalTitle}</Typography>
            </Grid>
            <Grid item>
              <CloseButton onClick={closeModal} />
            </Grid>
          </Grid>
        </CardContent>
        <Divider />
        <CardContent>
          <Suspense fallback={<Skeleton variant="rectangular" width="100%" height={500} />}>
            {children}
          </Suspense>
        </CardContent>
        <Divider />
        <CardContent sx={{ py: 1 }}>
          <CloseButton large onClick={closeModal} />
        </CardContent>
      </CardDark>
    </ModalWrapper >
  </CardDark>
}
Example #8
Source File: QuestionTooltip.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
QuestionTooltip = ({ className, ...props }: ITooltipProps) =>
  <BootstrapTooltip placement="top" {...props} className={className}>
    <Box component="span" sx={{ cursor: "help" }}><FontAwesomeIcon icon={faQuestionCircle} /></Box>
  </BootstrapTooltip>
Example #9
Source File: SettingsConnection.tsx    From mysterium-vpn-desktop with MIT License 5 votes vote down vote up
TooltipIcon = styled(FontAwesomeIcon).attrs({
    icon: faQuestionCircle,
})`
    margin-left: 10px;
`
Example #10
Source File: OrderBreakdown.tsx    From mysterium-vpn-desktop with MIT License 5 votes vote down vote up
TooltipIcon = styled(FontAwesomeIcon).attrs({
    icon: faQuestionCircle,
})`
    margin-left: 10px;
`
Example #11
Source File: TutorOverview.tsx    From TutorBase with MIT License 4 votes vote down vote up
TutorOverview = () => {
    let tutorData = useSelector(selectTutorData);
    let dispatch = useDispatch();

    let [tooltipsOpen, setTooltipsOpen] = useState<Array<boolean>>([false, false, false, false, false, false, false]);
    let [weeklyAppointments, setWeeklyAppointments] = useState<Array<Appointment>>([]);
    let [tutorCourses, setTutorCourses] = useState<Array<Course>>([]);

    let daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    let currDate = useMemo(() => {return new Date()}, [])
    let currWeekMap = GetWeekMap(currDate);

    useEffect(() => {
        const getTutorAppointments = async () => {
            return (await api.GetTutorAppointments(tutorData.tutorId)).data;
        }

        getTutorAppointments().then(value => {
                setWeeklyAppointments(GetWeeklyAppointments(value, currDate));
                dispatch(tutorDataActions.setAppointment(value));
            }
        )
    }, [currDate, tutorData.tutorId, dispatch]);

    useEffect(() => {
        const getTutorCourses = async () => {
            return (await api.GetCoursesByTutorId(tutorData.tutorId)).data;
        }

        getTutorCourses().then(value => {
                setTutorCourses(value);
                dispatch(tutorDataActions.setCourses(value));
            }
        )
    }, [tutorData.tutorId, dispatch]);

    return (
        <Container className="overview" fluid>
            <Row className="title" style={{ marginTop: '25px'}}>
                <div className="profile-text">Overview</div>
            </Row>

            <hr></hr>

            <Row>
                <Col className="courses-col" md={6}>
                    <Row className="title" style={{ marginTop: '25px'}}>
                        <h2>Courses</h2>
                    </Row>
                    <Container className="table-container">
                        <Table className="table-striped">
                            <tbody>
                                {tutorCourses.map((course, i) => {
                                        return (
                                            <tr key={i}>
                                                <td className="td-bold">{course.name}</td>
                                            </tr>
                                        );
                                    }
                                )}
                                {tutorCourses.length > 0 ? <></> :
                                    <tr><td className="td-bold">No courses found!<br/>Change which courses you plan to tutor from the Settings page.</td></tr>
                                }
                            </tbody>
                        </Table>
                    </Container>
                </Col>
                <Col className="weekly-sched-col" md={6}>
                    <Row className="title" style={{ marginTop: '25px'}}>
                        <h2>Weekly Tutoring Schedule</h2>
                    </Row>
                    <Container className="table-container">
                        <Table className="table-striped">
                            <tbody>
                                {Array.from(Array(7).keys()).map(day => {
                                    let date = currWeekMap.get(day);
                                    if(date !== undefined) {
                                        let date_time = BreakDownTime(date.toISOString());
                                        let daily_appointments = GetDailyAppointments(weeklyAppointments, date);
                                        let unconfirmed = UnconfirmedMeetingExists(daily_appointments);
                                        return (
                                            <tr key={day}>
                                                <td className="td-bold">{daysOfWeek[day]}, {date_time[0].split(",")[0]}</td>
                                                <td>
                                                    {daily_appointments.length > 0 ? daily_appointments.length : "No"} Meetings
                                                    {unconfirmed ? 
                                                    <span className="sched-pending">
                                                        <FontAwesomeIcon id={"pending-icon-"+day} icon={faQuestionCircle}/>
                                                        <Tooltip placement="top" isOpen={tooltipsOpen[day]} target={"pending-icon-"+day} toggle={() => {
                                                            let tooltipsOpenCopy = [...tooltipsOpen];
                                                            tooltipsOpenCopy[day] = !tooltipsOpen[day];
                                                            setTooltipsOpen(tooltipsOpenCopy); 
                                                        }}>
                                                            You have one or more unconfirmed meetings on this day.
                                                        </Tooltip>
                                                    </span> : <></>}
                                                </td>
                                            </tr>
                                        );
                                    } else {
                                        return <></>;
                                    }
                                })}
                            </tbody>
                        </Table>
                    </Container>
                </Col>
            </Row>

        </Container>
    );
}
Example #12
Source File: DiemCheckout.tsx    From reference-merchant with Apache License 2.0 4 votes vote down vote up
export default function DiemCheckout({ paymentId, orderId, demoMode }: DiemCheckoutProps) {
  const [paymentOptions, setPaymentOptions] = useState<
    PaymentOptions | undefined
  >();
  const [selectedOption, setSelectedOption] = useState(0);
  const [chooseWallet, setChooseWallet] = useState(true);

  useEffect(() => {
    let isOutdated = false;

    const fetchOrder = async () => {
      try {
        const fetched = await new Vasp().getPaymentOptions(paymentId);

        if (!isOutdated) {
          setPaymentOptions(fetched);
        }
      } catch (e) {
        console.error("Unexpected error", e);
      }
    };

    // noinspection JSIgnoredPromiseFromCall
    fetchOrder();

    return () => {
      isOutdated = true;
    };
  }, [paymentId]);

  const onCurrencyClick = (index: number) => setSelectedOption(index);

  if (!paymentOptions) {
    return <div>Loading...</div>;
  }

  const handleClick = () => {
    setChooseWallet(false)
  }

  return (
    <>
      <div className="w-100">
        <Row>
          <Col className="text-nowrap text-right">Total price:</Col>
          <Col className="d-flex align-items-center">
            <span className="text-nowrap">
            {fiatToHumanFriendly(paymentOptions.fiatPrice)}{" "}
            {paymentOptions.fiatCurrency}
            </span>
            <FontAwesomeIcon size="xs" icon={faQuestionCircle} className="ml-2" id="totalPriceHelp" />
            <UncontrolledTooltip target="totalPriceHelp">
              The price in fiat set by the merchant
            </UncontrolledTooltip>
          </Col>
        </Row>
        <Row>
          <Col className="text-nowrap text-right align-self-center">
            Payment currency:
          </Col>
          <Col className="d-flex align-items-center">
            <UncontrolledDropdown>
              <DropdownToggle caret color="outline-dark" className="py-0 px-2">
                {paymentOptions.options[selectedOption].currency}
              </DropdownToggle>
              <DropdownMenu>
                {paymentOptions.options.map((op, i) => (
                  <DropdownItem
                    key={op.currency}
                    onClick={() => onCurrencyClick(i)}
                  >
                    {op.currency}
                  </DropdownItem>
                ))}
              </DropdownMenu>
            </UncontrolledDropdown>
            <FontAwesomeIcon size="xs" icon={faQuestionCircle} className="ml-2" id="currencyHelp" />
            <UncontrolledTooltip target="currencyHelp">
              Please select a Diem currency
            </UncontrolledTooltip>
          </Col>
        </Row>
        <Row>
          <Col className="text-nowrap text-right">Total to pay:</Col>
          <Col className="d-flex align-items-center">
            <span className="text-nowrap">
              {diemToHumanFriendly(
                paymentOptions.options[selectedOption].amount
              )}{" "}
              {paymentOptions.options[selectedOption].currency}
            </span>
            <FontAwesomeIcon size="xs" icon={faQuestionCircle} className="ml-2" id="totalToPayHelp" />
            <UncontrolledTooltip target="totalToPayHelp">
              The amount you will be changed in Diem
            </UncontrolledTooltip>
          </Col>
        </Row>
      </div>
      <div>
        {!chooseWallet ? (
          <>
            <QRCode
              className="img-fluid mt-4"
              size={192}
              value={paymentOptions.options[selectedOption].paymentLink}
              imageSettings={{
                src: require("../logo.svg"),
                height: 32,
                width: 32,
                excavate: true,
              }}
            />
            <div className="text-center small py-4 font-weight-bold">
              - OR -
            </div>
            <div className="text-center">
              <Button color="primary" size="sm" onClick={() => setChooseWallet(true)}>
                Open in Diem wallet
              </Button>
            </div>
          </>
        ) : (
          <>
            <div className="mt-4">
              <div className="text-center">Choose your wallet:</div>
              <PayWithDiem
                paymentInfo={paymentOptions}
                orderId={orderId}
                demoMode={demoMode}
              />
            </div>
            <div className="text-center small py-4 font-weight-bold">
              - OR -
            </div>
            <div className="text-center">
              <Button color="primary" size="sm" onClick={()=>handleClick()}>
                Scan QR
              </Button>
            </div>
          </>
        )}
      </div>
    </>
  );
}
Example #13
Source File: ArtifactEditor.tsx    From genshin-optimizer with MIT License 4 votes vote down vote up
export default function ArtifactEditor({ artifactIdToEdit = "", cancelEdit, allowUpload = false, allowEmpty = false, disableEditSetSlot: disableEditSlotProp = false }:
  { artifactIdToEdit?: string, cancelEdit: () => void, allowUpload?: boolean, allowEmpty?: boolean, disableEditSetSlot?: boolean }) {
  const { t } = useTranslation("artifact")

  const artifactSheets = usePromise(ArtifactSheet.getAll, [])

  const { database } = useContext(DatabaseContext)

  const [show, setShow] = useState(false)

  const [dirtyDatabase, setDirtyDatabase] = useForceUpdate()
  useEffect(() => database.followAnyArt(setDirtyDatabase), [database, setDirtyDatabase])

  const [editorArtifact, artifactDispatch] = useReducer(artifactReducer, undefined)
  const artifact = useMemo(() => editorArtifact && parseArtifact(editorArtifact), [editorArtifact])

  const [modalShow, setModalShow] = useState(false)

  const [{ processed, outstanding }, dispatchQueue] = useReducer(queueReducer, { processed: [], outstanding: [] })
  const firstProcessed = processed[0] as ProcessedEntry | undefined
  const firstOutstanding = outstanding[0] as OutstandingEntry | undefined

  const processingImageURL = usePromise(firstOutstanding?.imageURL, [firstOutstanding?.imageURL])
  const processingResult = usePromise(firstOutstanding?.result, [firstOutstanding?.result])

  const remaining = processed.length + outstanding.length

  const image = firstProcessed?.imageURL ?? processingImageURL
  const { artifact: artifactProcessed, texts } = firstProcessed ?? {}
  // const fileName = firstProcessed?.fileName ?? firstOutstanding?.fileName ?? "Click here to upload Artifact screenshot files"

  const disableEditSetSlot = disableEditSlotProp || !!artifact?.location

  useEffect(() => {
    if (!artifact && artifactProcessed)
      artifactDispatch({ type: "overwrite", artifact: artifactProcessed })
  }, [artifact, artifactProcessed, artifactDispatch])

  useEffect(() => {
    const numProcessing = Math.min(maxProcessedCount - processed.length, maxProcessingCount, outstanding.length)
    const processingCurrent = numProcessing && !outstanding[0].result
    outstanding.slice(0, numProcessing).forEach(processEntry)
    if (processingCurrent)
      dispatchQueue({ type: "processing" })
  }, [processed.length, outstanding])

  useEffect(() => {
    if (processingResult)
      dispatchQueue({ type: "processed", ...processingResult })
  }, [processingResult, dispatchQueue])

  const uploadFiles = useCallback((files: FileList) => {
    setShow(true)
    dispatchQueue({ type: "upload", files: [...files].map(file => ({ file, fileName: file.name })) })
  }, [dispatchQueue, setShow])
  const clearQueue = useCallback(() => dispatchQueue({ type: "clear" }), [dispatchQueue])

  useEffect(() => {
    const pasteFunc = (e: any) => uploadFiles(e.clipboardData.files)
    allowUpload && window.addEventListener('paste', pasteFunc);
    return () => {
      if (allowUpload) window.removeEventListener('paste', pasteFunc)
    }
  }, [uploadFiles, allowUpload])

  const onUpload = useCallback(
    e => {
      uploadFiles(e.target.files)
      e.target.value = null // reset the value so the same file can be uploaded again...
    },
    [uploadFiles],
  )

  const { old, oldType }: { old: ICachedArtifact | undefined, oldType: "edit" | "duplicate" | "upgrade" | "" } = useMemo(() => {
    const databaseArtifact = dirtyDatabase && artifactIdToEdit && database._getArt(artifactIdToEdit)
    if (databaseArtifact) return { old: databaseArtifact, oldType: "edit" }
    if (artifact === undefined) return { old: undefined, oldType: "" }
    const { duplicated, upgraded } = dirtyDatabase && database.findDuplicates(artifact)
    return { old: duplicated[0] ?? upgraded[0], oldType: duplicated.length !== 0 ? "duplicate" : "upgrade" }
  }, [artifact, artifactIdToEdit, database, dirtyDatabase])

  const { artifact: cachedArtifact, errors } = useMemo(() => {
    if (!artifact) return { artifact: undefined, errors: [] as Displayable[] }
    const validated = validateArtifact(artifact, artifactIdToEdit)
    if (old) {
      validated.artifact.location = old.location
      validated.artifact.exclude = old.exclude
    }
    return validated
  }, [artifact, artifactIdToEdit, old])

  // Overwriting using a different function from `databaseArtifact` because `useMemo` does not
  // guarantee to trigger *only when* dependencies change, which is necessary in this case.
  useEffect(() => {
    if (artifactIdToEdit === "new") {
      setShow(true)
      artifactDispatch({ type: "reset" })
    }
    const databaseArtifact = artifactIdToEdit && dirtyDatabase && database._getArt(artifactIdToEdit)
    if (databaseArtifact) {
      setShow(true)
      artifactDispatch({ type: "overwrite", artifact: deepClone(databaseArtifact) })
    }
  }, [artifactIdToEdit, database, dirtyDatabase])

  const sheet = artifact ? artifactSheets?.[artifact.setKey] : undefined
  const reset = useCallback(() => {
    cancelEdit?.();
    dispatchQueue({ type: "pop" })
    artifactDispatch({ type: "reset" })
  }, [cancelEdit, artifactDispatch])
  const update = useCallback((newValue: Partial<IArtifact>) => {
    const newSheet = newValue.setKey ? artifactSheets![newValue.setKey] : sheet!

    function pick<T>(value: T | undefined, available: readonly T[], prefer?: T): T {
      return (value && available.includes(value)) ? value : (prefer ?? available[0])
    }

    if (newValue.setKey) {
      newValue.rarity = pick(artifact?.rarity, newSheet.rarity, Math.max(...newSheet.rarity) as ArtifactRarity)
      newValue.slotKey = pick(artifact?.slotKey, newSheet.slots)
    }
    if (newValue.rarity)
      newValue.level = artifact?.level ?? 0
    if (newValue.level)
      newValue.level = clamp(newValue.level, 0, 4 * (newValue.rarity ?? artifact!.rarity))
    if (newValue.slotKey)
      newValue.mainStatKey = pick(artifact?.mainStatKey, Artifact.slotMainStats(newValue.slotKey))

    if (newValue.mainStatKey) {
      newValue.substats = [0, 1, 2, 3].map(i =>
        (artifact && artifact.substats[i].key !== newValue.mainStatKey) ? artifact!.substats[i] : { key: "", value: 0 })
    }
    artifactDispatch({ type: "update", artifact: newValue })
  }, [artifact, artifactSheets, sheet, artifactDispatch])
  const setSubstat = useCallback((index: number, substat: ISubstat) => {
    artifactDispatch({ type: "substat", index, substat })
  }, [artifactDispatch])
  const isValid = !errors.length
  const canClearArtifact = (): boolean => window.confirm(t`editor.clearPrompt` as string)
  const { rarity = 5, level = 0, slotKey = "flower" } = artifact ?? {}
  const { currentEfficiency = 0, maxEfficiency = 0 } = cachedArtifact ? Artifact.getArtifactEfficiency(cachedArtifact, allSubstatFilter) : {}
  const preventClosing = processed.length || outstanding.length
  const onClose = useCallback(
    (e) => {
      if (preventClosing) e.preventDefault()
      setShow(false)
      cancelEdit()
    }, [preventClosing, setShow, cancelEdit])

  const theme = useTheme();
  const grmd = useMediaQuery(theme.breakpoints.up('md'));

  const element = artifact ? allElementsWithPhy.find(ele => artifact.mainStatKey.includes(ele)) : undefined
  const color = artifact
    ? element ?? "success"
    : "primary"

  return <ModalWrapper open={show} onClose={onClose} >
    <Suspense fallback={<Skeleton variant="rectangular" sx={{ width: "100%", height: show ? "100%" : 64 }} />}><CardDark >
      <UploadExplainationModal modalShow={modalShow} hide={() => setModalShow(false)} />
      <CardHeader
        title={<Trans t={t} i18nKey="editor.title" >Artifact Editor</Trans>}
        action={<CloseButton disabled={!!preventClosing} onClick={onClose} />}
      />
      <CardContent sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
        <Grid container spacing={1} columns={{ xs: 1, md: 2 }} >
          {/* Left column */}
          <Grid item xs={1} display="flex" flexDirection="column" gap={1}>
            {/* set & rarity */}
            <ButtonGroup sx={{ display: "flex", mb: 1 }}>
              {/* Artifact Set */}
              <ArtifactSetSingleAutocomplete
                size="small"
                disableClearable
                artSetKey={artifact?.setKey ?? ""}
                setArtSetKey={setKey => update({ setKey: setKey as ArtifactSetKey })}
                sx={{ flexGrow: 1 }}
                disabled={disableEditSetSlot}
              />
              {/* rarity dropdown */}
              <ArtifactRarityDropdown rarity={artifact ? rarity : undefined} onChange={r => update({ rarity: r })} filter={r => !!sheet?.rarity?.includes?.(r)} disabled={disableEditSetSlot || !sheet} />
            </ButtonGroup>

            {/* level */}
            <Box component="div" display="flex">
              <CustomNumberTextField id="filled-basic" label="Level" variant="filled" sx={{ flexShrink: 1, flexGrow: 1, mr: 1, my: 0 }} margin="dense" size="small"
                value={level} disabled={!sheet} placeholder={`0~${rarity * 4}`} onChange={l => update({ level: l })}
              />
              <ButtonGroup >
                <Button onClick={() => update({ level: level - 1 })} disabled={!sheet || level === 0}>-</Button>
                {rarity ? [...Array(rarity + 1).keys()].map(i => 4 * i).map(i => <Button key={i} onClick={() => update({ level: i })} disabled={!sheet || level === i}>{i}</Button>) : null}
                <Button onClick={() => update({ level: level + 1 })} disabled={!sheet || level === (rarity * 4)}>+</Button>
              </ButtonGroup>
            </Box>

            {/* slot */}
            <Box component="div" display="flex">
              <ArtifactSlotDropdown disabled={disableEditSetSlot || !sheet} slotKey={slotKey} onChange={slotKey => update({ slotKey })} />
              <CardLight sx={{ p: 1, ml: 1, flexGrow: 1 }}>
                <Suspense fallback={<Skeleton width="60%" />}>
                  <Typography color="text.secondary">
                    {sheet?.getSlotName(artifact!.slotKey) ? <span><ImgIcon src={sheet.slotIcons[artifact!.slotKey]} /> {sheet?.getSlotName(artifact!.slotKey)}</span> : t`editor.unknownPieceName`}
                  </Typography>
                </Suspense>
              </CardLight>
            </Box>

            {/* main stat */}
            <Box component="div" display="flex">
              <DropdownButton startIcon={element ? uncoloredEleIcons[element] : (artifact?.mainStatKey ? StatIcon[artifact.mainStatKey] : undefined)}
                title={<b>{artifact ? KeyMap.getArtStr(artifact.mainStatKey) : t`mainStat`}</b>} disabled={!sheet} color={color} >
                {Artifact.slotMainStats(slotKey).map(mainStatK =>
                  <MenuItem key={mainStatK} selected={artifact?.mainStatKey === mainStatK} disabled={artifact?.mainStatKey === mainStatK} onClick={() => update({ mainStatKey: mainStatK })} >
                    <ListItemIcon>{StatIcon[mainStatK]}</ListItemIcon>
                    <ListItemText>{KeyMap.getArtStr(mainStatK)}</ListItemText>
                  </MenuItem>)}
              </DropdownButton>
              <CardLight sx={{ p: 1, ml: 1, flexGrow: 1 }}>
                <Typography color="text.secondary">
                  {artifact ? `${cacheValueString(Artifact.mainStatValue(artifact.mainStatKey, rarity, level), KeyMap.unit(artifact.mainStatKey))}${KeyMap.unit(artifact.mainStatKey)}` : t`mainStat`}
                </Typography>
              </CardLight>
            </Box>

            {/* Current/Max Substats Efficiency */}
            <SubstatEfficiencyDisplayCard valid={isValid} efficiency={currentEfficiency} t={t} />
            {currentEfficiency !== maxEfficiency && <SubstatEfficiencyDisplayCard max valid={isValid} efficiency={maxEfficiency} t={t} />}

            {/* Image OCR */}
            {allowUpload && <CardLight>
              <CardContent sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
                {/* TODO: artifactDispatch not overwrite */}
                <Suspense fallback={<Skeleton width="100%" height="100" />}>
                  <Grid container spacing={1} alignItems="center">
                    <Grid item flexGrow={1}>
                      <label htmlFor="contained-button-file">
                        <InputInvis accept="image/*" id="contained-button-file" multiple type="file" onChange={onUpload} />
                        <Button component="span" startIcon={<PhotoCamera />}>
                          Upload Screenshot (or Ctrl-V)
                        </Button>
                      </label>
                    </Grid>
                    <Grid item>
                      <Button color="info" sx={{ px: 2, minWidth: 0 }} onClick={() => setModalShow(true)}><Typography><FontAwesomeIcon icon={faQuestionCircle} /></Typography></Button>
                    </Grid>
                  </Grid>
                  {image && <Box display="flex" justifyContent="center">
                    <Box component="img" src={image} width="100%" maxWidth={350} height="auto" alt="Screenshot to parse for artifact values" />
                  </Box>}
                  {remaining > 0 && <CardDark sx={{ pl: 2 }} ><Grid container spacing={1} alignItems="center" >
                    {!firstProcessed && firstOutstanding && <Grid item>
                      <CircularProgress size="1em" />
                    </Grid>}
                    <Grid item flexGrow={1}>
                      <Typography>
                        <span>
                          Screenshots in file-queue: <b>{remaining}</b>
                          {/* {process.env.NODE_ENV === "development" && ` (Debug: Processed ${processed.length}/${maxProcessedCount}, Processing: ${outstanding.filter(entry => entry.result).length}/${maxProcessingCount}, Outstanding: ${outstanding.length})`} */}
                        </span>
                      </Typography>
                    </Grid>
                    <Grid item>
                      <Button size="small" color="error" onClick={clearQueue}>Clear file-queue</Button>
                    </Grid>
                  </Grid></CardDark>}
                </Suspense>
              </CardContent>
            </CardLight>}
          </Grid>

          {/* Right column */}
          <Grid item xs={1} display="flex" flexDirection="column" gap={1}>
            {/* substat selections */}
            {[0, 1, 2, 3].map((index) => <SubstatInput key={index} index={index} artifact={cachedArtifact} setSubstat={setSubstat} />)}
            {texts && <CardLight><CardContent>
              <div>{texts.slotKey}</div>
              <div>{texts.mainStatKey}</div>
              <div>{texts.mainStatVal}</div>
              <div>{texts.rarity}</div>
              <div>{texts.level}</div>
              <div>{texts.substats}</div>
              <div>{texts.setKey}</div>
            </CardContent></CardLight>}
          </Grid>
        </Grid>

        {/* Duplicate/Updated/Edit UI */}
        {old && <Grid container sx={{ justifyContent: "space-around" }} spacing={1} >
          <Grid item xs={12} md={5.5} lg={4} ><CardLight>
            <Typography sx={{ textAlign: "center" }} py={1} variant="h6" color="text.secondary" >{oldType !== "edit" ? (oldType === "duplicate" ? t`editor.dupArt` : t`editor.upArt`) : t`editor.beforeEdit`}</Typography>
            <ArtifactCard artifactObj={old} />
          </CardLight></Grid>
          {grmd && <Grid item md={1} display="flex" alignItems="center" justifyContent="center" >
            <CardLight sx={{ display: "flex" }}><ChevronRight sx={{ fontSize: 40 }} /></CardLight>
          </Grid>}
          <Grid item xs={12} md={5.5} lg={4} ><CardLight>
            <Typography sx={{ textAlign: "center" }} py={1} variant="h6" color="text.secondary" >{t`editor.preview`}</Typography>
            <ArtifactCard artifactObj={cachedArtifact} />
          </CardLight></Grid>
        </Grid>}

        {/* Error alert */}
        {!isValid && <Alert variant="filled" severity="error" >{errors.map((e, i) => <div key={i}>{e}</div>)}</Alert>}

        {/* Buttons */}
        <Grid container spacing={2}>
          <Grid item>
            {oldType === "edit" ?
              <Button startIcon={<Add />} onClick={() => {
                database.updateArt(editorArtifact!, old!.id);
                if (allowEmpty) reset()
                else {
                  setShow(false)
                  cancelEdit()
                }
              }} disabled={!editorArtifact || !isValid} color="primary">
                {t`editor.btnSave`}
              </Button> :
              <Button startIcon={<Add />} onClick={() => {
                database.createArt(artifact!);
                if (allowEmpty) reset()
                else {
                  setShow(false)
                  cancelEdit()
                }
              }} disabled={!artifact || !isValid} color={oldType === "duplicate" ? "warning" : "primary"}>
                {t`editor.btnAdd`}
              </Button>}
          </Grid>
          <Grid item flexGrow={1}>
            {allowEmpty && <Button startIcon={<Replay />} disabled={!artifact} onClick={() => { canClearArtifact() && reset() }} color="error">{t`editor.btnClear`}</Button>}
          </Grid>
          <Grid item>
            {process.env.NODE_ENV === "development" && <Button color="info" startIcon={<Shuffle />} onClick={async () => artifactDispatch({ type: "overwrite", artifact: await randomizeArtifact() })}>{t`editor.btnRandom`}</Button>}
          </Grid>
          {old && oldType !== "edit" && <Grid item>
            <Button startIcon={<Update />} onClick={() => { database.updateArt(editorArtifact!, old.id); allowEmpty ? reset() : setShow(false) }} disabled={!editorArtifact || !isValid} color="success">{t`editor.btnUpdate`}</Button>
          </Grid>}
        </Grid>
      </CardContent>
    </CardDark ></Suspense>
  </ModalWrapper>
}
Example #14
Source File: PaypalPaymentOptions.tsx    From mysterium-vpn-desktop with MIT License 4 votes vote down vote up
PaypalPaymentOptions: React.FC = observer(() => {
    const { payment } = useStores()
    const navigate = useNavigate()
    const [loading, setLoading] = useState(false)
    const isOptionActive = (cur: string) => {
        return payment.paymentCurrency == cur
    }
    const selectOption = (cur: string) => () => {
        payment.setPaymentCurrency(cur)
    }
    const handleNextClick = async () => {
        setLoading(() => true)
        try {
            await payment.createOrder()
            setLoading(() => false)
            navigate("../" + topupSteps.paypalOrderSummary)
        } catch (err) {
            setLoading(() => false)
            const msg = parseError(err)
            logErrorMessage("Could not create a payment order", msg)
            toast.error(dismissibleToast(<span>{msg.humanReadable}</span>))
        }
    }
    const options = payment.paymentMethod?.gatewayData.currencies || []
    return (
        <ViewContainer>
            <ViewNavBar onBack={() => navigate(-1)}>
                <div style={{ width: 375, textAlign: "center" }}>
                    <StepProgressBar step={1} />
                </div>
            </ViewNavBar>
            <ViewSplit>
                <ViewSidebar>
                    <SideTop>
                        <IconWallet color={brandLight} />
                        <Title>Top up your account</Title>
                        <TitleDescription>Select the payment options</TitleDescription>
                    </SideTop>
                    <SideBot>
                        <PaymentOption>Payment currency:</PaymentOption>
                        <AmountSelect>
                            {options.map((opt) => {
                                let currencyIcon = faQuestionCircle
                                switch (opt) {
                                    case "EUR":
                                        currencyIcon = faEuroSign
                                        break
                                    case "USD":
                                        currencyIcon = faDollarSign
                                        break
                                    case "GBP":
                                        currencyIcon = faPoundSign
                                        break
                                }
                                return (
                                    <AmountToggle
                                        key={opt}
                                        active={isOptionActive(opt)}
                                        onClick={selectOption(opt)}
                                        inactiveColor={lightBlue}
                                        height="36px"
                                        justify="center"
                                    >
                                        <div style={{ textAlign: "center" }}>
                                            <OptionValue>
                                                <FontAwesomeIcon icon={currencyIcon} fixedWidth size="sm" />
                                                {opt}
                                            </OptionValue>
                                        </div>
                                    </AmountToggle>
                                )
                            })}
                        </AmountSelect>
                        <PaymentOption>Tax residence country (VAT):</PaymentOption>
                        <SelectTaxCountry />
                        <BrandButton
                            style={{ marginTop: "auto" }}
                            onClick={handleNextClick}
                            loading={loading}
                            disabled={loading || !payment.paymentCurrency || !payment.taxCountry}
                        >
                            Next
                        </BrandButton>
                    </SideBot>
                </ViewSidebar>
                <ViewContent />
            </ViewSplit>
        </ViewContainer>
    )
})
Example #15
Source File: StripePaymentOptions.tsx    From mysterium-vpn-desktop with MIT License 4 votes vote down vote up
StripePaymentOptions: React.FC = observer(() => {
    const { payment } = useStores()
    const navigate = useNavigate()
    const [loading, setLoading] = useState(false)
    const isOptionActive = (cur: string) => {
        return payment.paymentCurrency == cur
    }
    const selectOption = (cur: string) => () => {
        payment.setPaymentCurrency(cur)
    }
    const handleNextClick = async () => {
        setLoading(() => true)
        try {
            await payment.createOrder()
            setLoading(() => false)
            navigate("../" + topupSteps.stripeOrderSummary)
        } catch (err) {
            setLoading(() => false)
            const msg = parseError(err)
            logErrorMessage("Could not create a payment order", msg)
            toast.error(dismissibleToast(<span>{msg.humanReadable}</span>))
        }
    }
    const options = payment.paymentMethod?.gatewayData.currencies || []
    return (
        <ViewContainer>
            <ViewNavBar onBack={() => navigate(-1)}>
                <div style={{ width: 375, textAlign: "center" }}>
                    <StepProgressBar step={1} />
                </div>
            </ViewNavBar>
            <ViewSplit>
                <ViewSidebar>
                    <SideTop>
                        <IconWallet color={brandLight} />
                        <Title>Top up your account</Title>
                        <TitleDescription>Select the payment options</TitleDescription>
                    </SideTop>
                    <SideBot>
                        <PaymentOption>Payment currency:</PaymentOption>
                        <AmountSelect>
                            {options.map((opt) => {
                                let currencyIcon = faQuestionCircle
                                switch (opt) {
                                    case "EUR":
                                        currencyIcon = faEuroSign
                                        break
                                    case "USD":
                                        currencyIcon = faDollarSign
                                        break
                                    case "GBP":
                                        currencyIcon = faPoundSign
                                        break
                                }
                                return (
                                    <AmountToggle
                                        key={opt}
                                        active={isOptionActive(opt)}
                                        onClick={selectOption(opt)}
                                        inactiveColor={lightBlue}
                                        height="36px"
                                        justify="center"
                                    >
                                        <div style={{ textAlign: "center" }}>
                                            <OptionValue>
                                                <FontAwesomeIcon icon={currencyIcon} fixedWidth size="sm" />
                                                {opt}
                                            </OptionValue>
                                        </div>
                                    </AmountToggle>
                                )
                            })}
                        </AmountSelect>
                        <PaymentOption>Tax residence country (VAT):</PaymentOption>
                        <SelectTaxCountry />
                        <BrandButton
                            style={{ marginTop: "auto" }}
                            onClick={handleNextClick}
                            loading={loading}
                            disabled={loading || !payment.paymentCurrency || !payment.taxCountry}
                        >
                            Next
                        </BrandButton>
                    </SideBot>
                </ViewSidebar>
                <ViewContent />
            </ViewSplit>
        </ViewContainer>
    )
})