summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/Collapsible.tsx33
-rw-r--r--components/ParallaxScrollView.tsx33
-rw-r--r--components/PrimaryButton.tsx1
-rw-r--r--components/ThemedText.tsx29
-rw-r--r--components/ThemedView.tsx17
-rw-r--r--components/login/ShipCredsForm.tsx105
6 files changed, 173 insertions, 45 deletions
diff --git a/components/Collapsible.tsx b/components/Collapsible.tsx
index 55bff2f..5820251 100644
--- a/components/Collapsible.tsx
+++ b/components/Collapsible.tsx
@@ -1,28 +1,33 @@
-import { PropsWithChildren, useState } from 'react';
-import { StyleSheet, TouchableOpacity } from 'react-native';
+"use client";
+import { PropsWithChildren, useState } from "react";
+import { StyleSheet, TouchableOpacity } from "react-native";
-import { ThemedText } from '@/components/ThemedText';
-import { ThemedView } from '@/components/ThemedView';
-import { IconSymbol } from '@/components/ui/IconSymbol';
-import { Colors } from '@/constants/Colors';
-import { useColorScheme } from '@/hooks/useColorScheme';
+import { ThemedText } from "@/components/ThemedText";
+import { ThemedView } from "@/components/ThemedView";
+import { IconSymbol } from "@/components/ui/IconSymbol";
+import { Colors } from "@/constants/Colors";
+import { useColorScheme } from "@/hooks/useColorScheme";
-export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
+export function Collapsible({
+ children,
+ title,
+}: PropsWithChildren & { title: string }) {
const [isOpen, setIsOpen] = useState(false);
- const theme = useColorScheme() ?? 'light';
+ const theme = useColorScheme() ?? "light";
return (
<ThemedView>
<TouchableOpacity
style={styles.heading}
onPress={() => setIsOpen((value) => !value)}
- activeOpacity={0.8}>
+ activeOpacity={0.8}
+ >
<IconSymbol
name="chevron.right"
size={18}
weight="medium"
- color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
- style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
+ color={theme === "light" ? Colors.light.icon : Colors.dark.icon}
+ style={{ transform: [{ rotate: isOpen ? "90deg" : "0deg" }] }}
/>
<ThemedText type="defaultSemiBold">{title}</ThemedText>
@@ -34,8 +39,8 @@ export function Collapsible({ children, title }: PropsWithChildren & { title: st
const styles = StyleSheet.create({
heading: {
- flexDirection: 'row',
- alignItems: 'center',
+ flexDirection: "row",
+ alignItems: "center",
gap: 6,
},
content: {
diff --git a/components/ParallaxScrollView.tsx b/components/ParallaxScrollView.tsx
index 5df1d75..46ed68e 100644
--- a/components/ParallaxScrollView.tsx
+++ b/components/ParallaxScrollView.tsx
@@ -1,15 +1,16 @@
-import type { PropsWithChildren, ReactElement } from 'react';
-import { StyleSheet } from 'react-native';
+"use client";
+import type { PropsWithChildren, ReactElement } from "react";
+import { StyleSheet } from "react-native";
import Animated, {
interpolate,
useAnimatedRef,
useAnimatedStyle,
useScrollViewOffset,
-} from 'react-native-reanimated';
+} from "react-native-reanimated";
-import { ThemedView } from '@/components/ThemedView';
-import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
-import { useColorScheme } from '@/hooks/useColorScheme';
+import { ThemedView } from "@/components/ThemedView";
+import { useBottomTabOverflow } from "@/components/ui/TabBarBackground";
+import { useColorScheme } from "@/hooks/useColorScheme";
const HEADER_HEIGHT = 250;
@@ -23,7 +24,7 @@ export default function ParallaxScrollView({
headerImage,
headerBackgroundColor,
}: Props) {
- const colorScheme = useColorScheme() ?? 'light';
+ const colorScheme = useColorScheme() ?? "light";
const scrollRef = useAnimatedRef<Animated.ScrollView>();
const scrollOffset = useScrollViewOffset(scrollRef);
const bottom = useBottomTabOverflow();
@@ -34,11 +35,15 @@ export default function ParallaxScrollView({
translateY: interpolate(
scrollOffset.value,
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
- [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
+ [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75],
),
},
{
- scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]),
+ scale: interpolate(
+ scrollOffset.value,
+ [-HEADER_HEIGHT, 0, HEADER_HEIGHT],
+ [2, 1, 1],
+ ),
},
],
};
@@ -50,13 +55,15 @@ export default function ParallaxScrollView({
ref={scrollRef}
scrollEventThrottle={16}
scrollIndicatorInsets={{ bottom }}
- contentContainerStyle={{ paddingBottom: bottom }}>
+ contentContainerStyle={{ paddingBottom: bottom }}
+ >
<Animated.View
style={[
styles.header,
{ backgroundColor: headerBackgroundColor[colorScheme] },
headerAnimatedStyle,
- ]}>
+ ]}
+ >
{headerImage}
</Animated.View>
<ThemedView style={styles.content}>{children}</ThemedView>
@@ -71,12 +78,12 @@ const styles = StyleSheet.create({
},
header: {
height: HEADER_HEIGHT,
- overflow: 'hidden',
+ overflow: "hidden",
},
content: {
flex: 1,
padding: 32,
gap: 16,
- overflow: 'hidden',
+ overflow: "hidden",
},
});
diff --git a/components/PrimaryButton.tsx b/components/PrimaryButton.tsx
index 94bd8ce..b515818 100644
--- a/components/PrimaryButton.tsx
+++ b/components/PrimaryButton.tsx
@@ -1,3 +1,4 @@
+"use client";
import React from "react";
import {
TouchableOpacity,
diff --git a/components/ThemedText.tsx b/components/ThemedText.tsx
index 9d214a2..c545b1c 100644
--- a/components/ThemedText.tsx
+++ b/components/ThemedText.tsx
@@ -1,31 +1,32 @@
-import { StyleSheet, Text, type TextProps } from 'react-native';
+"use client";
+import { StyleSheet, Text, type TextProps } from "react-native";
-import { useThemeColor } from '@/hooks/useThemeColor';
+import { useThemeColor } from "@/hooks/useThemeColor";
export type ThemedTextProps = TextProps & {
lightColor?: string;
darkColor?: string;
- type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
+ type?: "default" | "title" | "defaultSemiBold" | "subtitle" | "link";
};
export function ThemedText({
style,
lightColor,
darkColor,
- type = 'default',
+ type = "default",
...rest
}: ThemedTextProps) {
- const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
+ const color = useThemeColor({ light: lightColor, dark: darkColor }, "text");
return (
<Text
style={[
{ color },
- type === 'default' ? styles.default : undefined,
- type === 'title' ? styles.title : undefined,
- type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined,
- type === 'subtitle' ? styles.subtitle : undefined,
- type === 'link' ? styles.link : undefined,
+ type === "default" ? styles.default : undefined,
+ type === "title" ? styles.title : undefined,
+ type === "defaultSemiBold" ? styles.defaultSemiBold : undefined,
+ type === "subtitle" ? styles.subtitle : undefined,
+ type === "link" ? styles.link : undefined,
style,
]}
{...rest}
@@ -41,20 +42,20 @@ const styles = StyleSheet.create({
defaultSemiBold: {
fontSize: 16,
lineHeight: 24,
- fontWeight: '600',
+ fontWeight: "600",
},
title: {
fontSize: 32,
- fontWeight: 'bold',
+ fontWeight: "bold",
lineHeight: 32,
},
subtitle: {
fontSize: 20,
- fontWeight: 'bold',
+ fontWeight: "bold",
},
link: {
lineHeight: 30,
fontSize: 16,
- color: '#0a7ea4',
+ color: "#0a7ea4",
},
});
diff --git a/components/ThemedView.tsx b/components/ThemedView.tsx
index 4d2cb09..fe06be6 100644
--- a/components/ThemedView.tsx
+++ b/components/ThemedView.tsx
@@ -1,14 +1,23 @@
-import { View, type ViewProps } from 'react-native';
+"use client";
+import { View, type ViewProps } from "react-native";
-import { useThemeColor } from '@/hooks/useThemeColor';
+import { useThemeColor } from "@/hooks/useThemeColor";
export type ThemedViewProps = ViewProps & {
lightColor?: string;
darkColor?: string;
};
-export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
- const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
+export function ThemedView({
+ style,
+ lightColor,
+ darkColor,
+ ...otherProps
+}: ThemedViewProps) {
+ const backgroundColor = useThemeColor(
+ { light: lightColor, dark: darkColor },
+ "background",
+ );
return <View style={[{ backgroundColor }, style]} {...otherProps} />;
}
diff --git a/components/login/ShipCredsForm.tsx b/components/login/ShipCredsForm.tsx
new file mode 100644
index 0000000..15712c2
--- /dev/null
+++ b/components/login/ShipCredsForm.tsx
@@ -0,0 +1,105 @@
+"use client";
+import { ColorScheme, lightColors } from "@/constants";
+import { BottomTabBarButtonProps } from "@react-navigation/bottom-tabs";
+import {
+ StyleSheet,
+ TextInput,
+ TouchableOpacity,
+ View,
+ Text,
+} from "react-native";
+import PrimaryButton from "../PrimaryButton";
+import { useState } from "react";
+
+export function ShipForm() {
+ const colors = lightColors;
+ const styles = getStyles(colors);
+ const [patp, setPatp] = useState("~mirtyl-wacdec");
+ const [ticket, setTicket] = useState("~posseg-winnub-fogluc-dirmes");
+ const [isLoading, setIsLoading] = useState(false);
+ async function onSubmit() {
+ console.log({ patp, ticket });
+ }
+ return (
+ <View style={styles.bottomSection}>
+ <TextInput
+ style={styles.input}
+ placeholder="~sampel-palnet"
+ placeholderTextColor={colors.secondary}
+ value={patp}
+ onChangeText={setPatp}
+ autoCapitalize="none"
+ autoCorrect={false}
+ />
+ <TextInput
+ style={styles.input}
+ placeholder="~sampel-ticlyt-migfun-falmel"
+ placeholderTextColor={colors.secondary}
+ value={ticket}
+ onChangeText={setTicket}
+ autoCapitalize="none"
+ autoCorrect={false}
+ secureTextEntry
+ />
+
+ <PrimaryButton
+ label="Log in"
+ onPress={onSubmit}
+ style={{ marginTop: 0 }}
+ isLoading={isLoading}
+ />
+
+ <TouchableOpacity style={styles.footer}>
+ <Text style={styles.footerText}>No Urbit ID? Get yours.</Text>
+ </TouchableOpacity>
+ </View>
+ );
+}
+export const getStyles = (colors: ColorScheme) =>
+ StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: colors.background,
+ justifyContent: "space-between",
+ padding: 20,
+ },
+ topSection: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ },
+ walletIcon: {
+ width: 64,
+ height: 64,
+ marginBottom: 12,
+ },
+ logoText: {
+ fontSize: 18,
+ color: colors.text,
+ fontWeight: "400",
+ },
+ bottomSection: {
+ gap: 8,
+ marginBottom: 40,
+ },
+ input: {
+ height: 48,
+ backgroundColor: colors.card,
+ borderColor: colors.border,
+ borderWidth: 1,
+ borderRadius: 8,
+ paddingHorizontal: 16,
+ paddingVertical: 12,
+ color: colors.text,
+ fontWeight: "500",
+ fontSize: 16,
+ },
+ footer: {
+ marginTop: 50,
+ alignItems: "center",
+ },
+ footerText: {
+ color: colors.text,
+ fontSize: 16,
+ },
+ });