react-icons/fi#FiEdit3 JavaScript Examples

The following examples show how to use react-icons/fi#FiEdit3. 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: new.js    From plataforma-sabia with MIT License 4 votes vote down vote up
NewServicePage = ({ keywordTerms }) => {
	const form = useForm({
		defaultValues: {
			name: '',
			keywords: null,
			description: '',
			measure_unit: null,
			price: '',
			type: null,
			payment_message: '',
			thumbnail_id: null,
		},
	});
	const { colors } = useTheme();
	const [addedServices, setAddedServices] = useState([]);
	const [isSubmitting, setIsSubmitting] = useState(false);
	const [uploadError, setUploadError] = useState('');
	const [thumbnailPreview, setThumbnailPreview] = useState('');
	const router = useRouter();
	const { user } = useAuth();
	const { openModal } = useModal();

	const handleSubmit = async (values, _, isFinalize) => {
		setIsSubmitting(true);

		const preparedData = prepareFormData(values);
		const result = await createService(preparedData);

		if (result) {
			toast.success('Serviço criado com sucesso!');
			form.reset();
			setThumbnailPreview(null);
			setAddedServices((prevValue) => [...prevValue, result]);
		} else {
			return toast.error('Erro ao criar serviço, tente novamente em instantes');
		}

		if (isFinalize) {
			return router.push('/');
		}

		return setIsSubmitting(false);
	};

	const handleDeleteService = async (serviceId) => {
		setIsSubmitting(true);

		const result = await deleteService(serviceId);

		if (!result)
			toast.error(
				'Ocorreu um erro ao tentar deletar o serviço. Tente novamente em instantes',
			);
		else {
			toast.success('Serviço deletado com sucesso');
			setAddedServices((prevValue) => prevValue.filter((item) => item.id !== serviceId));
		}

		setIsSubmitting(false);
	};

	/*
	 * If user's adding the first service he can click in finalize button so it'll
	 * add the service and then redirect to home
	 * If user already added some services he can click in finalize button and then
	 * he'll be just redirected to home
	 * The advantage is that user can register only one service and get redirected to home
	 * in just one click
	 */
	const handleFinalizeRegistration = async () => {
		if (addedServices.length) {
			return router.push('/');
		}

		const isValidForm = await form.trigger();
		if (isValidForm) {
			await handleSubmit(form.getValues(), null, true);
		}

		return true;
	};

	const onCreateTerm = async (inputValue, taxonomy) => {
		const term = await createTerm(inputValue, taxonomy);
		return { label: term.term, value: `${term.id}` };
	};

	const onDropAttachment = async (acceptedFiles) => {
		if (!acceptedFiles) return null;

		const formData = new FormData();
		if (acceptedFiles.length !== 0) {
			formData.append(`files[0]`, acceptedFiles[0], acceptedFiles[0].name);
		}

		const response = await upload(formData);

		if (response.status === 200) {
			const { id, url } = response.data[0];
			setThumbnailPreview(url);
			form.setValue('thumbnail_id', id);
		} else {
			setUploadError(response.data.error.message[0].message);
		}

		return true;
	};

	return (
		<Wrapper>
			<Protected>
				<Container onSubmit={form.handleSubmit(handleSubmit)}>
					<Details>
						<Title align="left" color={colors.black}>
							Novo serviço
						</Title>

						<Fields>
							<Dropzone
								accept="image/*"
								onDrop={(acceptedFiles) => onDropAttachment(acceptedFiles)}
								multiple={false}
							>
								{({ getRootProps, getInputProps }) => (
									<UploadWrapper>
										{thumbnailPreview && (
											<ThumbnailWrapper>
												<Image
													src={thumbnailPreview}
													width={80}
													height={80}
													alt="Service thumbnail"
												/>
											</ThumbnailWrapper>
										)}
										<UploadThumbnail {...getRootProps()}>
											<UploadBody>
												<FiImage fontSize={24} />
												<div>
													<p>Selecione uma imagem de capa</p>
													<p>Limite de 5mb</p>
												</div>
											</UploadBody>
											<input name="logo" {...getInputProps()} />
										</UploadThumbnail>
										{uploadError && <UploadError>{uploadError}</UploadError>}
									</UploadWrapper>
								)}
							</Dropzone>
							<InputHiddenField form={form} name="thumbnail_id" />

							<Inputs>
								<InputField
									form={form}
									name="name"
									label="Nome do serviço"
									validation={{ required: true }}
									placeholder="Digite o nome"
									variant="gray"
								/>

								<SelectField
									form={form}
									name="keywords"
									instanceId="keywords-select"
									placeholder="Busque por palavras chaves (pode adicionar mais de um item)"
									label="Palavras-chave"
									validation={{ required: true }}
									options={mapArrayOfObjectToSelect(keywordTerms, 'term', 'id')}
									onCreate={(inputValue) => onCreateTerm(inputValue, 'KEYWORDS')}
									variant="gray"
									isMulti
									creatable
								/>

								<TextField
									form={form}
									name="description"
									validation={{ required: true }}
									label="Descrição"
									placeholder="Digite a descrição"
									variant="gray"
									resize="none"
								/>

								<SelectField
									form={form}
									name="measure_unit"
									instanceId="measure_unit-select"
									label="Unidade de Medida"
									placeholder="Escolha uma unidade"
									validation={{ required: true }}
									options={measureUnitOptions}
									variant="rounded"
								/>

								<CurrencyInputField
									form={form}
									name="price"
									validation={{ required: true }}
									label="Preço"
									placeholder="Digite o preço"
									variant="gray"
								/>

								<SelectField
									form={form}
									name="type"
									instanceId="type-select"
									label="Tipo"
									placeholder="Escolha um tipo"
									validation={{ required: true }}
									options={typeOptions}
									variant="rounded"
								/>
							</Inputs>

							<RectangularButton
								disabled={isSubmitting}
								variant="outlined"
								colorVariant="blue"
								type="submit"
								fullWidth
							>
								Adicionar novo serviço
							</RectangularButton>
							<RectangularButton
								variant="filled"
								colorVariant="orange"
								disabled={isSubmitting}
								onClick={handleFinalizeRegistration}
								fullWidth
							>
								Finalizar cadastro
							</RectangularButton>
						</Fields>

						<PaymentMessage>
							<div>
								<p>Responsável:</p>
								<p>{user.full_name}</p>

								<p>Instituição:</p>
								<p>{user.institution?.name}</p>
							</div>

							<Watcher
								form={form}
								property="payment_message"
								render={(paymentMessageHtml) => (
									<HtmlViewField
										label="Mensagem de pagamento"
										placeholder="Insira a mensagem de pagamento"
										html={paymentMessageHtml}
									/>
								)}
							/>

							<RectangularButton
								fullWidth
								variant="text"
								colorVariant="blue"
								onClick={() =>
									openModal(
										'ckEditor',
										{
											form,
											name: 'payment_message',
											config: {
												placeholder: 'Insira a mensagem de pagamento',
												removePlugins: [
													'ImageUpload',
													'Table',
													'MediaEmbed',
												],
											},
											onChange: (editorData) =>
												form.setValue('payment_message', editorData),
											renderWithController: false,
											defaultValue: form.getValues()?.payment_message,
										},
										{
											customModal: true,
											overlayClick: false,
										},
									)
								}
							>
								<FiEdit3 fontSize={14} />
								Editar mensagem
							</RectangularButton>
							<InputHiddenField form={form} name="payment_message" />
						</PaymentMessage>
					</Details>

					<Review>
						<Title align="left" color={colors.black}>
							Serviços
						</Title>

						{addedServices.map((service) => (
							<ServiceCard key={service.id}>
								<div>
									<ServiceThumbnailWrapper>
										<Image
											src={service.thumbnail?.url || '/card-image.jpg'}
											width={80}
											height={80}
										/>
									</ServiceThumbnailWrapper>

									<ServiceInfos>
										<p>{service.name}</p>
										<span>{service.description}</span>
										<p>{formatMoney(service.price)}</p>
									</ServiceInfos>
								</div>

								<RectangularButton
									variant="text"
									colorVariant="red"
									onClick={() => handleDeleteService(service.id)}
								>
									Remover
								</RectangularButton>
							</ServiceCard>
						))}
					</Review>
				</Container>
			</Protected>
		</Wrapper>
	);
}
Example #2
Source File: index.js    From plataforma-sabia with MIT License 4 votes vote down vote up
CommonDataForm = ({ form, user, message, loading }) => {
	const { setValue, register, watch } = form;
	const { t } = useTranslation(['account']);
	const { openModal } = useModal();
	const [isResearcher, setIsResearcher] = useState(Boolean(user.researcher));
	const [userAreas, setUserAreas] = useState(user?.areas || []);
	const [hasAreasLoading, setHasAreasLoading] = useState([true]);
	const areaKeys = ['great_area_id', 'area_id', 'sub_area_id', 'speciality_id'];
	const maxAreaNumber = 4;
	const emptyArea = {
		great_area_id: null,
		area_id: null,
		sub_area_id: null,
		speciality_id: null,
	};
	const brazilStateId = watch('state_id');

	const { data: { data: institutions } = {} } = useSWR(
		'get-institutions',
		() => getInstitutions({ perPage: 10, order: 'desc' }),
		{
			revalidateOnFocus: false,
		},
	);

	const { data: brazilStates = [] } = useSWR('get-brazil-states', () => getStates(), {
		revalidateOnFocus: false,
	});

	const { data: brazilStateCities = [] } = useSWR(
		brazilStateId ? `get-brazil-state-city-${brazilStateId.value || brazilStateId}` : null,
		() => getStateCities(brazilStateId.value || brazilStateId, { perPage: 10 }),
		{
			revalidateOnFocus: false,
		},
	);

	const handleFetchInstitutions = debounce((value, callback) => {
		getInstitutions({ filterBy: 'name', filter: value, order: 'desc' }).then((response) => {
			const mappedOptions = mapInstitutionsOptions(response.data);
			callback(mappedOptions);
		});
	}, 300);

	/**
	 * Returns default institutions for use in async select
	 * Do not concat user institution with institutions array if already exists
	 *
	 * @returns {Array} Institutions options
	 */
	const getDefaultInstitutionsOptions = () => {
		const userInstitution = institutions?.find(
			(institution) => institution.id === user.institution_id,
		);

		return [
			...mapInstitutionsOptions(institutions),
			...(!userInstitution ? mapInstitutionsOptions([user.institution]) : []),
		];
	};

	useEffect(() => {
		register('researcher');
		setValue('researcher', isResearcher);
		let newAreaValue;

		if (isResearcher) {
			newAreaValue = userAreas.length ? [...userAreas] : [emptyArea];
		} else {
			newAreaValue = [];
		}

		setUserAreas(newAreaValue);
		setValue('areas', newAreaValue);
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [isResearcher]);

	return (
		<>
			<h3>Dados pessoais</h3>
			<Row>
				<Cell col={4}>
					<InputField
						form={form}
						name="full_name"
						label={t('account:labels.fullName')}
						validation={{ required: true }}
						variant="gray"
					/>
				</Cell>
				<Cell col={3}>
					<Row>
						<InputField
							form={form}
							name="email"
							label={t('account:labels.mainEmail')}
							type="email"
							disabled="disabled"
							variant="gray"
							wrapperCss={S.inputEmailWrapperCss}
						/>
						<S.ButtonChangeEmail
							type="button"
							onClick={() => openModal('updateEmail', {}, { customModal: true })}
							aria-label="Change e-mail"
						>
							<FiEdit3 /> Alterar
						</S.ButtonChangeEmail>
					</Row>
				</Cell>
			</Row>
			<Row>
				<Cell col={4}>
					<MaskedInputField
						form={form}
						name="cpf"
						label={t('account:labels.cpf')}
						validation={{ required: true }}
						variant="gray"
						pattern={maskPatterns.cpf.pattern}
						mask={maskPatterns.cpf.stringMask}
					/>
				</Cell>
				<Cell col={4}>
					<MaskedInputField
						form={form}
						name="birth_date"
						label={t('account:labels.birthDate')}
						validation={{ required: true }}
						variant="gray"
						pattern={maskPatterns.brazilianDate.pattern}
						mask={maskPatterns.brazilianDate.stringMask}
					/>
				</Cell>
				<Cell col={4}>
					<MaskedInputField
						form={form}
						name="phone_number"
						alwaysShowMask={false}
						label={t('account:labels.phoneNumber')}
						validation={{ required: true }}
						variant="gray"
						maskChar={null}
						mask={maskPatterns.phoneNumber.stringMask}
						pattern={maskPatterns.phoneNumber.pattern}
						formatChars={maskPatterns.phoneNumber.formatChars}
					/>
				</Cell>
			</Row>
			<Row>
				<Cell col={4}>
					<MaskedInputField
						form={form}
						name="zipcode"
						validation={{ required: true }}
						label={t('account:labels.zipCode')}
						variant="gray"
						mask={maskPatterns.zipCode.stringMask}
						pattern={maskPatterns.zipCode.pattern}
					/>
				</Cell>
				<Cell col={4}>
					<InputField
						form={form}
						name="address"
						validation={{ required: true }}
						label={t('account:labels.address')}
						variant="gray"
					/>
				</Cell>
				<Cell col={4}>
					<InputField
						form={form}
						name="address2"
						validation={{ required: true }}
						label={t('account:labels.address2')}
						variant="gray"
					/>
				</Cell>
			</Row>
			<Row>
				<Cell col={3}>
					<InputField
						form={form}
						name="district"
						validation={{ required: true }}
						label={t('account:labels.district')}
						variant="gray"
					/>
				</Cell>
				<Cell col={3}>
					<SelectField
						form={form}
						name="state_id"
						label={t('account:labels.state')}
						validation={{ required: true }}
						variant="gray"
						options={mapArrayOfObjectToSelect(brazilStates, 'initials', 'id')}
						instanceId="select-state-my-account"
						placeholder="Selecione o estado..."
						callback={() => {
							setValue('city_id', null);
						}}
					/>
				</Cell>
				<Cell col={3}>
					<SelectField
						form={form}
						name="city_id"
						label={t('account:labels.city')}
						placeholder={
							!brazilStateId
								? 'Selecione o estado primeiro...'
								: 'Selecione a cidade...'
						}
						variant="gray"
						options={mapArrayOfObjectToSelect(brazilStateCities, 'name', 'id')}
						noOptionsMessage={() => 'Nenhuma cidade encontrada...'}
						instanceId="select-city-my-account"
						validation={{ required: true }}
					/>
				</Cell>
				<Cell col={3}>
					<InputField
						form={form}
						name="country"
						validation={{ required: true }}
						label={t('account:labels.country')}
						variant="gray"
					/>
				</Cell>
			</Row>

			<h3>Dados Organizacionais e Acadêmicos</h3>
			<Row>
				<Cell col={9}>
					<Row align="center">
						<Cell col="auto">
							<SelectField
								form={form}
								name="institution_id"
								label={t('account:labels.institution')}
								placeholder="Pesquise sua instituição"
								variant="gray"
								isAsync
								cacheOptions
								defaultOptions={getDefaultInstitutionsOptions()}
								loadOptions={handleFetchInstitutions}
								loadingMessage={() => 'Carregando...'}
								noOptionsMessage={() => 'Nenhuma insitutição encontrada...'}
								instanceId="select-institutions-my-account"
							/>
						</Cell>
						<S.Button
							type="button"
							variant="outlined"
							wrapperCss={S.buttonInstitutionsWrapperCss}
							onClick={() =>
								openModal('createInstitutions', null, { overlayClick: false })
							}
						>
							<FaPlus /> Nova Organização
						</S.Button>
					</Row>
				</Cell>
				<Cell col={3}>
					<InputField
						form={form}
						name="lattes_id"
						type="number"
						label={t('account:labels.lattesId')}
						variant="gray"
						help={
							<>
								<p>
									O ID Lattes poderá ser obtido na{' '}
									<a
										href="http://lattes.cnpq.br/"
										target="_blank"
										rel="noreferrer"
									>
										Plataforma Lattes
									</a>{' '}
									nessa parte do currículo:
								</p>
								<img
									src="/lattes.jpg"
									alt="Currículo Lattes com ID Lattes destacado"
								/>
							</>
						}
					/>
				</Cell>
			</Row>

			<h3>Áreas do conhecimento</h3>
			<Row align="center">
				<CheckBoxField
					name="researcher"
					value={isResearcher}
					label={t('account:labels.researcher')}
					onChange={setIsResearcher}
				/>
			</Row>
			<Row align="flex-start" justify="center">
				{!!isResearcher && userAreas.length <= maxAreaNumber && (
					<Loading
						loading={hasAreasLoading.some((item) => item !== false)}
						alwaysRenderChildren
					>
						{userAreas.map((area, index) => {
							const key = areaKeys
								.map((field) => area[field])
								.filter(Boolean)
								.concat(index)
								.join('-');

							return (
								<Cell key={key} col={userAreas.length}>
									<UserSpecialities
										form={form}
										selected={area}
										index={index}
										onFinishInitialLoading={() => {
											const newValue = [...hasAreasLoading];
											newValue[index] = false;
											setHasAreasLoading(newValue);
										}}
									/>
								</Cell>
							);
						})}

						{userAreas.length < maxAreaNumber && (
							<S.Button
								type="button"
								variant="contained"
								wrapperCss={S.buttonAddAreasWrapperCss}
								alignSelf="flex-start"
								onClick={() => {
									const newUserAreaValues = [...userAreas, emptyArea];
									setUserAreas(newUserAreaValues);
									setValue('areas', newUserAreaValues);
								}}
							>
								+
							</S.Button>
						)}
					</Loading>
				)}
			</Row>

			<Row>
				<Cell align="center">
					<p>{message}</p>
				</Cell>
			</Row>

			<Actions center>
				<S.Button type="submit" disabled={loading}>
					{loading ? t('account:labels.updatingUser') : t('account:labels.updateUser')}
				</S.Button>
			</Actions>
		</>
	);
}