Merge branch 'main' into chor/text-colors+weights
This commit is contained in:
commit
c5077f098f
|
@ -44,13 +44,15 @@ export default function InstalledAppsLayout({
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
|
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
|
||||||
|
const variant: typeof InstalledAppVariants[number] = "payment";
|
||||||
|
|
||||||
const query = trpc.viewer.integrations.useQuery({
|
const query = trpc.viewer.integrations.useQuery({
|
||||||
variant: InstalledAppVariants.payment,
|
variant,
|
||||||
onlyInstalled: true,
|
onlyInstalled: true,
|
||||||
});
|
});
|
||||||
let actualTabs = tabs;
|
let actualTabs = tabs;
|
||||||
if (query.data?.items.length === 0) {
|
if (query.data?.items.length === 0) {
|
||||||
actualTabs = tabs.filter((tab) => tab.name !== InstalledAppVariants.payment);
|
actualTabs = tabs.filter((tab) => tab.name !== variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// lets refactor and move this into packages/lib/hooks/
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
const useMediaQuery = (query: string) => {
|
const useMediaQuery = (query: string) => {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { IdentityProvider } from "@prisma/client";
|
import { IdentityProvider } from "@prisma/client";
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
import { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
|
import { hashPassword } from "@calcom/lib/auth";
|
||||||
import { closeComUpsertTeamUser } from "@calcom/lib/sync/SyncServiceManager";
|
import { closeComUpsertTeamUser } from "@calcom/lib/sync/SyncServiceManager";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
|
|
||||||
import { hashPassword } from "@lib/auth";
|
|
||||||
import slugify from "@lib/slugify";
|
import slugify from "@lib/slugify";
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
|
|
@ -92,8 +92,8 @@ function ConnectOrDisconnectIntegrationButton(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IntegrationsContainerProps {
|
interface IntegrationsContainerProps {
|
||||||
variant?: keyof typeof InstalledAppVariants;
|
variant?: typeof InstalledAppVariants[number];
|
||||||
exclude?: (keyof typeof InstalledAppVariants)[];
|
exclude?: typeof InstalledAppVariants[number][];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IntegrationsListProps {
|
interface IntegrationsListProps {
|
||||||
|
@ -143,8 +143,10 @@ const IntegrationsContainer = ({ variant, exclude }: IntegrationsContainerProps)
|
||||||
automation: Icon.FiShare2,
|
automation: Icon.FiShare2,
|
||||||
analytics: Icon.FiBarChart,
|
analytics: Icon.FiBarChart,
|
||||||
payment: Icon.FiCreditCard,
|
payment: Icon.FiCreditCard,
|
||||||
|
web3: Icon.FiBarChart,
|
||||||
other: Icon.FiGrid,
|
other: Icon.FiGrid,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryCell
|
<QueryCell
|
||||||
query={query}
|
query={query}
|
||||||
|
@ -198,31 +200,29 @@ const IntegrationsContainer = ({ variant, exclude }: IntegrationsContainerProps)
|
||||||
};
|
};
|
||||||
|
|
||||||
const querySchema = z.object({
|
const querySchema = z.object({
|
||||||
category: z.nativeEnum(InstalledAppVariants),
|
category: z.enum(InstalledAppVariants),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type querySchemaType = z.infer<typeof querySchema>;
|
||||||
|
|
||||||
export default function InstalledApps() {
|
export default function InstalledApps() {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const category = router.query.category;
|
const category = router.query.category as querySchemaType["category"];
|
||||||
|
const categoryList: querySchemaType["category"][] = [
|
||||||
|
"payment",
|
||||||
|
"conferencing",
|
||||||
|
"automation",
|
||||||
|
"analytics",
|
||||||
|
"web3",
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InstalledAppsLayout heading={t("installed_apps")} subtitle={t("manage_your_connected_apps")}>
|
<InstalledAppsLayout heading={t("installed_apps")} subtitle={t("manage_your_connected_apps")}>
|
||||||
{(category === InstalledAppVariants.payment || category === InstalledAppVariants.conferencing) && (
|
{categoryList.includes(category) && <IntegrationsContainer variant={category} />}
|
||||||
<IntegrationsContainer variant={category} />
|
{category === "calendar" && <CalendarListContainer />}
|
||||||
)}
|
{category === "other" && (
|
||||||
{(category === InstalledAppVariants.automation || category === InstalledAppVariants.analytics) && (
|
<IntegrationsContainer variant={category} exclude={[...categoryList, "calendar"]} />
|
||||||
<IntegrationsContainer variant={category} />
|
|
||||||
)}
|
|
||||||
{category === InstalledAppVariants.calendar && <CalendarListContainer />}
|
|
||||||
{category === InstalledAppVariants.other && (
|
|
||||||
<IntegrationsContainer
|
|
||||||
exclude={[
|
|
||||||
InstalledAppVariants.conferencing,
|
|
||||||
InstalledAppVariants.calendar,
|
|
||||||
InstalledAppVariants.analytics,
|
|
||||||
InstalledAppVariants.automation,
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</InstalledAppsLayout>
|
</InstalledAppsLayout>
|
||||||
);
|
);
|
||||||
|
|
|
@ -799,12 +799,14 @@
|
||||||
"no_category_apps_description_analytics": "Add an analytics app for your booking pages",
|
"no_category_apps_description_analytics": "Add an analytics app for your booking pages",
|
||||||
"no_category_apps_description_automation": "Add an automation app to use",
|
"no_category_apps_description_automation": "Add an automation app to use",
|
||||||
"no_category_apps_description_other": "Add any other type of app to do all sorts of things",
|
"no_category_apps_description_other": "Add any other type of app to do all sorts of things",
|
||||||
|
"no_category_apps_description_web3": "Add a web3 app for your booking pages",
|
||||||
"installed_app_calendar_description": "Set the calendars to check for conflicts to prevent double bookings.",
|
"installed_app_calendar_description": "Set the calendars to check for conflicts to prevent double bookings.",
|
||||||
"installed_app_conferencing_description": "Add your favourite video conferencing apps for your meetings",
|
"installed_app_conferencing_description": "Add your favourite video conferencing apps for your meetings",
|
||||||
"installed_app_payment_description": "Configure which payment processing services to use when charging your clients.",
|
"installed_app_payment_description": "Configure which payment processing services to use when charging your clients.",
|
||||||
"installed_app_analytics_description": "Configure which analytics apps to use for your booking pages",
|
"installed_app_analytics_description": "Configure which analytics apps to use for your booking pages",
|
||||||
"installed_app_other_description": "All your installed apps from other categories.",
|
"installed_app_other_description": "All your installed apps from other categories.",
|
||||||
"installed_app_automation_description": "Configure which automation apps to use",
|
"installed_app_automation_description": "Configure which automation apps to use",
|
||||||
|
"installed_app_web3_description": "Configure which web3 apps to use for your booking pages",
|
||||||
"analytics": "Analytics",
|
"analytics": "Analytics",
|
||||||
"empty_installed_apps_headline": "No apps installed",
|
"empty_installed_apps_headline": "No apps installed",
|
||||||
"empty_installed_apps_description": "Apps enable you to enhance your workflow and improve your scheduling life significantly.",
|
"empty_installed_apps_description": "Apps enable you to enhance your workflow and improve your scheduling life significantly.",
|
||||||
|
@ -1217,6 +1219,7 @@
|
||||||
"connect_automation_apps": "Connect automation apps",
|
"connect_automation_apps": "Connect automation apps",
|
||||||
"connect_analytics_apps": "Connect analytics apps",
|
"connect_analytics_apps": "Connect analytics apps",
|
||||||
"connect_other_apps": "Connect other apps",
|
"connect_other_apps": "Connect other apps",
|
||||||
|
"connect_web3_apps": "Connect web3 apps",
|
||||||
"current_step_of_total": "Step {{currentStep}} of {{maxSteps}}",
|
"current_step_of_total": "Step {{currentStep}} of {{maxSteps}}",
|
||||||
"add_variable": "Add variable",
|
"add_variable": "Add variable",
|
||||||
"custom_phone_number": "Custom phone number",
|
"custom_phone_number": "Custom phone number",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import z from "zod";
|
||||||
|
|
||||||
import { InstalledAppVariants } from "../utils";
|
import { InstalledAppVariants } from "../utils";
|
||||||
|
|
||||||
const variantSchema = z.nativeEnum(InstalledAppVariants);
|
const variantSchema = z.enum(InstalledAppVariants);
|
||||||
|
|
||||||
export default function getInstalledAppPath(
|
export default function getInstalledAppPath(
|
||||||
{ variant, slug }: { variant?: string; slug?: string },
|
{ variant, slug }: { variant?: string; slug?: string },
|
||||||
|
|
|
@ -273,7 +273,7 @@ export default class GoogleCalendarService implements Calendar {
|
||||||
auth: myGoogleAuth,
|
auth: myGoogleAuth,
|
||||||
calendarId: calendarId ? calendarId : defaultCalendarId,
|
calendarId: calendarId ? calendarId : defaultCalendarId,
|
||||||
eventId: uid,
|
eventId: uid,
|
||||||
sendNotifications: true,
|
sendNotifications: false,
|
||||||
sendUpdates: "all",
|
sendUpdates: "all",
|
||||||
},
|
},
|
||||||
function (err: GoogleCalError | null, event) {
|
function (err: GoogleCalError | null, event) {
|
||||||
|
|
|
@ -31,14 +31,15 @@ const credentialData = Prisma.validator<Prisma.CredentialArgs>()({
|
||||||
|
|
||||||
export type CredentialData = Prisma.CredentialGetPayload<typeof credentialData>;
|
export type CredentialData = Prisma.CredentialGetPayload<typeof credentialData>;
|
||||||
|
|
||||||
export enum InstalledAppVariants {
|
export const InstalledAppVariants = [
|
||||||
"conferencing" = "conferencing",
|
"conferencing",
|
||||||
"calendar" = "calendar",
|
"calendar",
|
||||||
"payment" = "payment",
|
"payment",
|
||||||
"analytics" = "analytics",
|
"analytics",
|
||||||
"automation" = "automation",
|
"automation",
|
||||||
"other" = "other",
|
"other",
|
||||||
}
|
"web3",
|
||||||
|
] as const;
|
||||||
|
|
||||||
export const ALL_APPS = Object.values(ALL_APPS_MAP);
|
export const ALL_APPS = Object.values(ALL_APPS_MAP);
|
||||||
|
|
||||||
|
|
|
@ -306,15 +306,16 @@ async function handler(req: NextApiRequest & { userId?: number }) {
|
||||||
) {
|
) {
|
||||||
bookingToDelete.user.credentials
|
bookingToDelete.user.credentials
|
||||||
.filter((credential) => credential.type.endsWith("_calendar"))
|
.filter((credential) => credential.type.endsWith("_calendar"))
|
||||||
.forEach((credential) => {
|
.forEach(async (credential) => {
|
||||||
const calendar = getCalendar(credential);
|
const calendar = getCalendar(credential);
|
||||||
updatedBookings.forEach((updBooking) => {
|
for (const updBooking of updatedBookings) {
|
||||||
const bookingRef = updBooking.references.find((ref) => ref.type.includes("_calendar"));
|
const bookingRef = updBooking.references.find((ref) => ref.type.includes("_calendar"));
|
||||||
if (bookingRef) {
|
if (bookingRef) {
|
||||||
const { uid, externalCalendarId } = bookingRef;
|
const { uid, externalCalendarId } = bookingRef;
|
||||||
apiDeletes.push(calendar?.deleteEvent(uid, evt, externalCalendarId) as Promise<unknown>);
|
const deletedEvent = await calendar?.deleteEvent(uid, evt, externalCalendarId);
|
||||||
|
apiDeletes.push(deletedEvent);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
apiDeletes.push(calendar?.deleteEvent(uid, evt, externalCalendarId) as Promise<unknown>);
|
apiDeletes.push(calendar?.deleteEvent(uid, evt, externalCalendarId) as Promise<unknown>);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { useEmbedStyles } from "@calcom/embed-core/embed-iframe";
|
||||||
import classNames from "@calcom/lib/classNames";
|
import classNames from "@calcom/lib/classNames";
|
||||||
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
|
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
|
import useMediaQuery from "@calcom/lib/hooks/useMediaQuery";
|
||||||
import { weekdayNames } from "@calcom/lib/weekday";
|
import { weekdayNames } from "@calcom/lib/weekday";
|
||||||
import { Button, Icon, SkeletonText } from "@calcom/ui";
|
import { Button, Icon, SkeletonText } from "@calcom/ui";
|
||||||
|
|
||||||
|
@ -135,6 +136,9 @@ const Days = ({
|
||||||
const date = browsingDate.set("date", day);
|
const date = browsingDate.set("date", day);
|
||||||
days.push(date);
|
days.push(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{days.map((day, idx) => (
|
{days.map((day, idx) => (
|
||||||
|
@ -153,12 +157,13 @@ const Days = ({
|
||||||
date={day}
|
date={day}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.onChange(day);
|
props.onChange(day);
|
||||||
setTimeout(() => {
|
isMobile &&
|
||||||
window.scrollTo({
|
setTimeout(() => {
|
||||||
top: 360,
|
window.scrollTo({
|
||||||
behavior: "smooth",
|
top: 360,
|
||||||
});
|
behavior: "smooth",
|
||||||
}, 500);
|
});
|
||||||
|
}, 500);
|
||||||
}}
|
}}
|
||||||
disabled={
|
disabled={
|
||||||
(includedDates && !includedDates.includes(yyyymmdd(day))) ||
|
(includedDates && !includedDates.includes(yyyymmdd(day))) ||
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { z } from "zod";
|
||||||
|
|
||||||
import MemberInvitationModal from "@calcom/features/ee/teams/components/MemberInvitationModal";
|
import MemberInvitationModal from "@calcom/features/ee/teams/components/MemberInvitationModal";
|
||||||
import { classNames } from "@calcom/lib";
|
import { classNames } from "@calcom/lib";
|
||||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
import { WEBAPP_URL, APP_NAME } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { RouterOutputs, trpc } from "@calcom/trpc/react";
|
import { RouterOutputs, trpc } from "@calcom/trpc/react";
|
||||||
import { Avatar, Badge, Button, Icon, showToast, SkeletonContainer, SkeletonText } from "@calcom/ui";
|
import { Avatar, Badge, Button, Icon, showToast, SkeletonContainer, SkeletonText } from "@calcom/ui";
|
||||||
|
@ -156,7 +156,7 @@ const PendingMemberItem = (props: { member: TeamMember; index: number; teamId: n
|
||||||
{member.username ? (
|
{member.username ? (
|
||||||
<p className="text-gray-600">{`${WEBAPP_URL}/${member.username}`}</p>
|
<p className="text-gray-600">{`${WEBAPP_URL}/${member.username}`}</p>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-gray-600">{t("not_on_cal")}</p>
|
<p className="text-gray-600">{t("not_on_cal", { appName: APP_NAME })}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const useMediaQuery = (query: string) => {
|
||||||
|
const [matches, setMatches] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const media = window.matchMedia(query);
|
||||||
|
if (media.matches !== matches) {
|
||||||
|
setMatches(media.matches);
|
||||||
|
}
|
||||||
|
const listener = () => setMatches(media.matches);
|
||||||
|
window.addEventListener("resize", listener);
|
||||||
|
return () => window.removeEventListener("resize", listener);
|
||||||
|
}, [matches, query]);
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useMediaQuery;
|
|
@ -251,7 +251,7 @@ export const viewerTeamsRouter = router({
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
teamId: z.number(),
|
teamId: z.number(),
|
||||||
usernameOrEmail: z.string(),
|
usernameOrEmail: z.string().transform((usernameOrEmail) => usernameOrEmail.toLowerCase()),
|
||||||
role: z.nativeEnum(MembershipRole),
|
role: z.nativeEnum(MembershipRole),
|
||||||
language: z.string(),
|
language: z.string(),
|
||||||
sendEmailInvitation: z.boolean(),
|
sendEmailInvitation: z.boolean(),
|
||||||
|
@ -321,7 +321,7 @@ export const viewerTeamsRouter = router({
|
||||||
from: ctx.user.name,
|
from: ctx.user.name,
|
||||||
to: input.usernameOrEmail,
|
to: input.usernameOrEmail,
|
||||||
teamName: team.name,
|
teamName: team.name,
|
||||||
joinLink: `${WEBAPP_URL}/signup?token=${token}&callbackUrl=/settings/teams`,
|
joinLink: `${WEBAPP_URL}/signup?token=${token}&callbackUrl=/teams`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user