Skip to content

Commit

Permalink
Improved Overall UX/UI of some elements. Use secure store on mobile. …
Browse files Browse the repository at this point in the history
…Handle errors in auth callback. Added Windsurf rules.
  • Loading branch information
Gbuomprisco committed Jan 19, 2025
1 parent 17ef527 commit 1299d1c
Show file tree
Hide file tree
Showing 34 changed files with 622 additions and 213 deletions.
4 changes: 3 additions & 1 deletion .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ The below is the Expo app structure:
--- supabase # supabase root
```

Features are located in the "packages/features" directory. We should colocate the components, hooks, and lib files for a feature together. Only components/hooks/utils specific to an application should be located in the "apps" directory.
- Features are located in the "packages/features" directory.
- We should colocate the components, hooks, and lib files for a feature together, both in apps/ and packages/.
- Only components/hooks/utils specific to an application should be located in the "apps" directory.

## Database

Expand Down
95 changes: 95 additions & 0 deletions .windsurfrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Makerkit Guidelines

You are an expert programming assistant focusing on:

- Expertise: Expo, React Native, Supabase, TypeScript, Tailwind CSS in a Turborepo project
- Focus: Code clarity, Readability, Best practices, Maintainability
- Style: Expert level, factual, solution-focused
- Libraries: TypeScript, React Hook Form, React Query, Zod, Lucide React Native

## Project Structure

The below is the Expo app structure:

```
- apps
-- expo-app
--- (app)
---- (main) # protected routes
---- auth # auth pages
--- components # global components
--- supabase # supabase root
```

- Features are located in the "packages/features" directory.
- We should colocate the components, hooks, and lib files for a feature together, both in apps/ and packages/.
- Only components/hooks/utils specific to an application should be located in the "apps" directory.

## Database

- Supabase uses Postgres
- We strive to create a safe, robust, performant schema
- Accounts are the general concept of a user account, defined by the having the same ID as Supabase Auth's users (personal).
- Generally speaking, other tables will be used to store data related to the account. For example, a table `notes` would have a foreign key `account_id` to link it to an account.
- Using RLS, we must ensure that only the account owner can access the data. Always write safe RLS policies and ensure that the policies are enforced.
- Unless specified, always enable RLS when creating a table. Propose the required RLS policies ensuring the safety of the data.
- Always consider any required constraints and triggers are in place for data consistency
- Always consider the compromises you need to make and explain them so I can make an educated decision. Follow up with the considerations make and explain them.
- Always consider the security of the data and explain the security implications of the data.
- Always use Postgres schemas explicitly (e.g., `public.accounts`)
- Data types should always be inferred using the `Database` types from `@kit/supabase/database`

```tsx
import type { Tables } from "@kit/supabase";
type Bookmark = Tables<"bookmarks">;
```

## UI Components

Reusable UI components are defined in the "packages/ui" package named `@kit/ui`. All components are exported from `@kit/ui`

### Code Standards

- Files
- Always use kebab-case
- Naming
- Functions/Vars: camelCase
- Constants: UPPER_SNAKE_CASE
- Types/Classes: PascalCase
- TypeScript
- Prefer types over interfaces
- Use type inference whenever possible
- Avoid any, any[], unknown, or any other generic type
- Use spaces between code blocks to improve readability

### Styling

- Styling is done using Tailwind CSS. We use the "cn" function from the "@kit/ui" package to generate class names.
- Avoid fixes classes such as "bg-gray-500". Instead, use Shadcn classes such as "bg-background", "text-secondary-foreground", "text-muted-foreground", etc.

### Data Fetching

- In a Client Component context, please use the `useQuery` hook from the "@tanstack/react-query" package to wrap any async data fetching.

#### Supabase Clients

- Use the `useSupabase` hook from the `@kit/supabase` package in React Components to get the Supabase client. You can use the Supabase Client in combination with the `useQuery` hook to fetch data.

#### React Query

When using `useQuery`, make sure to define the data fetching hook. Create two components: one that fetches the data and one that displays the data.

## Forms

- Use Zod for form validation.
- Use the `zodResolver` function to resolve the Zod schema to the form.
- Always use `@kit/ui/form` for writing the UI of the form
- Use `react-hook-form` for the form's state management
- Use React Query's mutation to submit the form mutation

## Error Handling

- Don't swallow errors, always handle them appropriately
- Handle promises and async/await gracefully
- Consider the unhappy path and handle errors appropriately
- Context without sensitive data
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@

# NEW! Expo + Supabase - React Native Starter Kit by MakerKit.dev

This is a starter kit for React Native applications, mostly useful as a companion Starter Kit for [MakerKit](https://makerkit.dev), but can be used as a standalone starter kit.
This is a starter kit for React Native applications, mostly useful as a
companion Starter Kit for [MakerKit](https://makerkit.dev), but can be used as a
standalone starter kit.

It uses Expo and Supabase for authentication and database management.

NB: this is an early preview. It likely contains bugs, and the documentation is still incomplete.
NB: this is an early preview. It likely contains bugs, and the documentation is
still incomplete.

## What's Included

### Core Architecture

- 🏗️ Expo + React Native
- 🎨 NativeWind + Tailwind CSS + [React Native Reusable Components](https://rnr-docs.vercel.app/getting-started/introduction/)
- 🎨 NativeWind + Tailwind CSS +
[React Native Reusable Components](https://rnr-docs.vercel.app/getting-started/introduction/)
- 🔐 Supabase authentication & basic DB
- ✨ Full TypeScript + ESLint + Prettier configuration

### Key Features

- 👤 User authentication flow
- ⚙️ User profile & settings
- 🔒 Protected routes
Expand All @@ -30,11 +36,17 @@ This starter kit provides core foundations:
- [Supabase](https://supabase.com/) - Authentication and database management
- [NativeWind](https://nativewind.dev/) - Tailwind CSS for React Native
- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework
- [React Native Reusable Components](https://rnr-docs.vercel.app/getting-started/introduction/) - Reusable React Native components
- [React Native Reusable Components](https://rnr-docs.vercel.app/getting-started/introduction/) -
Reusable React Native components
- [TypeScript](https://www.typescriptlang.org/) - Typed JavaScript
- [ESLint](https://eslint.org/) - Linting and code formatting
- [Prettier](https://prettier.io/) - Code formatting

## Preview

![Sign In](apps/expo-app/assets/images/sign-in.png)
![Sign Up](apps/expo-app/assets/images/sign-up.png)

## Requirements

- Node.js 18.x
Expand Down Expand Up @@ -88,12 +100,16 @@ The documentation is not yet available. Please check back later.

## Contributing

Contributions for bug fixed are welcome! However, please open an issue first to discuss your ideas before making a pull request.
Contributions for bug fixed are welcome! However, please open an issue first to
discuss your ideas before making a pull request.

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file
for more details.

## Support

No support is provided for this kit. Feel free to open an issue if you have any questions or need help, but there is no guaranteed response time, nor guarantee a fix.
No support is provided for this kit. Feel free to open an issue if you have any
questions or need help, but there is no guaranteed response time, nor guarantee
a fix.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Link } from 'expo-router';
import { ChevronRight } from 'lucide-react-native';
import { FlatList, View } from 'react-native';

import { Text } from '@kit/ui';

import { SignOutButton } from './sign-out-button';

type Page = {
name: string;
title: string;
href: string;
};

const pages: Page[] = [
{
name: 'application',
title: 'Application',
href: '/settings/application' as const,
},
{
name: 'profile',
title: 'Profile',
href: '/settings/profile' as const,
},
{
name: 'account',
title: 'Account',
href: '/settings/account' as const,
},
];

export function SettingsPagesList() {
return (
<View className={'h-full w-full flex-1 flex-col space-y-8 p-4'}>
<FlatList
data={pages}
ItemSeparatorComponent={() => (
<View className={'h-px w-full bg-border'} />
)}
renderItem={({ item }) => (
<Link className={'h-14'} href={item.href}>
<View
className={'h-full w-full flex-row items-center justify-between'}
>
<Text className={'text-lg'}>{item.title}</Text>
<ChevronRight className={'h-5'} />
</View>
</Link>
)}
/>

<SignOutButton />
</View>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useSignOut } from '@kit/supabase';
import { Button, Text } from '@kit/ui';

export function SignOutButton() {
const signOutMutation = useSignOut();

return (
<Button
variant={'destructive'}
className={'mt-auto'}
onPress={() => signOutMutation.mutate()}
>
<Text>Sign Out</Text>
</Button>
);
}
2 changes: 1 addition & 1 deletion apps/expo-app/app/(app)/(main)/settings/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { UpdateAccountContainer } from '@kit/account';

export default function AccountSettingsPage() {
return (
<View>
<View className="flex-1 p-4">
<Stack.Screen
options={{
title: 'Account',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Moon, Sun } from 'lucide-react-native';
import { useColorScheme } from 'nativewind';
import { View } from 'react-native';

import { ToggleGroup, ToggleGroupItem } from '@kit/ui';

type Theme = 'light' | 'dark' | 'system';

export function ThemeModeToggle() {
const { colorScheme, setColorScheme } = useColorScheme();

return (
<View className="flex justify-start">
<ToggleGroup
className="justify-start"
type="single"
value={colorScheme}
onValueChange={async (value) => {
setColorScheme(value as Theme);
await AsyncStorage.setItem('theme', value as Theme);
}}
>
<ToggleGroupItem value="light" aria-label="Light Mode">
<Sun className="h-4 w-4 text-secondary-foreground" />
</ToggleGroupItem>

<ToggleGroupItem value="dark" aria-label="Dark Mode">
<Moon className="h-4 w-4 text-secondary-foreground" />
</ToggleGroupItem>
</ToggleGroup>
</View>
);
}
43 changes: 43 additions & 0 deletions apps/expo-app/app/(app)/(main)/settings/application/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Stack } from 'expo-router';
import { Text, View } from 'react-native';

Check failure on line 2 in apps/expo-app/app/(app)/(main)/settings/application/index.tsx

View workflow job for this annotation

GitHub Actions / ʦ TypeScript

'Text' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 2 in apps/expo-app/app/(app)/(main)/settings/application/index.tsx

View workflow job for this annotation

GitHub Actions / ʦ TypeScript

'Text' is defined but never used

import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@kit/ui';

import { ThemeModeToggle } from './_components/theme-mode-toggle';

export default function ApplicationSettingsPage() {
return (
<View className="flex-1 p-4">
<Stack.Screen
options={{
title: 'Application',
headerBackVisible: true,
headerBackTitle: 'Settings',
headerBackButtonMenuEnabled: true,
}}
/>

<View className="gap-4">
<Card>
<CardHeader>
<CardTitle>Appearance</CardTitle>

<CardDescription>
Customize your app's theme and appearance
</CardDescription>
</CardHeader>

<CardContent>
<ThemeModeToggle />
</CardContent>
</Card>
</View>
</View>
);
}
Loading

0 comments on commit 1299d1c

Please sign in to comment.