Refactor: use EditableHeading in event-types/[type].tsx (#3468)

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
Pavel Shapel
2022-07-22 20:51:38 +00:00
committed by GitHub
co-authored by Peer Richelsen
parent 982ca3a783
commit 342efaed31
6 changed files with 39 additions and 106 deletions
-56
View File
@@ -1,56 +0,0 @@
// This component is abstracted from /event-types/[type] for common usecase.
import { PencilIcon } from "@heroicons/react/solid";
import { useState } from "react";
export default function PencilEdit({
value,
// eslint-disable-next-line @typescript-eslint/no-empty-function
onChange = () => {},
placeholder = "",
readOnly = false,
}: {
value: string;
onChange?: (value: string) => void;
placeholder?: string;
readOnly?: boolean;
}) {
const [editIcon, setEditIcon] = useState(true);
const onDivClick = !readOnly
? () => {
return setEditIcon(false);
}
: // eslint-disable-next-line @typescript-eslint/no-empty-function
() => {};
return (
<div className="group relative min-h-[28px] cursor-pointer" onClick={onDivClick}>
{editIcon ? (
<>
<h1
style={{ fontSize: 22, letterSpacing: "-0.0009em" }}
className="inline-block pl-0 text-gray-900 focus:text-black group-hover:text-gray-500">
{value}
</h1>
{!readOnly ? (
<PencilIcon className="ml-1 -mt-1 inline h-4 w-4 text-gray-700 group-hover:text-gray-500" />
) : null}
</>
) : (
<div style={{ marginBottom: -11 }}>
<input
type="text"
autoFocus
style={{ top: -6, fontSize: 22 }}
required
className="relative h-10 w-full cursor-pointer border-none bg-transparent pl-0 text-gray-900 hover:text-gray-700 focus:text-black focus:outline-none focus:ring-0"
placeholder={placeholder}
defaultValue={value}
onBlur={(e) => {
setEditIcon(true);
onChange(e.target.value);
}}
/>
</div>
)}
</div>
);
}
+24 -7
View File
@@ -1,18 +1,31 @@
import { PencilIcon } from "@heroicons/react/solid";
import { useState } from "react";
const EditableHeading = ({ title, onChange }: { title: string; onChange: (value: string) => void }) => {
const [editIcon, setEditIcon] = useState(true);
const EditableHeading = ({
title,
onChange,
placeholder = "",
readOnly = false,
}: {
title: string;
onChange?: (value: string) => void;
placeholder?: string;
readOnly?: boolean;
}) => {
const [isEditing, setIsEditing] = useState(false);
const enableEditing = () => !readOnly && setIsEditing(true);
return (
<div className="group relative cursor-pointer" onClick={() => setEditIcon(false)}>
{editIcon ? (
<div className="group relative cursor-pointer" onClick={enableEditing}>
{!isEditing ? (
<>
<h1
style={{ fontSize: 22, letterSpacing: "-0.0009em" }}
className="inline pl-0 text-gray-900 focus:text-black group-hover:text-gray-500">
className="inline pl-0 normal-case text-gray-900 focus:text-black group-hover:text-gray-500">
{title}
</h1>
<PencilIcon className="ml-1 -mt-1 inline h-4 w-4 text-gray-700 group-hover:text-gray-500" />
{!readOnly ? (
<PencilIcon className="ml-1 -mt-1 inline h-4 w-4 text-gray-700 group-hover:text-gray-500" />
) : null}
</>
) : (
<div style={{ marginBottom: -11 }}>
@@ -22,8 +35,12 @@ const EditableHeading = ({ title, onChange }: { title: string; onChange: (value:
style={{ top: -6, fontSize: 22 }}
required
className="relative h-10 w-full cursor-pointer border-none bg-transparent pl-0 text-gray-900 hover:text-gray-700 focus:text-black focus:outline-none focus:ring-0"
placeholder={placeholder}
defaultValue={title}
onChange={(e) => onChange(e.target.value)}
onBlur={(e) => {
setIsEditing(false);
onChange && onChange(e.target.value);
}}
/>
</div>
)}
+1 -1
View File
@@ -141,7 +141,7 @@ export default function Availability() {
success={({ data }) => {
return (
<Shell
heading={<EditableHeading title={data.schedule.name} onChange={setName} />}
heading={<EditableHeading title={name || data.schedule.name} onChange={setName} />}
subtitle={data.schedule.availability.map((availability) => (
<span key={availability.id}>
{availabilityAsString(availability, i18n.language)}
+6 -33
View File
@@ -67,6 +67,7 @@ import { EditLocationDialog } from "@components/dialog/EditLocationDialog";
import RecurringEventController from "@components/eventtype/RecurringEventController";
import CustomInputTypeForm from "@components/pages/eventtypes/CustomInputTypeForm";
import Badge from "@components/ui/Badge";
import EditableHeading from "@components/ui/EditableHeading";
import InfoBadge from "@components/ui/InfoBadge";
import CheckboxField from "@components/ui/form/CheckboxField";
import CheckedSelect from "@components/ui/form/CheckedSelect";
@@ -310,7 +311,6 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
});
const connectedCalendarsQuery = trpc.useQuery(["viewer.connectedCalendars"]);
const [editIcon, setEditIcon] = useState(true);
const [showLocationModal, setShowLocationModal] = useState(false);
const [selectedLocation, setSelectedLocation] = useState<OptionTypeBase | undefined>(undefined);
const [selectedCustomInput, setSelectedCustomInput] = useState<EventTypeCustomInput | undefined>(undefined);
@@ -318,7 +318,6 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
const [customInputs, setCustomInputs] = useState<EventTypeCustomInput[]>(
eventType.customInputs.sort((a, b) => a.id - b.id) || []
);
const [tokensList, setTokensList] = useState<Array<Token>>([]);
const defaultSeatsPro = 6;
const minSeats = 2;
@@ -439,6 +438,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
const formMethods = useForm<FormValues>({
defaultValues: {
title: eventType.title,
locations: eventType.locations || [],
recurringEvent: eventType.recurringEvent || null,
schedule: eventType.schedule?.id,
@@ -846,37 +846,10 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<Shell
title={t("event_type_title", { eventTypeTitle: eventType.title })}
heading={
<div className="group relative cursor-pointer" onClick={() => setEditIcon(false)}>
{editIcon ? (
<>
<h1
style={{ fontSize: 22, letterSpacing: "-0.0009em" }}
className="inline pl-0 text-gray-900 focus:text-black group-hover:text-gray-500">
{formMethods.getValues("title") && formMethods.getValues("title") !== ""
? formMethods.getValues("title")
: eventType.title}
</h1>
<PencilIcon className="ml-1 -mt-1 inline h-4 w-4 text-gray-700 group-hover:text-gray-500" />
</>
) : (
<div style={{ marginBottom: -11 }}>
<input
type="text"
autoFocus
style={{ top: -6, fontSize: 22 }}
required
className="relative h-10 w-full cursor-pointer border-none bg-transparent pl-0 text-gray-900 hover:text-gray-700 focus:text-black focus:outline-none focus:ring-0"
placeholder={t("quick_chat")}
{...formMethods.register("title")}
defaultValue={eventType.title}
onBlur={() => {
setEditIcon(true);
formMethods.getValues("title") === "" && formMethods.setValue("title", eventType.title);
}}
/>
</div>
)}
</div>
<EditableHeading
title={formMethods.watch("title")}
onChange={(value) => formMethods.setValue("title", value)}
/>
}
subtitle={eventType.description || ""}>
<ClientSuspense fallback={<Loader />}>
@@ -14,7 +14,7 @@ import { Form, TextArea } from "@calcom/ui/form/fields";
import { inferSSRProps } from "@lib/types/inferSSRProps";
import PencilEdit from "@components/PencilEdit";
import EditableHeading from "@components/ui/EditableHeading";
import RoutingShell from "../../components/RoutingShell";
import SideBar from "../../components/SideBar";
@@ -285,12 +285,8 @@ export default function FormEdit({
form={form}
appUrl={appUrl}
heading={
<PencilEdit
value={
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
hookForm.watch("name")
}
<EditableHeading
title={hookForm.watch("name")}
onChange={(value) => {
hookForm.setValue("name", value);
}}
@@ -13,7 +13,7 @@ import { inferSSRProps } from "@calcom/types/inferSSRProps";
import { Button } from "@calcom/ui";
import { Label } from "@calcom/ui/form/fields";
import PencilEdit from "@components/PencilEdit";
import EditableHeading from "@components/ui/EditableHeading";
import { SelectWithValidation as Select } from "@components/ui/form/Select";
import RoutingShell from "../../components/RoutingShell";
@@ -466,7 +466,10 @@ export default function RouteBuilder({
appUrl,
}: inferSSRProps<typeof getServerSideProps> & { appUrl: string }) {
return (
<RoutingShell appUrl={appUrl} heading={<PencilEdit value={form?.name} readOnly={true} />} form={form}>
<RoutingShell
appUrl={appUrl}
heading={<EditableHeading title={form?.name} readOnly={true} />}
form={form}>
<div className="route-config">
<Routes form={form} appUrl={appUrl} />
</div>