import React from "react"; import { ActivityIndicator, Pressable, StyleSheet, Text, TextInput, View } from "react-native"; import { ApiError } from "./api"; import { colors, radii, spacing } from "./theme"; export const styles = StyleSheet.create({ page: { flexGrow: 1, backgroundColor: colors.background }, scrollContent: { padding: spacing.lg, gap: spacing.lg }, title: { fontSize: 20, fontWeight: "500", color: colors.foreground }, heading: { fontSize: 16, fontWeight: "500", color: colors.foreground }, text: { fontSize: 14, lineHeight: 20, color: colors.foreground }, muted: { fontSize: 12, lineHeight: 18, color: colors.mutedForeground }, card: { padding: spacing.lg, gap: spacing.md, borderWidth: 1, borderColor: colors.border, borderRadius: radii.lg, backgroundColor: colors.card }, input: { minHeight: 48, borderWidth: 1, borderColor: colors.border, borderRadius: radii.md, padding: spacing.md, fontSize: 16, backgroundColor: colors.inputBackground, color: colors.foreground }, textarea: { minHeight: 104, textAlignVertical: "top" }, row: { flexDirection: "row", flexWrap: "wrap", gap: spacing.sm, alignItems: "center" }, button: { minHeight: 44, justifyContent: "center", paddingHorizontal: 18, borderRadius: radii.lg, backgroundColor: colors.primary }, buttonSecondary: { backgroundColor: colors.secondary }, buttonDanger: { backgroundColor: colors.destructive }, buttonDisabled: { opacity: 0.5 }, buttonText: { color: colors.primaryForeground, fontWeight: "500", fontSize: 14, textAlign: "center" }, buttonTextSecondary: { color: colors.secondaryForeground }, link: { color: colors.primary, fontSize: 14, textDecorationLine: "underline", paddingVertical: spacing.sm }, badge: { borderRadius: radii.full, backgroundColor: colors.muted, color: colors.foreground, paddingHorizontal: 10, paddingVertical: 5, fontSize: 12, alignSelf: "flex-start" }, error: { borderLeftWidth: 4, borderColor: colors.destructive, backgroundColor: "#fef2f2", padding: spacing.md, color: "#7f1d1d", fontSize: 14 }, success: { borderLeftWidth: 4, borderColor: colors.success, backgroundColor: "#f0fdf4", padding: spacing.md, color: "#14532d", fontSize: 14 }, modalBackdrop: { position: "absolute", top: 0, right: 0, bottom: 0, left: 0, zIndex: 10, backgroundColor: "rgba(3, 2, 19, 0.45)", alignItems: "center", justifyContent: "center", padding: spacing.lg }, modal: { width: "100%", maxWidth: 360, borderRadius: radii.xl, backgroundColor: colors.card, padding: spacing.lg, gap: spacing.md, borderWidth: 1, borderColor: colors.border }, }); export function Button({ title, onPress, disabled, secondary, danger }: { title: string; onPress: () => void; disabled?: boolean; secondary?: boolean; danger?: boolean; }) { return [ styles.button, secondary && styles.buttonSecondary, danger && styles.buttonDanger, disabled && styles.buttonDisabled, pressed && { opacity: 0.8 }, ]} > {title} ; } export function Field(props: React.ComponentProps & { label: string; error?: string }) { return {props.label} {props.error && {props.error}} ; } export function Loading() { return Загрузка…; } export function ErrorNotice({ error, retry }: { error: unknown; retry?: () => void }) { const requestId = error instanceof ApiError ? error.requestId : undefined; return {error instanceof ApiError ? error.message : error instanceof Error ? error.message : "Произошла ошибка"} {requestId ? `\nКод обращения: ${requestId}` : ""} {retry &&