From 77b0ddb8f9d3bfd8d74620f22e0648315706c42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Per=C3=B4nico=20Barbotin?= Date: Sat, 18 Nov 2023 10:19:17 -0300 Subject: [PATCH 01/18] =?UTF-8?q?Formulario=20b=C3=A1sico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UniversiForm/ManageMaterial.less | 220 ++++++++++++++++++ .../UniversiForm/ManageMaterial.tsx | 206 ++++++++++++++++ src/components/UniversiForm/UniversiForm.tsx | 121 ++++++++++ .../ManageMaterial/ManageMaterial.tsx | 14 ++ 4 files changed, 561 insertions(+) create mode 100644 src/components/UniversiForm/ManageMaterial.less create mode 100644 src/components/UniversiForm/ManageMaterial.tsx create mode 100644 src/components/UniversiForm/UniversiForm.tsx diff --git a/src/components/UniversiForm/ManageMaterial.less b/src/components/UniversiForm/ManageMaterial.less new file mode 100644 index 00000000..9241d4ef --- /dev/null +++ b/src/components/UniversiForm/ManageMaterial.less @@ -0,0 +1,220 @@ +@import url(/src/layouts/colors.less); +@import url(/src/layouts/fonts.less); +@import url(/src/layouts/border-radius.less); + +#manage-material { + @left-padding: 2.1rem; + + display: flex; + flex-direction: column; + + background-color: white; + border-radius: var(--border-radius); + + width: 45rem; + overflow: hidden; + + box-sizing: 0px 4px 4px 0px rgba(0, 0, 0, 0.50); + + @header-padding: 1rem; + @header-image-size: 3rem; + + .header { + display: flex; + flex-direction: row; + align-items: center; + + padding: @header-padding @left-padding; + + background-color: @primary-color; + border-bottom: 5px solid @secondary-color; + + color: white; + + gap: 1rem; + + img { + width: @header-image-size; + height: @header-image-size; + } + + .title { + color: @font-color-v1; + } + } + + .manage-material.fields { + max-height: calc(90vh - (@header-padding * 2) - @header-image-size); + overflow: auto; + + .url-wrapper { + display: flex; + flex-direction: row; + align-items: start; + + .type-fieldset { + padding-right: calc(@left-padding / 2); + + .material-type-trigger { + height: 3rem; + padding: .5rem; + aspect-ratio: 1; + + background-color: @card-background-color; + + cursor: pointer; + } + + .type-dropdown-menu { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + + background-color: @card-background-color; + border-radius: @border-radius; + + border: 1px solid @primary-color; + + .type-dropdown-arrow { + fill: @card-background-color + } + + .type-dropdown-option { + outline: none; + + .material-type-icon { + height: calc(4rem - 10px); + cursor: pointer; + padding: 5px; + margin: 5px; + + border-radius: 10px; + + &:hover { + outline: 2px solid @primary-color; + } + } + } + + } + } + + + .url-fieldset { + width: 100%; + padding-left: 0; + } + } + + fieldset { + border: none; + padding: 0 @left-padding; + margin-top: 1rem; + + &:not(:last-child) { + margin-bottom: 1rem; + } + + .field-input { + width: 100%; + background-color: @card-background-color; + } + + input { + font-size: 1rem; + padding: 1rem .5rem; + } + + textarea { + min-height: 2em; + max-height: 8rem; + padding: .5rem; + + resize: vertical; + } + + input, textarea, .material-type-trigger { + border: none; + border-radius: .625rem; + + &:focus { + outline: solid 2px @primary-color; + } + } + + > legend { + display: flex; + flex-direction: row; + align-items: end; + justify-content: space-between; + + width: 100%; + + font-size: 1.25rem; + padding-bottom: 0.75rem; + + .char-counter { + display: inline; + margin-right: .25em; + + font-size: .75em; + } + } + } + + .operation-buttons { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; + margin: 2.1rem; + gap: 1rem; + + > button { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + + border: none; + width: 7.5em; + max-height: 2rem; + padding: .75em 0; + border-radius: .625rem; + + gap: .5rem; + + color: @font-color-v1; + font-size: .9rem; + font-weight: @font-weight-bold; + + cursor: pointer; + will-change: background-color; + + &.cancel-button { + background-color: @secondary-color; + } + + &.submit-button { + &:not(:disabled) { + background-color: @primary-color; + &:hover { + background-color: @secondary-color; + } + } + + &:disabled { + background-color: @font-color-v3; + } + } + + .bi { + width: 1rem; + font-size: 1.2rem; + margin: 0; + } + } + } + } +} diff --git a/src/components/UniversiForm/ManageMaterial.tsx b/src/components/UniversiForm/ManageMaterial.tsx new file mode 100644 index 00000000..db3eb779 --- /dev/null +++ b/src/components/UniversiForm/ManageMaterial.tsx @@ -0,0 +1,206 @@ +import { useContext, useEffect, useState } from "react"; +import Select from 'react-select'; +import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; + +import { CATEGORY_SELECT_STYLES, GroupContext } from "@/pages/Group"; +import UniversimeApi from "@/services/UniversimeApi"; +import { UniversiModal } from "@/components/UniversiModal"; +import { setStateAsValue } from "@/utils/tsxUtils"; +import { type OptionInMenu, renderOption } from "@/utils/dropdownMenuUtils"; + +import type { ContentCreate_ResponseDTO, ContentEdit_ResponseDTO } from "@/services/UniversimeApi/Capacity"; +import type { Category, ContentType } from "@/types/Capacity"; +import "./ManageMaterial.less"; +import { FormInputs, UniversiForm } from "./UniversiForm"; + +export type ManageMaterialProps = { + refreshMaterials: () => any; +} + +const MAX_TITLE_LENGTH = 50; +const MAX_DESC_LENGTH = 150; +const MAX_URL_LENGTH = 100; + +export function ManageMaterial(props: Readonly) { + const context = useContext(GroupContext); + + const [title, setTitle] = useState(context?.editMaterial?.title ?? ""); + const [description, setDescription] = useState(context?.editMaterial?.description ?? ""); + const [url, setUrl] = useState(context?.editMaterial?.url ?? ""); + const [type, setType] = useState(context?.editMaterial?.type ?? "LINK"); + // const [contentsIds, setContentsIds] = useState((context?.editMaterial?.folders ?? []).map(c => c.id)); + const [categoriesIds, setCategoriesIds] = useState((context?.editMaterial?.categories ?? []).map(c => c.id)); + + const [availableCategories, setAvailableCategories] = useState([]); + useEffect(()=>{ + UniversimeApi.Capacity.categoryList() + .then(response => { + if (response.success && response.body) { + setAvailableCategories(response.body.categories); + } + }) + }, []); + + useEffect(() => { + if (context?.editMaterial === undefined) + return; + + setTitle(context?.editMaterial?.title ?? ""); + setDescription(context?.editMaterial?.description ?? ""); + setUrl(context?.editMaterial?.url ?? ""); + setType(context?.editMaterial?.type ?? "LINK"); + // setContentsIds((context?.editMaterial?.folders ?? []).map(c => c.id)); + setCategoriesIds((context?.editMaterial?.categories ?? []).map(c => c.id)); + }, [context?.editMaterial]); + + // prevent later checks + if (!context) + return null; + + if (context.editMaterial === undefined) + return null; + + const canSave = (title.length > 0) && (description.length > 0) && (url.length > 0); + const isNewMaterial = context.editMaterial === null; + + const contentTypeIcon = getContentTypeIcon(type); + + const MATERIAL_TYPE_OPTIONS: [OptionInMenu, ContentType][] = AVAILABLE_MATERIAL_TYPES + .map(t => { + return [{ + text: getContentTypeOptionText(t[0], t[1]), + className: "type-dropdown-option", + onSelect(data){ setType(data); }, + }, t[0]] + }); + + + return +
+ +
+ +

{ isNewMaterial ? "Criar" : "Editar" } material

+
+ + +
+
+ + Título do Material +
+ {title.length} / {MAX_TITLE_LENGTH} +
+
+ +
+ +
+ + Descrição +
+ {description.length} / {MAX_DESC_LENGTH} +
+
+