diff --git a/src/components/LanguageToggle.tsx b/src/components/LanguageToggle.tsx
index 86088b5..1de656c 100644
--- a/src/components/LanguageToggle.tsx
+++ b/src/components/LanguageToggle.tsx
@@ -119,7 +119,7 @@ export function LanguageToggle({ compact = false, inline = false, className, var
}
return (
-
+ { if (!open) setQuery(''); }}>
-
+
>
)}
@@ -1296,5 +1298,6 @@ export function Layout({ children, noPadding }: LayoutProps) {
{/* Mirrors in-app activity to OS notifications — inert until opted in. */}
+
);
}
diff --git a/src/components/TripItineraryCard.tsx b/src/components/TripItineraryCard.tsx
index 864f650..4a01c75 100644
--- a/src/components/TripItineraryCard.tsx
+++ b/src/components/TripItineraryCard.tsx
@@ -17,6 +17,7 @@ import { useCreateSpotCollection } from '@/hooks/useSpotCollections';
import { useToast } from '@/hooks/useToast';
import { useTranslation } from '@/contexts/language';
import { cn } from '@/lib/utils';
+import { sanitizeUrl } from '@/lib/sanitizeUrl';
const KIND_ICON = {
spot: MapPin,
@@ -117,6 +118,7 @@ export function TripItineraryCard({ itinerary }: { itinerary: Itinerary }) {
{day.stops.map((stop, i) => {
const Icon = KIND_ICON[stop.kind];
+ const stopUrl = sanitizeUrl(stop.url);
const inner = (
@@ -131,10 +133,10 @@ export function TripItineraryCard({ itinerary }: { itinerary: Itinerary }) {
);
- return stop.url ? (
+ return stopUrl ? (
{t('routeUi.localCrews')}
- {itinerary.crews.map((c, i) => (
-
- 👥 {c.name}
-
- ))}
+ {itinerary.crews.map((c, i) => {
+ const crewUrl = sanitizeUrl(c.url);
+ const cls = 'text-[9px] px-1.5 py-0.5 rounded bg-white/5 text-gray-200 hover:bg-[#ccff00]/10 hover:text-[#ccff00] transition-colors';
+ return crewUrl ? (
+
+ 👥 {c.name}
+
+ ) : (
+
👥 {c.name}
+ );
+ })}
)}
diff --git a/src/components/auth/LoginArea.tsx b/src/components/auth/LoginArea.tsx
index 87735d1..13ec763 100644
--- a/src/components/auth/LoginArea.tsx
+++ b/src/components/auth/LoginArea.tsx
@@ -10,6 +10,7 @@ import { useLoggedInAccounts } from '@/hooks/useLoggedInAccounts';
import { AccountSwitcher } from './AccountSwitcher';
import { cn } from '@/lib/utils';
import { useTranslation } from '@/contexts/language';
+import { useAuthDialog } from '@/contexts/authDialog';
export interface LoginAreaProps {
className?: string;
@@ -27,16 +28,19 @@ export interface LoginAreaProps {
export function LoginArea({ className, compact, onLoginRequest, onSignupRequest }: LoginAreaProps) {
const { currentUser } = useLoggedInAccounts();
const { t } = useTranslation();
+ const authDialog = useAuthDialog();
const [loginDialogOpen, setLoginDialogOpen] = useState(false);
const [signupDialogOpen, setSignupDialogOpen] = useState(false);
- const globalAuth = !!onLoginRequest && !!onSignupRequest;
+ const globalAuth = !!authDialog || (!!onLoginRequest && !!onSignupRequest);
const openLogin = () => {
- if (onLoginRequest) onLoginRequest();
+ if (authDialog) authDialog.openLogin();
+ else if (onLoginRequest) onLoginRequest();
else setLoginDialogOpen(true);
};
const openSignup = () => {
- if (onSignupRequest) onSignupRequest();
+ if (authDialog) authDialog.openSignup();
+ else if (onSignupRequest) onSignupRequest();
else setSignupDialogOpen(true);
};
@@ -57,6 +61,7 @@ export function LoginArea({ className, compact, onLoginRequest, onSignupRequest
size="icon"
className='h-9 w-9 rounded-full bg-[#ccff00] text-black hover:bg-[#ccff00]/90'
title={t('settingsUi.loginArea.signUp')}
+ aria-label={t('settingsUi.loginArea.signUp')}
>
@@ -66,6 +71,7 @@ export function LoginArea({ className, compact, onLoginRequest, onSignupRequest
size="icon"
className="h-9 w-9 rounded-full border border-gray-600 hover:border-[#ff0040]"
title={t('settingsUi.loginArea.logIn')}
+ aria-label={t('settingsUi.loginArea.logIn')}
>
diff --git a/src/components/auth/LoginDialog.tsx b/src/components/auth/LoginDialog.tsx
index 2caa40e..2ab66b7 100644
--- a/src/components/auth/LoginDialog.tsx
+++ b/src/components/auth/LoginDialog.tsx
@@ -321,7 +321,7 @@ export const LoginDialog: React.FC = ({ isOpen, onClose, onLog
return (