Skip to content

Commit 9fc1e63

Browse files
authored
Merge branch 'main' into feat/custom-org-domains-ui
2 parents 2b304b0 + bd5d94a commit 9fc1e63

File tree

60 files changed

+1341
-299
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1341
-299
lines changed

apps/web/app/(use-page-wrapper)/payment/[uid]/PaymentPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ const PaymentPage: FC<PaymentPageProps> = (props) => {
124124
<div className="col-span-2 mb-6">
125125
{date.locale(i18n.language ?? "en").format("dddd, DD MMMM YYYY")}
126126
<br />
127-
{date.format(is24h ? "H:mm" : "h:mma")} - {props.eventType.length} mins{" "}
127+
{date.format(is24h ? "H:mm" : "h:mma")} - {props.eventType.length} {t("minute_timeUnit")}{" "}
128128
<span className="text-subtle">({timezone})</span>
129129
</div>
130130
{props.booking.location && (

apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/playground/weekly-calendar/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { useState } from "react";
44

55
import dayjs from "@calcom/dayjs";
6-
import { Calendar } from "@calcom/web/modules/calendars/weeklyview/components/Calendar";
6+
import { Calendar } from "@calcom/features/calendars/weeklyview/components/Calendar";
77
import type { CalendarEvent } from "@calcom/features/calendars/weeklyview/types/events";
88
import type { CalendarComponentProps, Hours } from "@calcom/features/calendars/weeklyview/types/state";
99

apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ const SettingsSidebarContainer = ({
824824
href={child.href || "/"}
825825
trackingMetadata={child.trackingMetadata}
826826
textClassNames="text-emphasis font-medium text-sm"
827-
className={`px-2! py-1! min-h-7 h-auto w-fit ${
827+
className={`px-2! py-1! min-h-7 h-auto w-full ${
828828
tab.children && index === tab.children?.length - 1 && "mb-3!"
829829
}`}
830830
disableChevron

apps/web/components/apps/paypal/Setup.tsx

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@ export default function PayPalSetup() {
1515
const [newSecretKey, setNewSecretKey] = useState("");
1616
const router = useRouter();
1717
const { t } = useLocale();
18-
const integrations = trpc.viewer.apps.integrations.useQuery({ variant: "payment", appId: "paypal" });
18+
19+
const integrations = trpc.viewer.apps.integrations.useQuery({
20+
variant: "payment",
21+
appId: "paypal",
22+
});
23+
1924
const [paypalPaymentAppCredentials] = integrations.data?.items || [];
2025
const [credentialId] = paypalPaymentAppCredentials?.userCredentialIds || [-1];
26+
2127
const showContent = !!integrations.data && integrations.isSuccess && !!credentialId;
28+
2229
const saveKeysMutation = trpc.viewer.apps.updateAppCredentials.useMutation({
2330
onSuccess: () => {
2431
showToast(t("keys_have_been_saved"), "success");
@@ -39,12 +46,13 @@ export default function PayPalSetup() {
3946
<div className="bg-default border-subtle m-auto max-w-[43em] overflow-auto rounded border pb-10 md:p-10">
4047
<div className="ml-2 ltr:mr-2 rtl:ml-2 md:ml-5">
4148
<div className="invisible md:visible">
42-
<img className="h-11" src="/api/app-store/paypal/icon.svg" alt="Paypal Payment Logo" />
43-
<p className="text-default mt-5 text-lg">Paypal</p>
49+
<img className="h-11" src="/api/app-store/paypal/icon.svg" alt={t("paypal_payment_logo")} />
50+
<p className="text-default mt-5 text-lg">{t("paypal")}</p>
4451
</div>
52+
4553
<form autoComplete="off" className="mt-5">
4654
<TextField
47-
label="Client Id"
55+
label={t("client_id")}
4856
type="text"
4957
name="client_id"
5058
id="client_id"
@@ -55,7 +63,7 @@ export default function PayPalSetup() {
5563
/>
5664

5765
<TextField
58-
label="Secret Key"
66+
label={t("secret_key")}
5967
type="password"
6068
name="access_token"
6169
id="access_token"
@@ -65,7 +73,6 @@ export default function PayPalSetup() {
6573
onChange={(e) => setNewSecretKey(e.target.value)}
6674
/>
6775

68-
{/* Button to submit */}
6976
<div className="mt-5 flex flex-row justify-end">
7077
<Button
7178
color="primary"
@@ -82,43 +89,39 @@ export default function PayPalSetup() {
8289
</Button>
8390
</div>
8491
</form>
92+
8593
<div>
86-
<p className="text-lgf text-default mt-5 font-bold">Getting started with Paypal APP</p>
87-
<p className="text-default font-semi mt-2">
88-
Here in Cal.com we offer Paypal as one of our payment gateway. You can use your own Paypal
89-
Business account to receive payments from your customers enabling and setting up price and
90-
currency for each of your event types.
91-
</p>
94+
<p className="text-lgf text-default mt-5 font-bold">{t("paypal_getting_started")}</p>
95+
96+
<p className="text-default font-semi mt-2">{t("paypal_description")}</p>
9297

9398
<p className="text-lgf text-default mt-5 inline-flex font-bold">
94-
<CircleAlertIcon className="mr-2 mt-1 h-4 w-4" /> Important requirements:
99+
<CircleAlertIcon className="mr-2 mt-1 h-4 w-4" />
100+
{t("important_requirements")}
95101
</p>
102+
96103
<ul className="text-default ml-1 mt-2 list-disc pl-2">
97-
<li>Paypal Business account</li>
98-
<li>Paypal Developer account</li>
104+
<li>{t("paypal_business_account")}</li>
105+
<li>{t("paypal_developer_account")}</li>
99106
</ul>
100107

101-
<p className="text-default mb-2 mt-5 font-bold">Resources:</p>
108+
<p className="text-default mb-2 mt-5 font-bold">{t("resources")}</p>
109+
102110
<a
103111
className="text-orange-600 underline"
104112
target="_blank"
105113
href="https://developer.paypal.com/api/rest/#link-getclientidandclientsecret"
106114
rel="noreferrer">
107-
Link to Paypal developer API REST Setup Guide:
108-
https://developer.paypal.com/api/rest/#link-getclientidandclientsecret
115+
{t("paypal_rest_setup_guide")}
109116
</a>
110117

111-
<p className="text-lgf text-default mt-5 font-bold">Setup instructions</p>
112-
<p className="text-default font-semi mt-2">
113-
Remember to only proceed with the following steps if your account has already been upgraded to
114-
a business account. Also keep in mind that some of the following steps might be different
115-
since Paypal offers different experiences based on your country.
116-
</p>
118+
<p className="text-lgf text-default mt-5 font-bold">{t("paypal_setup_instructions")}</p>
119+
120+
<p className="text-default font-semi mt-2">{t("paypal_setup_note")}</p>
117121

118122
<ol className="text-default ml-1 mt-5 list-decimal pl-2">
119-
{/* @TODO: translate */}
120123
<li>
121-
Log into your Paypal Developer account and create a new app{" "}
124+
{t("paypal_step_1")}{" "}
122125
<a
123126
target="_blank"
124127
href="https://developer.paypal.com/dashboard/applications/live"
@@ -128,39 +131,38 @@ export default function PayPalSetup() {
128131
</a>
129132
.
130133
</li>
131-
<li>Choose a name for your application.</li>
132-
<li>Click on the Create App button</li>
134+
135+
<li>{t("paypal_step_2")}</li>
136+
<li>{t("paypal_step_3")}</li>
133137

134138
<li>
135-
Go back to{" "}
139+
{t("paypal_step_4_part_1")}{" "}
136140
<a
137141
className="text-orange-600 underline"
138142
href="https://developer.paypal.com/dashboard/applications/live">
139-
dashboard
143+
{t("dashboard")}
140144
</a>
141-
, click on new app created.
145+
, {t("paypal_step_4_part_2")}
142146
</li>
143-
<li>Copy the Client ID and Secret Key using copy buttons one by one.</li>
144-
<li>Paste them on the required field and save them.</li>
145-
<li>You should be all setup after this.</li>
147+
148+
<li>{t("paypal_step_5")}</li>
149+
<li>{t("paypal_step_6")}</li>
150+
<li>{t("paypal_step_7")}</li>
146151
</ol>
152+
147153
<p className="text-default mt-5 inline-flex font-bold">
148154
<CircleAlertIcon className="mr-2 mt-1 h-4 w-4" />
149-
Reminder:
150-
</p>
151-
<p className="text-default mt-2">
152-
Our integration creates a specific webhook on your Paypal account that we use to report back
153-
transactions to our system. If you delete this webhook, we will not be able to report back and
154-
you should Uninstall and Install the app again for this to work again. Uninstalling the app
155-
won&apos;t delete your current event type price/currency configuration but you would not be
156-
able to receive bookings.
155+
{t("reminder")}:
157156
</p>
157+
158+
<p className="text-default mt-2">{t("paypal_webhook_reminder")}</p>
158159
</div>
159160
</div>
160161
</div>
161162
) : (
162163
<AppNotInstalledMessage appName="paypal" />
163164
)}
165+
164166
<Toaster position="bottom-right" />
165167
</div>
166168
);

apps/web/lib/daily-webhook/triggerWebhooks.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ export const triggerRecordingReadyWebhook = async ({
5454
})
5555
);
5656

57+
const { assignmentReason: _emailAssignmentReason, ...evtWithoutAssignmentReason } = evt;
5758
const payload: EventPayloadType = {
58-
...evt,
59+
...evtWithoutAssignmentReason,
5960
downloadLink,
6061
};
6162

@@ -94,8 +95,9 @@ export const triggerTranscriptionGeneratedWebhook = async ({
9495
})
9596
);
9697

98+
const { assignmentReason: _emailAssignmentReason2, ...evtWithoutAssignmentReason2 } = evt;
9799
const payload: EventPayloadType = {
98-
...evt,
100+
...evtWithoutAssignmentReason2,
99101
downloadLinks,
100102
};
101103

apps/web/modules/booking-audit/components/BookingHistory.tsx

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"use client";
22

3-
import dayjs from "@calcom/dayjs";
43
import type { AuditActorType } from "@calcom/features/booking-audit/lib/repository/IAuditActorRepository";
54
import ServerTrans from "@calcom/lib/components/ServerTrans";
65
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -10,6 +9,8 @@ import { Button } from "@calcom/ui/components/button";
109
import { FilterSearchField, Select } from "@calcom/ui/components/form";
1110
import { Icon, type IconName } from "@calcom/ui/components/icon";
1211
import { SkeletonText } from "@calcom/ui/components/skeleton";
12+
import { Tooltip } from "@calcom/ui/components/tooltip";
13+
import { format, formatDistanceToNow } from "date-fns";
1314
import Link from "next/link";
1415
import { useState } from "react";
1516

@@ -139,7 +140,13 @@ function ActionTitle({ actionDisplayTitle }: { actionDisplayTitle: TranslationWi
139140
values={actionDisplayTitle.params}
140141
components={actionDisplayTitle.components.map((comp) =>
141142
comp.type === "link" ? (
142-
<Link key={comp.href} href={comp.href} className="text-emphasis underline hover:no-underline" />
143+
<Link
144+
key={comp.href}
145+
href={comp.href}
146+
target="_blank"
147+
rel="noopener noreferrer"
148+
className="text-emphasis underline hover:no-underline"
149+
/>
143150
) : (
144151
<span key={comp.href} />
145152
)
@@ -280,7 +287,9 @@ function BookingLogsTimeline({ logs }: BookingLogsTimelineProps) {
280287
{actorRole && <span>{` (${t(actorRole)})`}</span>}
281288
</span>
282289
<span></span>
283-
<span>{dayjs(log.timestamp).fromNow()}</span>
290+
<Tooltip content={format(new Date(log.timestamp), "yyyy-MM-dd HH:mm:ss")}>
291+
<span>{formatDistanceToNow(new Date(log.timestamp), { addSuffix: true })}</span>
292+
</Tooltip>
284293
</div>
285294
</div>
286295
</div>
@@ -304,15 +313,15 @@ function BookingLogsTimeline({ logs }: BookingLogsTimelineProps) {
304313
{/* Render displayFields if available, otherwise show type */}
305314
{log.displayFields && log.displayFields.length > 0
306315
? log.displayFields.map((field, idx) => (
307-
<div
308-
key={idx}
309-
className="flex items-start gap-2 py-2 border-b px-3 border-subtle">
310-
<span className="font-medium text-emphasis w-[140px]">{t(field.labelKey)}</span>
311-
<span className="font-medium">
312-
<DisplayFieldValue field={field} />
313-
</span>
314-
</div>
315-
))
316+
<div
317+
key={idx}
318+
className="flex items-start gap-2 py-2 border-b px-3 border-subtle">
319+
<span className="font-medium text-emphasis w-[140px]">{t(field.labelKey)}</span>
320+
<span className="font-medium">
321+
<DisplayFieldValue field={field} />
322+
</span>
323+
</div>
324+
))
316325
: null}
317326
<div className="flex items-start gap-2 py-2 border-b px-3 border-subtle">
318327
<span className="font-medium text-emphasis w-[140px]">{t("actor")}</span>
@@ -337,7 +346,7 @@ function BookingLogsTimeline({ logs }: BookingLogsTimelineProps) {
337346
<div className="flex items-start gap-2 py-2 px-3 border-b border-subtle">
338347
<span className="font-medium text-emphasis w-[140px]">{t("timestamp")}</span>
339348
<span className="text-default">
340-
{dayjs(log.timestamp).format("YYYY-MM-DD HH:mm:ss")}
349+
{format(new Date(log.timestamp), "yyyy-MM-dd HH:mm:ss")}
341350
</span>
342351
</div>
343352
{log.displayJson && Object.keys(log.displayJson).length > 0 && (
@@ -368,28 +377,35 @@ function BookingLogsTimeline({ logs }: BookingLogsTimelineProps) {
368377
}
369378

370379
function useBookingLogsFilters(auditLogs: AuditLog[], searchTerm: string, actorFilter: string | null) {
380+
const { t } = useLocale();
381+
371382
const filteredLogs = auditLogs.filter((log) => {
372383
const doesMatchDisplayFields = (): boolean => {
373384
return (
374385
log.displayFields?.some((field) => {
375386
const searchLower = searchTerm.toLowerCase();
387+
388+
const translatedLabel = field.labelKey ? t(field.labelKey) : "";
389+
const translatedValue = field.valueKey ? t(field.valueKey) : "";
390+
const displayValue = field.value ?? "";
391+
const displayValues = field.values ?? [];
392+
376393
return (
377-
field.valueKey?.toLowerCase().includes(searchLower) ||
378-
field.labelKey?.toLowerCase().includes(searchLower) ||
379-
field.value?.toLowerCase().includes(searchLower) ||
380-
field.values?.some((v) => v.toLowerCase().includes(searchLower))
394+
translatedLabel.toLowerCase().includes(searchLower) ||
395+
translatedValue.toLowerCase().includes(searchLower) ||
396+
displayValue.toLowerCase().includes(searchLower) ||
397+
displayValues.some((v) => v.toLowerCase().includes(searchLower))
381398
);
382399
}) ?? false
383400
);
384401
};
385402

386403
const doesMatchActionDisplayTitle = (): boolean => {
387-
return (
388-
log.actionDisplayTitle.key?.toLowerCase().includes(searchTerm.toLowerCase()) ||
389-
Object.values(log.actionDisplayTitle.params ?? {}).some((param) =>
390-
param?.toString().toLowerCase().includes(searchTerm.toLowerCase())
391-
)
392-
);
404+
const translatedTitle = log.actionDisplayTitle.key
405+
? t(log.actionDisplayTitle.key, log.actionDisplayTitle.params ?? {})
406+
: "";
407+
408+
return translatedTitle.toLowerCase().includes(searchTerm.toLowerCase());
393409
};
394410

395411
const matchesSearch =

apps/web/modules/bookings/components/BookerWebWrapper.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { useInitializeBookerStore } from "@calcom/features/bookings/Booker/store
1919
import { useEvent, useScheduleForEvent } from "@calcom/web/modules/schedules/hooks/useEvent";
2020
import { useBrandColors } from "@calcom/features/bookings/Booker/utils/use-brand-colors";
2121
import type { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEvent";
22-
import { DEFAULT_DARK_BRAND_COLOR, DEFAULT_LIGHT_BRAND_COLOR, WEBAPP_URL } from "@calcom/lib/constants";
22+
import { DEFAULT_LIGHT_BRAND_COLOR, DEFAULT_DARK_BRAND_COLOR, WEBAPP_URL } from "@calcom/lib/constants";
2323
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
2424
import { localStorage } from "@calcom/lib/webstorage";
2525
import { usePathname, useRouter, useSearchParams } from "next/navigation";
@@ -42,11 +42,11 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps): JSX.Elemen
4242
});
4343
const event = props.eventData
4444
? {
45-
data: props.eventData,
46-
isSuccess: true,
47-
isError: false,
48-
isPending: false,
49-
}
45+
data: props.eventData,
46+
isSuccess: true,
47+
isError: false,
48+
isPending: false,
49+
}
5050
: clientFetchedEvent;
5151

5252
const bookerLayout = useBookerLayout(event.data?.profile?.bookerLayouts);
@@ -149,6 +149,9 @@ const BookerWebWrapperComponent = (props: BookerWebWrapperAtomProps): JSX.Elemen
149149
useApiV2: props.useApiV2,
150150
bookerLayout,
151151
...(props.entity.orgSlug ? { orgSlug: props.entity.orgSlug } : {}),
152+
restrictionSchedule: event.data?.restrictionScheduleId
153+
? { id: event.data.restrictionScheduleId, useBookerTimezone: event.data.useBookerTimezone }
154+
: undefined,
152155
});
153156
const bookings = useBookings({
154157
event,

apps/web/modules/bookings/components/BookingCalendarView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import dayjs from "@calcom/dayjs";
44
import { useTimePreferences } from "@calcom/features/bookings/lib";
55
import type { CalendarEvent } from "@calcom/features/calendars/weeklyview/types/events";
66
import { useGetTheme } from "@calcom/lib/hooks/useTheme";
7-
import { Calendar } from "@calcom/web/modules/calendars/weeklyview/components/Calendar";
7+
import { Calendar } from "@calcom/features/calendars/weeklyview/components/Calendar";
88
import { useBanners } from "@calcom/web/modules/shell/banners/useBanners";
99
import { useEffect, useMemo } from "react";
1010
import { useBookingDetailsSheetStore } from "../store/bookingDetailsSheetStore";

0 commit comments

Comments
 (0)