Files
calendar/companion/components/LogoutButton.tsx
T
Dhairyashil ShindeandGitHub 9203cb262c feat(companion): component improvements, migrate to path aliases, expo-haptics, expo-image (#26226)
* react compiler

* remove compilation mode 'all', it will use infer by default

* feat(companion): add theme tokens, path aliases, and component improvements

- Extend tailwind.config.js with Cal.com brand color tokens (cal.text, cal.bg, cal.border, cal.accent, cal.brand)
- Create theme/colors.ts for JS usage where Tailwind classes can't be used
- Configure path aliases in tsconfig.json (@/components, @/hooks, @/utils, etc.)
- Add expo-image and expo-haptics dependencies
- Enhance AppPressable with Reanimated animations (opacity + scale) and haptic feedback
- Extract shared logic from BookingListItem into useBookingListItemData hook and BookingListItemParts
- Extract shared logic from EventTypeListItem into useEventTypeListItemData hook and EventTypeListItemParts
- Extract shared logic from AvailabilityListItem into AvailabilityListItemParts
- Update all list item components to use new theme tokens instead of hardcoded hex values

* fix react compiler non memo issue

* feat(companion): migrate to path aliases and expo-image

- Remove theme/colors.ts and theme/index.ts (defer dark mode to future PR)
- Replace colors import with hardcoded hex values in components
- Migrate all files to use path aliases (@/components/*, @/hooks/*, etc.)
- Migrate SvgImage to use expo-image for better performance
- Update tsconfig.json to remove @/theme/* alias

* fix(companion): add path aliases to extension tsconfig

Add baseUrl and paths configuration to tsconfig.extension.json to support
path aliases in shared types used by the extension build.
2025-12-28 08:08:33 -03:00

82 lines
2.2 KiB
TypeScript

import { useState } from "react";
import { Alert, Platform, Text, TouchableOpacity } from "react-native";
import { useAuth } from "@/contexts/AuthContext";
import { LogoutConfirmModal } from "./LogoutConfirmModal";
interface LogoutButtonProps {
className?: string;
variant?: "default" | "destructive" | "ghost";
}
export function LogoutButton({ className = "" }: LogoutButtonProps) {
const { logout } = useAuth();
const [showConfirmModal, setShowConfirmModal] = useState(false);
const handleLogoutPress = () => {
if (Platform.OS === "web") {
setShowConfirmModal(true);
} else {
// Mobile: use Alert.alert
Alert.alert("Sign Out", "Are you sure you want to sign out?", [
{
text: "Cancel",
style: "cancel",
},
{
text: "Sign Out",
style: "destructive",
onPress: performLogout,
},
]);
}
};
const performLogout = async () => {
try {
await logout();
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error("Logout error", message);
if (__DEV__) {
const stack = error instanceof Error ? error.stack : undefined;
console.debug("[LogoutButton] logout failed", { message, stack });
}
if (Platform.OS === "web") {
window.alert("Failed to sign out. Please try again.");
} else {
Alert.alert("Error", "Failed to sign out. Please try again.");
}
}
};
const handleConfirmLogout = () => {
setShowConfirmModal(false);
performLogout();
};
const handleCancelLogout = () => {
setShowConfirmModal(false);
};
return (
<>
<TouchableOpacity
onPress={handleLogoutPress}
className={`rounded-lg bg-gray-600 px-4 py-2 ${className}`}
style={Platform.OS === "web" ? { cursor: "pointer" } : undefined}
activeOpacity={0.7}
>
<Text className="font-medium text-gray-900">Sign Out</Text>
</TouchableOpacity>
<LogoutConfirmModal
visible={showConfirmModal}
onConfirm={handleConfirmLogout}
onCancel={handleCancelLogout}
/>
</>
);
}
export default LogoutButton;