* feat(companion): add multi-browser OAuth support for extension
- Add browser-specific OAuth client ID and redirect URI configuration
- Support Chrome, Firefox, Safari, Edge, and Brave browsers
- Add build scripts for each browser target (ext:build-{browser})
- Fix Brave Shields compatibility for production builds
- Add EXTENSION_SETUP.md documentation
BREAKING CHANGE: None - backward compatible with existing Chrome config
* fix(companion): replace && conditional rendering with ternary operators
Replace all `{condition && (<Component />)}` patterns with explicit
`{condition ? (<Component />) : null}` syntax across the companion app.
This fixes "Unexpected text node: . A text node cannot be a child of
a <View>" errors that occur with react-native-css-interop when using
&& conditional rendering in React Native web builds.
Files updated:
- app/event-type-detail.tsx (16)
- app/booking-detail.tsx (10)
- app/(tabs)/bookings.tsx (8)
- app/(tabs)/availability.tsx (6)
- app/availability-detail.tsx (5)
- app/(tabs)/(event-types)/index.tsx (4)
- components/event-type-detail/tabs/LimitsTab.tsx (9)
- components/event-type-detail/tabs/BasicsTab.tsx (3)
- components/event-type-detail/tabs/AdvancedTab.tsx (3)
- components/event-type-detail/tabs/RecurringTab.tsx (1)
- components/event-type-detail/tabs/AvailabilityTab.tsx (1)
- components/event-type-list-item/EventTypeListItem.ios.tsx (3)
- components/BookingActionsModal.tsx (2)
- components/Tooltip.tsx (1)
- components/LocationsList.tsx (1)
- components/Header.tsx (1)
- components/EmptyScreen.tsx (1)
* correct command for edge
* dont break ci
* deslop ai
52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { Ionicons } from "@expo/vector-icons";
|
|
import React from "react";
|
|
import { View, Text, TouchableOpacity } from "react-native";
|
|
|
|
type IoniconName = keyof typeof Ionicons.glyphMap;
|
|
|
|
interface EmptyScreenProps {
|
|
icon: IoniconName;
|
|
headline: string;
|
|
description: string;
|
|
buttonText?: string;
|
|
onButtonPress?: () => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function EmptyScreen({
|
|
icon,
|
|
headline,
|
|
description,
|
|
buttonText,
|
|
onButtonPress,
|
|
className,
|
|
}: EmptyScreenProps) {
|
|
return (
|
|
<View
|
|
className={`flex w-full select-none flex-col items-center justify-center rounded-lg border border-gray-300 bg-white p-7 ${className || ""}`}
|
|
>
|
|
<View className="h-[72px] w-[72px] items-center justify-center rounded-full border border-gray-300 bg-gray-100">
|
|
<Ionicons name={icon} size={40} color="#374151" />
|
|
</View>
|
|
|
|
<View className="mt-6 max-w-[420px] flex-col items-center">
|
|
<Text className="text-center text-2xl font-semibold text-gray-900">{headline}</Text>
|
|
|
|
<Text className="mb-8 mt-3 text-center text-sm font-normal leading-6 text-gray-500">
|
|
{description}
|
|
</Text>
|
|
|
|
{buttonText && onButtonPress ? (
|
|
<TouchableOpacity
|
|
className="flex-row items-center justify-center gap-1 rounded-lg bg-gray-900 px-4 py-2.5"
|
|
onPress={onButtonPress}
|
|
>
|
|
<Ionicons name="add" size={18} color="#fff" />
|
|
<Text className="text-base font-medium text-white">{buttonText}</Text>
|
|
</TouchableOpacity>
|
|
) : null}
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|