-
Notifications
You must be signed in to change notification settings - Fork 0
fix(companion): event type links for org user #84
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
base: qodo_combined_20260121_qodo_grep_cursor_copilot_1_base_fixcompanion_event_type_links_for_org_user_pr706
Are you sure you want to change the base?
Changes from all commits
a92077c
cdfe735
102ed08
2b19bab
a3416cd
a0a15e1
4f49041
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -177,6 +177,7 @@ export default function EventTypeDetail() { | |
| const [conferencingOptions, setConferencingOptions] = useState<ConferencingOption[]>([]); | ||
| const [conferencingLoading, setConferencingLoading] = useState(false); | ||
| const [eventTypeData, setEventTypeData] = useState<EventType | null>(null); | ||
| const [bookingUrl, setBookingUrl] = useState<string>(""); | ||
| const [saving, setSaving] = useState(false); | ||
| const [beforeEventBuffer, setBeforeEventBuffer] = useState("No buffer time"); | ||
| const [afterEventBuffer, setAfterEventBuffer] = useState("No buffer time"); | ||
|
|
@@ -945,29 +946,19 @@ export default function EventTypeDetail() { | |
| }; | ||
|
|
||
| const handlePreview = async () => { | ||
| const eventTypeSlug = eventSlug || "preview"; | ||
| let link: string; | ||
| try { | ||
| link = await CalComAPIService.buildEventTypeLink(eventTypeSlug); | ||
| } catch (error) { | ||
| safeLogError("Failed to generate preview link:", error); | ||
| showErrorAlert("Error", "Failed to generate preview link. Please try again."); | ||
| if (!bookingUrl) { | ||
| showErrorAlert("Error", "Booking URL not available. Please save the event type first."); | ||
| return; | ||
| } | ||
| await openInAppBrowser(link, "event type preview"); | ||
| await openInAppBrowser(bookingUrl, "event type preview"); | ||
| }; | ||
|
|
||
| const handleCopyLink = async () => { | ||
| const eventTypeSlug = eventSlug || "event-link"; | ||
| let link: string; | ||
| try { | ||
| link = await CalComAPIService.buildEventTypeLink(eventTypeSlug); | ||
| } catch (error) { | ||
| safeLogError("Failed to copy link:", error); | ||
| showErrorAlert("Error", "Failed to copy link. Please try again."); | ||
| if (!bookingUrl) { | ||
| showErrorAlert("Error", "Booking URL not available. Please save the event type first."); | ||
| return; | ||
| } | ||
| await Clipboard.setStringAsync(link); | ||
| await Clipboard.setStringAsync(bookingUrl); | ||
| showSuccessAlert("Success", "Link copied!"); | ||
|
Comment on lines
+949
to
962
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 6. Bookingurl state never set • EventTypeDetail now gates Preview/Copy on a local bookingUrl state, but that state is initialized to an empty string and never updated from fetched event type data. • This makes preview/copy always fail with an error even for existing event types, and also passes an empty bookingUrl into BasicsTab. • The rest of the component fetch path only calls applyEventTypeData(eventType), which does not set bookingUrl, so the state remains empty indefinitely. Agent prompt
|
||
| }; | ||
|
Comment on lines
956
to
963
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3. handlecopylink lacks try/catch • handleCopyLink() now calls Clipboard.setStringAsync(bookingUrl) without guarding against runtime failures. • Clipboard operations can fail (permissions/platform limitations), and without error handling the user may see no meaningful feedback and the app may produce unhandled errors. Agent prompt
|
||
|
|
||
|
|
@@ -1279,7 +1270,10 @@ export default function EventTypeDetail() { | |
| {/* Tab Navigation Dropdown Menu */} | ||
| <DropdownMenu> | ||
| <DropdownMenuTrigger asChild> | ||
| <AppPressable className="flex-row items-center gap-1 px-2 py-2"> | ||
| <AppPressable | ||
| className="flex-row items-center gap-1 px-2 py-2" | ||
| style={{ flexDirection: "row", alignItems: "center" }} | ||
| > | ||
| <Text className="text-[16px] font-semibold text-[#000000]" numberOfLines={1}> | ||
| {tabs.find((tab) => tab.id === activeTab)?.label ?? "Basics"} | ||
| </Text> | ||
|
|
@@ -1433,6 +1427,7 @@ export default function EventTypeDetail() { | |
| onUpdateLocation={handleUpdateLocation} | ||
| locationOptions={getLocationOptionsForDropdown()} | ||
| conferencingLoading={conferencingLoading} | ||
| bookingUrl={bookingUrl} | ||
| /> | ||
| ) : null} | ||
|
|
||
|
|
@@ -2342,15 +2337,17 @@ export default function EventTypeDetail() { | |
| <View className="bg-white pl-4"> | ||
| <View | ||
| className="flex-row items-center justify-between pr-4" | ||
| style={{ height: 44 }} | ||
| style={{ height: 44, flexDirection: "row", alignItems: "center" }} | ||
| > | ||
| <Text className="text-[17px] text-black">Hidden</Text> | ||
| <Switch | ||
| value={isHidden} | ||
| onValueChange={setIsHidden} | ||
| trackColor={{ false: "#E5E5EA", true: "#000000" }} | ||
| thumbColor="#FFFFFF" | ||
| /> | ||
| <View style={{ justifyContent: "center", height: "100%" }}> | ||
| <Switch | ||
| value={isHidden} | ||
| onValueChange={setIsHidden} | ||
| trackColor={{ false: "#E5E5EA", true: "#000000" }} | ||
| thumbColor="#FFFFFF" | ||
| /> | ||
| </View> | ||
| </View> | ||
| </View> | ||
| </View> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,7 +37,7 @@ import { | |
| useEventTypes, | ||
| } from "@/hooks"; | ||
| import { useEventTypeFilter } from "@/hooks/useEventTypeFilter"; | ||
| import { CalComAPIService, type EventType } from "@/services/calcom"; | ||
| import type { EventType } from "@/services/calcom"; | ||
| import { showErrorAlert, showSuccessAlert } from "@/utils/alerts"; | ||
| import { openInAppBrowser } from "@/utils/browser"; | ||
| import { getEventDuration } from "@/utils/getEventDuration"; | ||
|
|
@@ -133,22 +133,27 @@ export default function EventTypes() { | |
| }; | ||
|
|
||
| const handleCopyLink = async (eventType: EventType) => { | ||
| if (!eventType.bookingUrl) { | ||
| showErrorAlert("Error", "Booking URL not available for this event type."); | ||
| return; | ||
| } | ||
| try { | ||
| const link = await CalComAPIService.buildEventTypeLink(eventType.slug); | ||
| await Clipboard.setStringAsync(link); | ||
|
|
||
| await Clipboard.setStringAsync(eventType.bookingUrl); | ||
| showSuccessAlert("Link Copied", "Event type link copied!"); | ||
| } catch { | ||
| showErrorAlert("Error", "Failed to copy link. Please try again."); | ||
| } | ||
| }; | ||
|
|
||
| const _handleShare = async (eventType: EventType) => { | ||
| if (!eventType.bookingUrl) { | ||
| showErrorAlert("Error", "Booking URL not available for this event type."); | ||
| return; | ||
| } | ||
| try { | ||
| const link = await CalComAPIService.buildEventTypeLink(eventType.slug); | ||
| await Share.share({ | ||
| message: `Book a meeting: ${eventType.title}`, | ||
| url: link, | ||
| url: eventType.bookingUrl, | ||
| }); | ||
|
Comment on lines
+136
to
157
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 7. Actions require bookingurl • EventTypes list screens now refuse to copy/share/preview unless eventType.bookingUrl exists,
showing an error otherwise.
• bookingUrl is explicitly optional in the EventType type and the client service does not derive
a fallback URL, so this can regress functionality whenever the API omits it.
• This creates an inconsistent UX vs other places (e.g., extension code) that still fall back to
constructing https://cal.com/{username}/{slug}.
Agent prompt
|
||
| } catch { | ||
| showErrorAlert("Error", "Failed to share link. Please try again."); | ||
|
|
@@ -280,14 +285,15 @@ export default function EventTypes() { | |
| }; | ||
|
|
||
| const handlePreview = async (eventType: EventType) => { | ||
| if (!eventType.bookingUrl) { | ||
| showErrorAlert("Error", "Booking URL not available for this event type."); | ||
| return; | ||
| } | ||
| try { | ||
| const link = await CalComAPIService.buildEventTypeLink(eventType.slug); | ||
| // Open in browser | ||
| if (Platform.OS === "web") { | ||
| window.open(link, "_blank"); | ||
| window.open(eventType.bookingUrl, "_blank"); | ||
| } else { | ||
| // For mobile, use in-app browser | ||
| await openInAppBrowser(link, "event type preview"); | ||
| await openInAppBrowser(eventType.bookingUrl, "event type preview"); | ||
| } | ||
|
Comment on lines
287
to
297
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 5. bookingurl opened without validation • eventType.bookingUrl (API-provided input) is opened directly via window.open() / openInAppBrowser() without validating scheme/host. • This violates the security-first input validation requirement and can enable unsafe navigation if the value is malformed or attacker-controlled upstream. Agent prompt
|
||
| } catch { | ||
| console.error("Failed to open preview"); | ||
|
|
@@ -443,6 +449,7 @@ export default function EventTypes() { | |
| /> | ||
| <TouchableOpacity | ||
| className="min-w-[60px] flex-row items-center justify-center gap-1 rounded-lg bg-black px-2.5 py-2" | ||
| style={{ flexDirection: "row", alignItems: "center", justifyContent: "center" }} | ||
| onPress={handleCreateNew} | ||
| > | ||
| <Ionicons name="add" size={18} color="#fff" /> | ||
|
|
@@ -507,6 +514,7 @@ export default function EventTypes() { | |
| /> | ||
| <TouchableOpacity | ||
| className="min-w-[60px] flex-row items-center justify-center gap-1 rounded-lg bg-black px-2.5 py-2" | ||
| style={{ flexDirection: "row", alignItems: "center", justifyContent: "center" }} | ||
| onPress={handleCreateNew} | ||
| > | ||
| <Ionicons name="add" size={18} color="#fff" /> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. handlepreview lacks try/catch
📘 Rule violation⛯ ReliabilityAgent prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools