Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 4232 - new theme toggle design. #4371

Merged
110 changes: 64 additions & 46 deletions apps/web/pages/v2/settings/my-account/appearance.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { GetServerSidePropsContext } from "next";
import { Trans } from "next-i18next";
import { Controller, useForm } from "react-hook-form";

import { useLocale } from "@calcom/lib/hooks/useLocale";
Expand All @@ -10,7 +9,6 @@ import { Button } from "@calcom/ui/v2/core/Button";
import Meta from "@calcom/ui/v2/core/Meta";
import Switch from "@calcom/ui/v2/core/Switch";
import ColorPicker from "@calcom/ui/v2/core/colorpicker";
import Select from "@calcom/ui/v2/core/form/Select";
import { Form } from "@calcom/ui/v2/core/form/fields";
import { getLayout } from "@calcom/ui/v2/core/layouts/SettingsLayout";
import showToast from "@calcom/ui/v2/core/notifications";
Expand All @@ -31,11 +29,6 @@ const AppearanceView = (props: inferSSRProps<typeof getServerSideProps>) => {
},
});

const themeOptions = [
{ value: "light", label: t("light") },
{ value: "dark", label: t("dark") },
];

const formMethods = useForm();

return (
Expand All @@ -44,45 +37,41 @@ const AppearanceView = (props: inferSSRProps<typeof getServerSideProps>) => {
handleSubmit={(values) => {
mutation.mutate({
...values,
theme: values.theme.value,
// Radio values don't support null as values, therefore we convert an empty string
// back to null here.
theme: values.theme || null,
});
}}>
<Meta title="appearance" description="appearance_description" />
<Controller
name="theme"
control={formMethods.control}
defaultValue={user.theme}
render={({ field: { value } }) => (
<>
<div className="flex items-center">
<div>
<p className="font-semibold">{t("follow_system_preferences")}</p>
<p className="text-gray-600">
<Trans i18nKey="system_preference_description">
Automatically adjust theme based on invitee system preferences. Note: This only applies to
the booking pages.
</Trans>
</p>
</div>
<Switch
onCheckedChange={(checked) => formMethods.setValue("theme", checked ? null : themeOptions[0])}
checked={!value}
/>
</div>
<div>
<Select
options={themeOptions}
onChange={(event) => {
if (event) formMethods.setValue("theme", { ...event });
}}
isDisabled={!value}
defaultValue={value || themeOptions[0]}
value={value || themeOptions[0]}
/>
</div>
</>
)}
/>
<div className="mb-6 flex items-center">
<div>
<p className="font-semibold">{t("theme")}</p>
<p className="text-gray-600">{t("theme_applies_note")}</p>
</div>
</div>
<div className="flex flex-col justify-between sm:flex-row">
<ThemeLabel
variant="system"
value={null}
label={t("theme_system")}
defaultChecked={user.theme === null}
register={formMethods.register}
/>
<ThemeLabel
variant="light"
value="light"
label={t("theme_light")}
defaultChecked={user.theme === "light"}
register={formMethods.register}
/>
<ThemeLabel
variant="dark"
value="dark"
label={t("theme_dark")}
defaultChecked={user.theme === "dark"}
register={formMethods.register}
/>
</div>

<hr className="border-1 my-8 border-neutral-200" />
<div className="mb-6 flex items-center">
Expand All @@ -91,7 +80,6 @@ const AppearanceView = (props: inferSSRProps<typeof getServerSideProps>) => {
<p className="text-gray-600">{t("customize_your_brand_colors")}</p>
</div>
</div>

<div className="flex justify-between">
<Controller
name="brandColor"
Expand Down Expand Up @@ -122,7 +110,6 @@ const AppearanceView = (props: inferSSRProps<typeof getServerSideProps>) => {
)}
/>
</div>

{/* TODO future PR to preview brandColors */}
{/* <Button
color="secondary"
Expand All @@ -131,7 +118,6 @@ const AppearanceView = (props: inferSSRProps<typeof getServerSideProps>) => {
onClick={() => window.open(`${WEBAPP_URL}/${user.username}/${user.eventTypes[0].title}`, "_blank")}>
Preview
</Button> */}

<hr className="border-1 my-8 border-neutral-200" />
<Controller
name="hideBranding"
Expand Down Expand Up @@ -204,3 +190,35 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
},
};
};

interface ThemeLabelProps {
variant: "light" | "dark" | "system";
value?: "light" | "dark" | null;
label: string;
defaultChecked?: boolean;
register: any;
}

const ThemeLabel = ({ variant, label, value, defaultChecked, register }: ThemeLabelProps) => {
return (
<label
className="relative mb-4 flex-1 cursor-pointer text-center last:mb-0 last:mr-0 sm:mr-4 sm:mb-0"
htmlFor={`theme-${variant}`}>
<input
className="peer absolute top-8 left-8"
type="radio"
value={value}
id={`theme-${variant}`}
defaultChecked={defaultChecked}
{...register("theme")}
/>
<img
aria-hidden="true"
className="cover relative z-10 w-full rounded-lg outline-2 transition-all peer-checked:outline"
src={`/theme-${variant}.svg`}
alt={`theme ${variant}`}
/>
<p className="mt-2 text-sm font-medium text-gray-600 peer-checked:text-gray-900">{label}</p>
</label>
);
};
7 changes: 6 additions & 1 deletion apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -1187,10 +1187,15 @@
"add_new_form": "Add new form",
"form_description": "Create your form to route a booker",
"copy_link_to_form": "Copy link to form",
"theme": "Theme",
"theme_applies_note": "This only applies to your public booking pages",
"theme_light": "Light",
"theme_dark": "Dark",
"theme_system": "System default",
"back_to_signin": "Back to sign in",
"reset_link_sent": "Reset link sent",
"password_reset_email":"An email is on it’s way to {{email}} with instructions to reset your password.",
"password_reset_leading":"If you did not receive the email soon, check that the email address you entered is correct, check your spam folder or reach out to support if the issue persists.",
"password_updated":"Password updated!",
"pending_payment": "Pending payment"
"pending_payment": "Pending payment",
}
40 changes: 40 additions & 0 deletions apps/web/public/theme-dark.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions apps/web/public/theme-light.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions apps/web/public/theme-system.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.