Skip to content

Commit

Permalink
feat: added shadcn ui in native
Browse files Browse the repository at this point in the history
  • Loading branch information
rajatsandeepsen committed Jan 25, 2024
1 parent 8848d9f commit b740ac0
Show file tree
Hide file tree
Showing 199 changed files with 22,493 additions and 227 deletions.
22 changes: 21 additions & 1 deletion .vscode/project.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"folders": [
{
"path": "..",
"name": "root",
"name": "root"
},
{
"name": "native",
Expand All @@ -12,5 +12,25 @@
"name": "web",
"path": "../apps/web/"
},
{
"name": "auth-proxy",
"path": "../apps/auth-proxy/"
},
{
"name": "api",
"path": "../packages/api/"
},
{
"name": "db",
"path": "../packages/db/"
},
{
"name": "auth",
"path": "../packages/auth/"
},
{
"name": "tooling",
"path": "../tooling/"
}
]
}
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"editor.codeActionsOnSave": { "source.fixAll.eslint": true },
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }],
Expand Down
2 changes: 1 addition & 1 deletion apps/native/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @type {import("@babel/core").ConfigFunction} */
module.exports = function (api) {
module.exports = (api) => {
api.cache.forever();

return {
Expand Down
9 changes: 6 additions & 3 deletions apps/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "expo-router/entry",
"scripts": {
"clean": "git clean -xdf .expo .turbo node_modules",
"dev": "expo start --ios",
"dev": "expo start --go",
"dev:android": "expo start --android",
"dev:ios": "expo start --ios",
"lint": "eslint .",
Expand All @@ -21,6 +21,8 @@
"@trpc/client": "next",
"@trpc/react-query": "next",
"@trpc/server": "next",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"expo": "^49.0.18",
"expo-constants": "~14.4.2",
"expo-linking": "~5.0.2",
Expand All @@ -35,7 +37,8 @@
"react-native-reanimated": "~3.3.0",
"react-native-safe-area-context": "4.6.3",
"react-native-screens": "~3.22.1",
"superjson": "2.2.0"
"superjson": "2.2.0",
"tailwind-merge": "^2.2.1"
},
"devDependencies": {
"@acme/api": "workspace:^0.1.0",
Expand Down Expand Up @@ -65,4 +68,4 @@
]
},
"prettier": "@acme/prettier-config"
}
}
15 changes: 1 addition & 14 deletions apps/native/src/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,10 @@ import { TRPCProvider } from "~/utils/api";

import "../styles.css";

// This is the main layout of the app
// It wraps your pages with the providers they need
const RootLayout = () => {
return (
<TRPCProvider>
{/*
The Stack component displays the current page.
It also allows you to configure your screens
*/}
<Stack
screenOptions={{
headerStyle: {
backgroundColor: "#f472b6",
},
}}
/>
<StatusBar />
<Stack />
</TRPCProvider>
);
};
Expand Down
135 changes: 8 additions & 127 deletions apps/native/src/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,144 +1,25 @@
import React from "react";
import { Button, Pressable, Text, TextInput, View } from "react-native";
import { Text, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { Link, Stack } from "expo-router";
import { FlashList } from "@shopify/flash-list";
import { Button } from "~/components/ui/button";
import { Card } from "~/components/ui/card";

import { api } from "~/utils/api";
import type { RouterOutputs } from "~/utils/api";

function PostCard(props: {
post: RouterOutputs["post"]["all"][number];
onDelete: () => void;
}) {
return (
<View className="flex flex-row rounded-lg bg-white/10 p-4">
<View className="flex-grow">
<Link
asChild
href={{
pathname: "/post/[id]",
params: { id: props.post.id },
}}
>
<Pressable>
<Text className="text-xl font-semibold text-pink-400">
{props.post.title}
</Text>
<Text className="mt-2 text-white">{props.post.content}</Text>
</Pressable>
</Link>
</View>
<Pressable onPress={props.onDelete}>
<Text className="font-bold uppercase text-pink-400">Delete</Text>
</Pressable>
</View>
);
}

function CreatePost() {
const utils = api.useContext();

const [title, setTitle] = React.useState("");
const [content, setContent] = React.useState("");

const { mutate, error } = api.post.create.useMutation({
async onSuccess() {
setTitle("");
setContent("");
await utils.post.all.invalidate();
},
});

return (
<View className="mt-4">
<TextInput
className="mb-2 rounded bg-white/10 p-2 text-white"
placeholderTextColor="rgba(255, 255, 255, 0.5)"
value={title}
onChangeText={setTitle}
placeholder="Title"
/>
{error?.data?.zodError?.fieldErrors.title && (
<Text className="mb-2 text-red-500">
{error.data.zodError.fieldErrors.title}
</Text>
)}
<TextInput
className="mb-2 rounded bg-white/10 p-2 text-white"
placeholderTextColor="rgba(255, 255, 255, 0.5)"
value={content}
onChangeText={setContent}
placeholder="Content"
/>
{error?.data?.zodError?.fieldErrors.content && (
<Text className="mb-2 text-red-500">
{error.data.zodError.fieldErrors.content}
</Text>
)}
<Pressable
className="rounded bg-pink-400 p-2"
onPress={() => {
mutate({
title,
content,
});
}}
>
<Text className="font-semibold text-white">Publish post</Text>
</Pressable>
{error?.data?.code === "UNAUTHORIZED" && (
<Text className="mt-2 text-red-500">
You need to be logged in to create a post
</Text>
)}
</View>
);
}

const Index = () => {
const utils = api.useContext();

const postQuery = api.post.all.useQuery();

const deletePostMutation = api.post.delete.useMutation({
onSettled: () => utils.post.all.invalidate(),
});

return (
<SafeAreaView className="bg-[#1F104A]">
{/* Changes page title visible on the header */}
<Stack.Screen options={{ title: "Home Page" }} />
<View className="h-full w-full p-4">
<Text className="pb-2 text-center text-5xl font-bold text-white">
Create <Text className="text-pink-400">T3</Text> Turbo
</Text>

<Button
onPress={() => void utils.post.all.invalidate()}
title="Refresh posts"
color={"#f472b6"}
/>

<View className="py-2">
<Text className="font-semibold italic text-white">
Press on a post
</Text>
<Card className="p-10">
<Button variant={"destructive"}>
hi
</Button>
</Card>
</View>

<FlashList
data={postQuery.data}
estimatedItemSize={20}
ItemSeparatorComponent={() => <View className="h-2" />}
renderItem={(p) => (
<PostCard
post={p.item}
onDelete={() => deletePostMutation.mutate(p.item.id)}
/>
)}
/>

<CreatePost />
</View>
</SafeAreaView>
);
Expand Down
31 changes: 31 additions & 0 deletions apps/native/src/components/DrawerToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DrawerNavigationProp } from '@react-navigation/drawer';
import { useNavigation } from 'expo-router';
import { AlignJustify } from 'lucide-react-native';
import { Pressable, View } from 'react-native';
import { cn } from '~/lib/utils';

export function DrawerToggle() {
const navigation = useNavigation<DrawerNavigationProp<{}>>();

return (
<Pressable
onPress={navigation.toggleDrawer}
className='ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'
>
{({ pressed }) => (
<View
className={cn(
'flex-1 aspect-square justify-center items-end pt-0.5 web:pl-4',
pressed && 'opacity-70'
)}
>
<AlignJustify
className='text-foreground'
size={24}
strokeWidth={1.25}
/>
</View>
)}
</Pressable>
);
}
40 changes: 40 additions & 0 deletions apps/native/src/components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { MoonStar, Sun } from 'lucide-react-native';
import { useColorScheme } from 'nativewind';
import { Pressable, View } from 'react-native';
import { setAndroidNavigationBar } from '~/lib/android-navigation-bar';
import { cn } from '~/lib/utils';

export function ThemeToggle() {
const { colorScheme, setColorScheme } = useColorScheme();
return (
<Pressable
onPress={() => {
const newTheme = colorScheme === 'dark' ? 'light' : 'dark';
setColorScheme(newTheme);
setAndroidNavigationBar(newTheme);
AsyncStorage.setItem('theme', newTheme);
}}
className='ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'
>
{({ pressed }) => (
<View
className={cn(
'flex-1 aspect-square pt-0.5 justify-center items-start web:px-5',
pressed && 'opacity-70'
)}
>
{colorScheme === 'light' ? (
<Sun className='text-foreground' size={24} strokeWidth={1.25} />
) : (
<MoonStar
className='text-foreground'
size={24}
strokeWidth={1.25}
/>
)}
</View>
)}
</Pressable>
);
}
Loading

0 comments on commit b740ac0

Please sign in to comment.