Add "light-brand" and "dark-brand" colors (add a second color picker) (#2028)
* init dark brand color addition * added dark mode css vars * added contrast brand colors * minor fixes * added dark branding to loader, button Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
parent
ce0c8347fb
commit
8c4eed2bbc
30 changed files with 96 additions and 35 deletions
|
@ -18,7 +18,7 @@ export default function AddToHomescreen() {
|
|||
<div className="rounded-lg p-2 shadow-lg sm:p-3" style={{ background: "#2F333D" }}>
|
||||
<div className="flex flex-wrap items-center justify-between">
|
||||
<div className="flex w-0 flex-1 items-center">
|
||||
<span className="bg-brand text-brandcontrast flex rounded-lg bg-opacity-30 p-2">
|
||||
<span className="bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast flex rounded-lg bg-opacity-30 p-2">
|
||||
<svg
|
||||
className="h-7 w-7 fill-current text-indigo-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
@ -2,6 +2,7 @@ import { useEffect } from "react";
|
|||
|
||||
const brandColor = "#292929";
|
||||
const brandTextColor = "#ffffff";
|
||||
const darkBrandColor = "#fafafa";
|
||||
|
||||
export function colorNameToHex(color: string) {
|
||||
const colors = {
|
||||
|
@ -174,8 +175,8 @@ function hexToRGB(hex: string) {
|
|||
return [parseInt(color.slice(0, 2), 16), parseInt(color.slice(2, 4), 16), parseInt(color.slice(4, 6), 16)];
|
||||
}
|
||||
|
||||
function getContrastingTextColor(bgColor: string | null): string {
|
||||
bgColor = bgColor == "" || bgColor == null ? brandColor : bgColor;
|
||||
function getContrastingTextColor(bgColor: string | null, dark: boolean): string {
|
||||
bgColor = bgColor == "" || bgColor == null ? (dark ? darkBrandColor : brandColor) : bgColor;
|
||||
const rgb = hexToRGB(bgColor);
|
||||
const whiteContrastRatio = computeContrastRatio(rgb, [255, 255, 255]);
|
||||
const blackContrastRatio = computeContrastRatio(rgb, [41, 41, 41]); //#292929
|
||||
|
@ -191,18 +192,38 @@ export function isValidHexCode(val: string | null) {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function fallBackHex(val: string | null): string {
|
||||
export function fallBackHex(val: string | null, dark: boolean): string {
|
||||
if (val) if (colorNameToHex(val)) return colorNameToHex(val) as string;
|
||||
return brandColor;
|
||||
return dark ? darkBrandColor : brandColor;
|
||||
}
|
||||
|
||||
const BrandColor = ({ val = brandColor }: { val: string | undefined | null }) => {
|
||||
const BrandColor = ({
|
||||
lightVal = brandColor,
|
||||
darkVal = darkBrandColor,
|
||||
}: {
|
||||
lightVal: string | undefined | null;
|
||||
darkVal: string | undefined | null;
|
||||
}) => {
|
||||
// ensure acceptable hex-code
|
||||
val = isValidHexCode(val) ? (val?.indexOf("#") === 0 ? val : "#" + val) : fallBackHex(val);
|
||||
lightVal = isValidHexCode(lightVal)
|
||||
? lightVal?.indexOf("#") === 0
|
||||
? lightVal
|
||||
: "#" + lightVal
|
||||
: fallBackHex(lightVal, false);
|
||||
darkVal = isValidHexCode(darkVal)
|
||||
? darkVal?.indexOf("#") === 0
|
||||
? darkVal
|
||||
: "#" + darkVal
|
||||
: fallBackHex(darkVal, true);
|
||||
useEffect(() => {
|
||||
document.documentElement.style.setProperty("--brand-color", val);
|
||||
document.documentElement.style.setProperty("--brand-text-color", getContrastingTextColor(val));
|
||||
}, [val]);
|
||||
document.documentElement.style.setProperty("--brand-color", lightVal);
|
||||
document.documentElement.style.setProperty("--brand-text-color", getContrastingTextColor(lightVal, true));
|
||||
document.documentElement.style.setProperty("--brand-color-dark-mode", darkVal);
|
||||
document.documentElement.style.setProperty(
|
||||
"--brand-text-color-dark-mode",
|
||||
getContrastingTextColor(darkVal, true)
|
||||
);
|
||||
}, [lightVal, darkVal]);
|
||||
return null;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export default function Loader() {
|
||||
return (
|
||||
<div className="loader border-brand dark:border-white">
|
||||
<span className="loader-inner bg-brand dark:bg-white"></span>
|
||||
<div className="loader border-brand dark:border-darkmodebrand">
|
||||
<span className="loader-inner bg-brand dark:bg-darkmodebrand"></span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ export default function Shell(props: {
|
|||
}
|
||||
return (
|
||||
<>
|
||||
<CustomBranding val={user?.brandColor} />
|
||||
<CustomBranding lightVal={user?.brandColor} darkVal={user?.darkBrandColor} />
|
||||
<HeadSeo
|
||||
title={pageTitle ?? "Cal.com"}
|
||||
description={props.subtitle ? props.subtitle?.toString() : ""}
|
||||
|
|
|
@ -101,7 +101,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
|
|||
<Link href={bookingUrl}>
|
||||
<a
|
||||
className={classNames(
|
||||
"text-primary-500 hover:bg-brand hover:text-brandcontrast dark:hover:bg-brand dark:hover:text-brandcontrast mb-2 block rounded-sm border bg-white py-4 font-medium hover:text-white dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 dark:hover:border-black",
|
||||
"text-primary-500 hover:bg-brand hover:text-brandcontrast dark:hover:bg-darkmodebrand dark:hover:text-darkmodebrandcontrast mb-2 block rounded-sm border bg-white py-4 font-medium hover:text-white dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 dark:hover:border-black",
|
||||
brand === "#fff" || brand === "#ffffff" ? "border-brandcontrast" : "border-brand"
|
||||
)}
|
||||
data-testid="time">
|
||||
|
|
|
@ -278,7 +278,7 @@ function DatePicker({
|
|||
"hover:border-brand hover:border dark:hover:border-white",
|
||||
day.disabled ? "cursor-default font-light text-gray-400 hover:border-0" : "font-medium",
|
||||
date && date.isSame(browsingDate.date(day.date), "day")
|
||||
? "bg-brand text-brandcontrast"
|
||||
? "bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast"
|
||||
: !day.disabled
|
||||
? " bg-gray-100 dark:bg-gray-600 dark:text-white"
|
||||
: ""
|
||||
|
|
|
@ -46,7 +46,9 @@ const TimeOptions: FC<Props> = ({ onToggle24hClock, onSelectTimeZone }) => {
|
|||
checked={is24hClock}
|
||||
onChange={handle24hClockToggle}
|
||||
className={classNames(
|
||||
is24hClock ? "bg-brand text-brandcontrast" : "bg-gray-200 dark:bg-gray-600",
|
||||
is24hClock
|
||||
? "bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast"
|
||||
: "bg-gray-200 dark:bg-gray-600",
|
||||
"relative inline-flex h-5 w-8 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2"
|
||||
)}>
|
||||
<span className="sr-only">{t("use_setting")}</span>
|
||||
|
|
|
@ -110,7 +110,7 @@ const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => {
|
|||
username={profile.slug || undefined}
|
||||
// avatar={profile.image || undefined}
|
||||
/>
|
||||
<CustomBranding val={profile.brandColor} />
|
||||
<CustomBranding lightVal={profile.brandColor} darkVal={profile.darkBrandColor} />
|
||||
<div>
|
||||
<main
|
||||
className={
|
||||
|
|
|
@ -280,7 +280,7 @@ const BookingPage = (props: BookingPageProps) => {
|
|||
</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<CustomBranding val={props.profile.brandColor} />
|
||||
<CustomBranding lightVal={props.profile.brandColor} darkVal={props.profile.darkBrandColor} />
|
||||
<main className="mx-auto my-0 max-w-3xl rounded-sm sm:my-24 sm:border sm:dark:border-gray-600">
|
||||
{isReady && (
|
||||
<div className="overflow-hidden border border-gray-200 bg-white dark:border-0 dark:bg-neutral-900 sm:rounded-sm">
|
||||
|
|
|
@ -4,7 +4,7 @@ import React from "react";
|
|||
const TwoFactorModalHeader = ({ title, description }: { title: string; description: string }) => {
|
||||
return (
|
||||
<div className="mb-4 sm:flex sm:items-start">
|
||||
<div className="bg-brand text-brandcontrast mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<div className="bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<ShieldCheckIcon className="h-6 w-6 text-black" />
|
||||
</div>
|
||||
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
|
|
|
@ -64,7 +64,7 @@ export default function MemberInvitationModal(props: { team: TeamWithMembers | n
|
|||
|
||||
<div className="inline-block transform rounded-lg bg-white px-4 pt-5 pb-4 text-left align-bottom shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6 sm:align-middle">
|
||||
<div className="mb-4 sm:flex sm:items-start">
|
||||
<div className="bg-brand text-brandcontrast mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<div className="bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<UserIcon className="text-brandcontrast h-6 w-6" />
|
||||
</div>
|
||||
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||
|
|
|
@ -33,7 +33,7 @@ export const WeekdaySelect = (props: WeekdaySelectProps) => {
|
|||
toggleDay(idx);
|
||||
}}
|
||||
className={`
|
||||
bg-brand text-brandcontrast
|
||||
bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast
|
||||
h-10 w-10 rounded px-3 py-1 focus:outline-none
|
||||
${activeDays[idx + 1] ? "rounded-r-none" : ""}
|
||||
${activeDays[idx - 1] ? "rounded-l-none" : ""}
|
||||
|
|
|
@ -62,7 +62,9 @@ export type ColorPickerProps = {
|
|||
};
|
||||
|
||||
const ColorPicker = (props: ColorPickerProps) => {
|
||||
const init = !isValidHexCode(props.defaultValue) ? fallBackHex(props.defaultValue) : props.defaultValue;
|
||||
const init = !isValidHexCode(props.defaultValue)
|
||||
? fallBackHex(props.defaultValue, false)
|
||||
: props.defaultValue;
|
||||
const [color, setColor] = useState(init);
|
||||
const [isOpen, toggle] = useState(false);
|
||||
const popover = useRef() as React.MutableRefObject<HTMLInputElement>;
|
||||
|
|
|
@ -59,7 +59,7 @@ export default function TeamAvailabilityTimes(props: Props) {
|
|||
{times.map((time) => (
|
||||
<div key={time.format()} className="flex flex-row items-center">
|
||||
<a
|
||||
className="min-w-48 border-brand text-primary-500 hover:bg-brand hover:text-brandcontrast mb-2 mr-3 block flex-grow rounded-sm border bg-white py-2 text-center font-medium dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 dark:hover:border-black dark:hover:bg-black dark:hover:text-white"
|
||||
className="min-w-48 border-brand text-primary-500 hover:bg-brand hover:text-brandcontrast dark:hover:bg-darkmodebrand dark:hover:text-darkmodebrandcontrast mb-2 mr-3 block flex-grow rounded-sm border bg-white py-2 text-center font-medium dark:border-transparent dark:bg-gray-600 dark:text-neutral-200 dark:hover:border-black dark:hover:bg-black dark:hover:text-white"
|
||||
data-testid="time">
|
||||
{time.format("HH:mm")}
|
||||
</a>
|
||||
|
|
|
@ -79,6 +79,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
availability: true,
|
||||
hideBranding: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
theme: true,
|
||||
plan: true,
|
||||
eventTypes: {
|
||||
|
@ -192,6 +193,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
theme: user.theme,
|
||||
weekStart: user.weekStart,
|
||||
brandColor: user.brandColor,
|
||||
darkBrandColor: user.darkBrandColor,
|
||||
},
|
||||
date: dateParam,
|
||||
eventType: eventTypeObject,
|
||||
|
|
|
@ -37,6 +37,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
avatar: true,
|
||||
theme: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -140,6 +141,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
image: user.avatar,
|
||||
theme: user.theme,
|
||||
brandColor: user.brandColor,
|
||||
darkBrandColor: user.darkBrandColor,
|
||||
},
|
||||
eventType: eventTypeObject,
|
||||
booking,
|
||||
|
|
|
@ -64,8 +64,8 @@ const AvailabilityView = ({ user }: { user: User }) => {
|
|||
/>
|
||||
<small className="block text-neutral-400">{t("hover_over_bold_times_tip")}</small>
|
||||
<div className="mt-4 space-y-4">
|
||||
<div className="bg-brand overflow-hidden rounded-sm">
|
||||
<div className="text-brandcontrast px-4 py-2 sm:px-6">
|
||||
<div className="bg-brand dark:bg-darkmodebrand overflow-hidden rounded-sm">
|
||||
<div className="text-brandcontrast dark:text-darkmodebrandcontrast px-4 py-2 sm:px-6">
|
||||
{t("your_day_starts_at")} {convertMinsToHrsMins(user.startTime)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -94,8 +94,8 @@ const AvailabilityView = ({ user }: { user: User }) => {
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="bg-brand overflow-hidden rounded-sm">
|
||||
<div className="text-brandcontrast px-4 py-2 sm:px-6">
|
||||
<div className="bg-brand dark:bg-darkmodebrand overflow-hidden rounded-sm">
|
||||
<div className="text-brandcontrast dark:text-darkmodebrandcontrast px-4 py-2 sm:px-6">
|
||||
{t("your_day_ends_at")} {convertMinsToHrsMins(user.endTime)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -35,7 +35,7 @@ export default function Type(props: inferSSRProps<typeof getServerSideProps>) {
|
|||
title={`${t("cancel")} ${props.booking && props.booking.title} | ${props.profile?.name}`}
|
||||
description={`${t("cancel")} ${props.booking && props.booking.title} | ${props.profile?.name}`}
|
||||
/>
|
||||
<CustomBranding val={props.profile?.brandColor} />
|
||||
<CustomBranding lightVal={props.profile?.brandColor} darkVal={props.profile?.darkBrandColor} />
|
||||
<main className="mx-auto my-24 max-w-3xl">
|
||||
<div className="fixed inset-0 z-50 overflow-y-auto">
|
||||
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||
|
@ -179,6 +179,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
username: true,
|
||||
name: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
},
|
||||
},
|
||||
eventType: {
|
||||
|
@ -210,6 +211,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
name: booking.eventType?.team?.name || booking.user?.name || null,
|
||||
slug: booking.eventType?.team?.slug || booking.user?.username || null,
|
||||
brandColor: booking.user?.brandColor || null,
|
||||
darkBrandColor: booking.user?.darkBrandColor || null,
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
|
@ -176,6 +176,7 @@ function SettingsView(props: ComponentProps<typeof Settings> & { localeProp: str
|
|||
const [hasErrors, setHasErrors] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const [brandColor, setBrandColor] = useState(props.user.brandColor);
|
||||
const [darkBrandColor, setDarkBrandColor] = useState(props.user.darkBrandColor);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.user.theme) return;
|
||||
|
@ -194,6 +195,7 @@ function SettingsView(props: ComponentProps<typeof Settings> & { localeProp: str
|
|||
const enteredDescription = descriptionRef.current.value;
|
||||
const enteredAvatar = avatarRef.current.value;
|
||||
const enteredBrandColor = brandColor;
|
||||
const enteredDarkBrandColor = darkBrandColor;
|
||||
const enteredTimeZone = typeof selectedTimeZone === "string" ? selectedTimeZone : selectedTimeZone.value;
|
||||
const enteredWeekStartDay = selectedWeekStartDay.value;
|
||||
const enteredHideBranding = hideBrandingRef.current.checked;
|
||||
|
@ -213,6 +215,7 @@ function SettingsView(props: ComponentProps<typeof Settings> & { localeProp: str
|
|||
hideBranding: enteredHideBranding,
|
||||
theme: asStringOrNull(selectedTheme?.value),
|
||||
brandColor: enteredBrandColor,
|
||||
darkBrandColor: enteredDarkBrandColor,
|
||||
locale: enteredLanguage,
|
||||
timeFormat: enteredTimeFormat,
|
||||
});
|
||||
|
@ -424,11 +427,19 @@ function SettingsView(props: ComponentProps<typeof Settings> & { localeProp: str
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="brandColor" className="block text-sm font-medium text-gray-700">
|
||||
{t("brand_color")}
|
||||
</label>
|
||||
<ColorPicker defaultValue={props.user.brandColor} onChange={setBrandColor} />
|
||||
<div className="block rtl:space-x-reverse sm:flex sm:space-x-2">
|
||||
<div className="mb-6 w-full sm:w-1/2">
|
||||
<label htmlFor="brandColor" className="block text-sm font-medium text-gray-700">
|
||||
{t("light_brand_color")}
|
||||
</label>
|
||||
<ColorPicker defaultValue={props.user.brandColor} onChange={setBrandColor} />
|
||||
</div>
|
||||
<div className="mb-6 w-full sm:w-1/2">
|
||||
<label htmlFor="darkBrandColor" className="block text-sm font-medium text-gray-700">
|
||||
{t("dark_brand_color")}
|
||||
</label>
|
||||
<ColorPicker defaultValue={props.user.darkBrandColor} onChange={setDarkBrandColor} />
|
||||
</div>
|
||||
<hr className="mt-6" />
|
||||
</div>
|
||||
<div>
|
||||
|
@ -524,6 +535,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
theme: true,
|
||||
plan: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
metadata: true,
|
||||
timeFormat: true,
|
||||
},
|
||||
|
|
|
@ -96,7 +96,7 @@ export default function Success(props: inferSSRProps<typeof getServerSideProps>)
|
|||
title={needsConfirmation ? t("booking_submitted") : t("booking_confirmed")}
|
||||
description={needsConfirmation ? t("booking_submitted") : t("booking_confirmed")}
|
||||
/>
|
||||
<CustomBranding val={props.profile.brandColor} />
|
||||
<CustomBranding lightVal={props.profile.brandColor} darkVal={props.profile.darkBrandColor} />
|
||||
<main className="mx-auto max-w-3xl py-24">
|
||||
<div className="fixed inset-0 z-50 overflow-y-auto">
|
||||
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||
|
@ -320,6 +320,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
plan: true,
|
||||
theme: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
},
|
||||
},
|
||||
team: {
|
||||
|
@ -348,6 +349,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
plan: true,
|
||||
theme: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
},
|
||||
});
|
||||
if (user) {
|
||||
|
@ -365,6 +367,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
name: eventType.team?.name || eventType.users[0]?.name || null,
|
||||
theme: (!eventType.team?.name && eventType.users[0]?.theme) || null,
|
||||
brandColor: eventType.team ? null : eventType.users[0].brandColor,
|
||||
darkBrandColor: eventType.team ? null : eventType.users[0].darkBrandColor,
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
|
@ -48,6 +48,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
hideBranding: true,
|
||||
plan: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
},
|
||||
},
|
||||
title: true,
|
||||
|
@ -105,6 +106,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
theme: null,
|
||||
weekStart: "Sunday",
|
||||
brandColor: "" /* TODO: Add a way to set a brand color for Teams */,
|
||||
darkBrandColor: "" /* TODO: Add a way to set a brand color for Teams */,
|
||||
},
|
||||
date: dateParam,
|
||||
eventType: eventTypeObject,
|
||||
|
|
|
@ -102,6 +102,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
|||
image: eventTypeObject.team?.logo || null,
|
||||
theme: null /* Teams don't have a theme, and `BookingPage` uses it */,
|
||||
brandColor: null /* Teams don't have a brandColor, and `BookingPage` uses it */,
|
||||
darkBrandColor: null /* Teams don't have a darkBrandColor, and `BookingPage` uses it */,
|
||||
},
|
||||
eventType: eventTypeObject,
|
||||
booking,
|
||||
|
|
|
@ -513,6 +513,8 @@
|
|||
"first_day_of_week": "First Day of Week",
|
||||
"single_theme": "Single Theme",
|
||||
"brand_color": "Brand Color",
|
||||
"light_brand_color": "Brand Color (Light Theme)",
|
||||
"dark_brand_color": "Brand Color (Dark Theme)",
|
||||
"file_not_named": "File is not named [idOrSlug]/[user]",
|
||||
"create_team": "Create Team",
|
||||
"name": "Name",
|
||||
|
|
|
@ -45,6 +45,7 @@ async function getUserFromSession({
|
|||
twoFactorEnabled: true,
|
||||
identityProvider: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
plan: true,
|
||||
away: true,
|
||||
credentials: {
|
||||
|
|
|
@ -83,6 +83,7 @@ const loggedInViewerRouter = createProtectedRouter()
|
|||
twoFactorEnabled: user.twoFactorEnabled,
|
||||
identityProvider: user.identityProvider,
|
||||
brandColor: user.brandColor,
|
||||
darkBrandColor: user.darkBrandColor,
|
||||
plan: user.plan,
|
||||
away: user.away,
|
||||
};
|
||||
|
@ -616,6 +617,7 @@ const loggedInViewerRouter = createProtectedRouter()
|
|||
weekStart: z.string().optional(),
|
||||
hideBranding: z.boolean().optional(),
|
||||
brandColor: z.string().optional(),
|
||||
darkBrandColor: z.string().optional(),
|
||||
theme: z.string().optional().nullable(),
|
||||
completedOnboarding: z.boolean().optional(),
|
||||
locale: z.string().optional(),
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
:root {
|
||||
--brand-color: #292929;
|
||||
--brand-text-color: #ffffff;
|
||||
--brand-color-dark-mode: #fafafa;
|
||||
--brand-text-color-dark-mode: #292929;
|
||||
}
|
||||
|
||||
/* PhoneInput dark-mode overrides (it would add a lot of boilerplate to do this in JavaScript) */
|
||||
|
|
|
@ -14,6 +14,8 @@ module.exports = {
|
|||
/* your primary brand color */
|
||||
brand: "var(--brand-color)",
|
||||
brandcontrast: "var(--brand-text-color)",
|
||||
darkmodebrand: "var(--brand-color-dark-mode)",
|
||||
darkmodebrandcontrast: "var(--brand-text-color-dark-mode)",
|
||||
black: "#111111",
|
||||
gray: {
|
||||
50: "#F8F8F8",
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "users" ADD COLUMN "darkBrandColor" TEXT NOT NULL DEFAULT E'#fafafa';
|
|
@ -142,6 +142,7 @@ model User {
|
|||
Schedule Schedule[]
|
||||
webhooks Webhook[]
|
||||
brandColor String @default("#292929")
|
||||
darkBrandColor String @default("#fafafa")
|
||||
// the location where the events will end up
|
||||
destinationCalendar DestinationCalendar?
|
||||
away Boolean @default(false)
|
||||
|
|
|
@ -65,7 +65,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonPr
|
|||
color === "primary" &&
|
||||
(disabled
|
||||
? "border border-transparent bg-gray-400 text-white"
|
||||
: "border border-transparent dark:text-brandcontrast text-brandcontrast bg-brand dark:bg-brand hover:bg-opacity-90 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-neutral-900"),
|
||||
: "border border-transparent dark:text-darkmodebrandcontrast text-brandcontrast bg-brand dark:bg-darkmodebrand hover:bg-opacity-90 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-neutral-900"),
|
||||
color === "secondary" &&
|
||||
(disabled
|
||||
? "border border-gray-200 text-gray-400 bg-white"
|
||||
|
|
Loading…
Reference in a new issue