import React from "react"; import { ScrollView, View } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import { StatusBar } from "expo-status-bar"; import { useColorScheme } from "nativewind"; import { MutedText, Text } from "../../components/text"; import { Button } from "../../components/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "../../components/card"; /** One requested scope, with an optional human-readable description. */ export interface ConsentScope { scope: string; description?: string; } export interface ConsentScreenProps { /** The relying party's display name (heading). */ clientName: string; /** The scopes the client is requesting. */ scopes: ConsentScope[]; /** Approve — the app records the grant and resumes the authorize request. */ onAllow: () => void; /** Decline — the app bounces the client with `access_denied`. */ onDeny: () => void; isLoading?: boolean; error?: string; } /** * OIDC consent prompt (OIDC Core §3.1.2.4). Presentational + prop-driven: the * host app fetches the request detail, records the decision, and navigates — * this screen only renders the scopes and the allow/deny choice, so it stays * transport-agnostic and reusable across apps. */ export function ConsentScreen({ clientName, scopes, onAllow, onDeny, isLoading, error, }: ConsentScreenProps) { const { colorScheme } = useColorScheme(); const isDark = colorScheme === "dark"; return ( Authorize {clientName} {clientName} wants access to your account. Review what it can do. {scopes.length === 0 ? ( Basic sign-in (no additional access requested). ) : ( scopes.map((s) => ( • {s.scope} {s.description ? ( {s.description} ) : null} )) )} {error ? ( {error} ) : null} ); } export default ConsentScreen;