newcandies 0.1.23 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/app-briefs/expo-router/cozynotes/README.md +79 -0
- package/templates/app-briefs/expo-router/cozynotes/app.json +51 -0
- package/templates/app-briefs/expo-router/cozynotes/assets/fonts/Caveat-Bold.ttf +0 -0
- package/templates/app-briefs/expo-router/cozynotes/assets/fonts/Caveat-Regular.ttf +0 -0
- package/templates/app-briefs/expo-router/cozynotes/assets/images/adaptive-icon.png +0 -0
- package/templates/app-briefs/expo-router/cozynotes/assets/images/favicon.png +0 -0
- package/templates/app-briefs/expo-router/cozynotes/assets/images/icon.png +0 -0
- package/templates/app-briefs/expo-router/cozynotes/assets/images/splash-icon.png +0 -0
- package/templates/app-briefs/expo-router/cozynotes/babel.config.js +8 -0
- package/templates/app-briefs/expo-router/cozynotes/eas.json +22 -0
- package/templates/app-briefs/expo-router/cozynotes/env +2 -0
- package/templates/app-briefs/expo-router/cozynotes/expo-env.d.ts +3 -0
- package/templates/app-briefs/expo-router/cozynotes/global.css +37 -0
- package/templates/app-briefs/expo-router/cozynotes/metro.config.js +15 -0
- package/templates/app-briefs/expo-router/cozynotes/package.json +53 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/_layout.tsx +24 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/about.tsx +25 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/index.tsx +62 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/note/[id].tsx +39 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/note/edit.tsx +30 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/note/new.tsx +26 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/settings.tsx +24 -0
- package/templates/app-briefs/expo-router/cozynotes/src/components/screens/home/note-card.tsx +65 -0
- package/templates/app-briefs/expo-router/cozynotes/src/components/ui/back-button.tsx +24 -0
- package/templates/app-briefs/expo-router/cozynotes/src/components/ui/screen.tsx +20 -0
- package/templates/app-briefs/expo-router/cozynotes/src/components/ui/squircle.tsx +7 -0
- package/templates/app-briefs/expo-router/cozynotes/src/components/ui/text.tsx +48 -0
- package/templates/app-briefs/expo-router/cozynotes/src/lib/constants/index.ts +2 -0
- package/templates/app-briefs/expo-router/cozynotes/src/lib/constants/notes.ts +136 -0
- package/templates/app-briefs/expo-router/cozynotes/src/types/note.d.ts +9 -0
- package/templates/app-briefs/expo-router/cozynotes/tsconfig.json +17 -0
- package/templates/app-briefs/expo-router/flourish/README.md +100 -0
- package/templates/app-briefs/expo-router/flourish/app.json +42 -0
- package/templates/app-briefs/expo-router/flourish/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/templates/app-briefs/expo-router/flourish/assets/images/adaptive-icon.png +0 -0
- package/templates/app-briefs/expo-router/flourish/assets/images/favicon.png +0 -0
- package/templates/app-briefs/expo-router/flourish/assets/images/icon.png +0 -0
- package/templates/app-briefs/expo-router/flourish/assets/images/splash-icon.png +0 -0
- package/templates/app-briefs/expo-router/flourish/babel.config.js +8 -0
- package/templates/app-briefs/expo-router/flourish/eas.json +22 -0
- package/templates/app-briefs/expo-router/flourish/env +2 -0
- package/templates/app-briefs/expo-router/flourish/expo-env.d.ts +3 -0
- package/templates/app-briefs/expo-router/flourish/global.css +53 -0
- package/templates/app-briefs/expo-router/flourish/metro.config.js +15 -0
- package/templates/app-briefs/expo-router/flourish/package.json +54 -0
- package/templates/app-briefs/expo-router/flourish/src/app/(tabs)/_layout.tsx +71 -0
- package/templates/app-briefs/expo-router/flourish/src/app/(tabs)/explore.tsx +24 -0
- package/templates/app-briefs/expo-router/flourish/src/app/(tabs)/index.tsx +102 -0
- package/templates/app-briefs/expo-router/flourish/src/app/(tabs)/profile.tsx +25 -0
- package/templates/app-briefs/expo-router/flourish/src/app/(tabs)/search.tsx +24 -0
- package/templates/app-briefs/expo-router/flourish/src/app/_layout.tsx +31 -0
- package/templates/app-briefs/expo-router/flourish/src/app/plant/[id].tsx +48 -0
- package/templates/app-briefs/expo-router/flourish/src/components/ui/screen.tsx +20 -0
- package/templates/app-briefs/expo-router/flourish/src/components/ui/squircle.tsx +5 -0
- package/templates/app-briefs/expo-router/flourish/src/components/ui/text.tsx +55 -0
- package/templates/app-briefs/expo-router/flourish/src/lib/constants/index.ts +148 -0
- package/templates/app-briefs/expo-router/flourish/src/lib/utils/index.ts +8 -0
- package/templates/app-briefs/expo-router/flourish/src/types/plant.d.ts +38 -0
- package/templates/app-briefs/expo-router/flourish/tsconfig.json +17 -0
- package/templates/app-briefs/expo-router/flourish-auth/README.md +153 -0
- package/templates/app-briefs/expo-router/flourish-auth/app.json +42 -0
- package/templates/app-briefs/expo-router/flourish-auth/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/templates/app-briefs/expo-router/flourish-auth/assets/images/adaptive-icon.png +0 -0
- package/templates/app-briefs/expo-router/flourish-auth/assets/images/favicon.png +0 -0
- package/templates/app-briefs/expo-router/flourish-auth/assets/images/icon.png +0 -0
- package/templates/app-briefs/expo-router/flourish-auth/assets/images/splash-icon.png +0 -0
- package/templates/app-briefs/expo-router/flourish-auth/babel.config.js +8 -0
- package/templates/app-briefs/expo-router/flourish-auth/eas.json +22 -0
- package/templates/app-briefs/expo-router/flourish-auth/env +2 -0
- package/templates/app-briefs/expo-router/flourish-auth/expo-env.d.ts +3 -0
- package/templates/app-briefs/expo-router/flourish-auth/global.css +53 -0
- package/templates/app-briefs/expo-router/flourish-auth/metro.config.js +15 -0
- package/templates/app-briefs/expo-router/flourish-auth/package.json +55 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(auth)/_layout.tsx +14 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(auth)/sign-in.tsx +25 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(auth)/sign-up.tsx +26 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(auth)/welcome.tsx +22 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(tabs)/_layout.tsx +71 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(tabs)/explore.tsx +24 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(tabs)/index.tsx +102 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(tabs)/profile.tsx +27 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/(tabs)/search.tsx +24 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/_layout.tsx +48 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/app/plant/[id].tsx +48 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/components/ui/screen.tsx +20 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/components/ui/squircle.tsx +5 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/components/ui/text.tsx +55 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/lib/constants/index.ts +148 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/lib/stores/README.md +31 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/lib/utils/index.ts +8 -0
- package/templates/app-briefs/expo-router/flourish-auth/src/types/plant.d.ts +38 -0
- package/templates/app-briefs/expo-router/flourish-auth/tsconfig.json +17 -0
- package/templates/app-briefs/react-query/sproutsy/global.css +23 -0
- package/templates/app-briefs/zustand/yummy/README.md +63 -0
- package/templates/app-briefs/zustand/yummy/app.json +42 -0
- package/templates/app-briefs/zustand/yummy/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/templates/app-briefs/zustand/yummy/assets/images/adaptive-icon.png +0 -0
- package/templates/app-briefs/zustand/yummy/assets/images/favicon.png +0 -0
- package/templates/app-briefs/zustand/yummy/assets/images/icon.png +0 -0
- package/templates/app-briefs/zustand/yummy/assets/images/splash-icon.png +0 -0
- package/templates/app-briefs/zustand/yummy/babel.config.js +8 -0
- package/templates/app-briefs/zustand/yummy/eas.json +22 -0
- package/templates/app-briefs/zustand/yummy/env +2 -0
- package/templates/app-briefs/zustand/yummy/expo-env.d.ts +3 -0
- package/templates/app-briefs/zustand/yummy/global.css +69 -0
- package/templates/app-briefs/zustand/yummy/metro.config.js +15 -0
- package/templates/app-briefs/zustand/yummy/package.json +55 -0
- package/templates/app-briefs/zustand/yummy/src/app/(tabs)/_layout.tsx +63 -0
- package/templates/app-briefs/zustand/yummy/src/app/(tabs)/cart.tsx +146 -0
- package/templates/app-briefs/zustand/yummy/src/app/(tabs)/index.tsx +76 -0
- package/templates/app-briefs/zustand/yummy/src/app/_layout.tsx +37 -0
- package/templates/app-briefs/zustand/yummy/src/components/ui/screen.tsx +18 -0
- package/templates/app-briefs/zustand/yummy/src/components/ui/squircle.tsx +5 -0
- package/templates/app-briefs/zustand/yummy/src/components/ui/text.tsx +55 -0
- package/templates/app-briefs/zustand/yummy/src/lib/constants/index.ts +45 -0
- package/templates/app-briefs/zustand/yummy/src/store/README.md +45 -0
- package/templates/app-briefs/zustand/yummy/src/types/product.d.ts +12 -0
- package/templates/app-briefs/zustand/yummy/tsconfig.json +17 -0
- package/templates/registry.json +40 -2
package/package.json
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# CozyNote - Expo Router Stack Navigation
|
|
2
|
+
|
|
3
|
+
A beautiful note-taking app brief for learning Expo Router stack navigation.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This app brief demonstrates stack navigation patterns including:
|
|
8
|
+
- Basic stack navigation with `Stack` component
|
|
9
|
+
- Dynamic routes with `[id]` parameter
|
|
10
|
+
- Native header configuration with `Stack.Screen`
|
|
11
|
+
- Header customization (left, right, title)
|
|
12
|
+
- Modal presentation styles
|
|
13
|
+
|
|
14
|
+
## Getting Started
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Install dependencies
|
|
18
|
+
bun install
|
|
19
|
+
|
|
20
|
+
# Start the app
|
|
21
|
+
bun start
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Learning Tasks
|
|
25
|
+
|
|
26
|
+
### 1. Set up Stack Navigator
|
|
27
|
+
Replace `<Slot />` in `_layout.tsx` with proper `<Stack>` configuration.
|
|
28
|
+
|
|
29
|
+
### 2. Build Note Detail Screen (`note/[id].tsx`)
|
|
30
|
+
- Add `BackButton` component at top
|
|
31
|
+
- Display note title and full content
|
|
32
|
+
- Add edit button linking to `/note/edit`
|
|
33
|
+
|
|
34
|
+
### 3. Build Create Note Screen (`note/new.tsx`)
|
|
35
|
+
- Add header with close button and "Create" action
|
|
36
|
+
- Implement title and content inputs
|
|
37
|
+
- Handle form submission
|
|
38
|
+
|
|
39
|
+
### 4. Build Edit Note Screen (`note/edit.tsx`)
|
|
40
|
+
- Pre-fill inputs with existing note data
|
|
41
|
+
- Add save functionality
|
|
42
|
+
|
|
43
|
+
### 5. Build Settings Screen (`settings.tsx`)
|
|
44
|
+
- Display app info
|
|
45
|
+
- Link to About screen
|
|
46
|
+
|
|
47
|
+
### 6. Build About Screen (`about.tsx`)
|
|
48
|
+
- Configure native header with `Stack.Screen`
|
|
49
|
+
- Add header buttons (back, share, info)
|
|
50
|
+
- Display app description
|
|
51
|
+
|
|
52
|
+
## Project Structure
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
src/
|
|
56
|
+
├── app/
|
|
57
|
+
│ ├── _layout.tsx # Root stack navigator
|
|
58
|
+
│ ├── index.tsx # Home screen (notes list)
|
|
59
|
+
│ ├── settings.tsx # Settings screen
|
|
60
|
+
│ ├── about.tsx # About screen (native header)
|
|
61
|
+
│ └── note/
|
|
62
|
+
│ ├── [id].tsx # Note detail (dynamic route)
|
|
63
|
+
│ ├── new.tsx # Create note
|
|
64
|
+
│ └── edit.tsx # Edit note
|
|
65
|
+
├── components/
|
|
66
|
+
│ ├── screens/
|
|
67
|
+
│ │ └── home/
|
|
68
|
+
│ │ └── note-card.tsx
|
|
69
|
+
│ └── ui/
|
|
70
|
+
│ ├── back-button.tsx
|
|
71
|
+
│ ├── screen.tsx
|
|
72
|
+
│ ├── squircle.tsx
|
|
73
|
+
│ └── text.tsx
|
|
74
|
+
└── lib/
|
|
75
|
+
└── constants/
|
|
76
|
+
├── index.ts
|
|
77
|
+
└── notes.ts
|
|
78
|
+
```
|
|
79
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"expo": {
|
|
3
|
+
"name": "cozynotes",
|
|
4
|
+
"slug": "cozynotes",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"orientation": "portrait",
|
|
7
|
+
"icon": "./assets/images/icon.png",
|
|
8
|
+
"scheme": "cozynotes",
|
|
9
|
+
"userInterfaceStyle": "automatic",
|
|
10
|
+
"newArchEnabled": true,
|
|
11
|
+
"splash": {
|
|
12
|
+
"image": "./assets/images/splash-icon.png",
|
|
13
|
+
"resizeMode": "contain",
|
|
14
|
+
"backgroundColor": "#ffffff"
|
|
15
|
+
},
|
|
16
|
+
"ios": {
|
|
17
|
+
"supportsTablet": true,
|
|
18
|
+
"bundleIdentifier": "com.example.cozynotes"
|
|
19
|
+
},
|
|
20
|
+
"android": {
|
|
21
|
+
"adaptiveIcon": {
|
|
22
|
+
"foregroundImage": "./assets/images/adaptive-icon.png",
|
|
23
|
+
"backgroundColor": "#ffffff"
|
|
24
|
+
},
|
|
25
|
+
"edgeToEdgeEnabled": true,
|
|
26
|
+
"predictiveBackGestureEnabled": false,
|
|
27
|
+
"package": "com.example.cozynotes"
|
|
28
|
+
},
|
|
29
|
+
"web": {
|
|
30
|
+
"bundler": "metro",
|
|
31
|
+
"output": "static",
|
|
32
|
+
"favicon": "./assets/images/favicon.png"
|
|
33
|
+
},
|
|
34
|
+
"plugins": [
|
|
35
|
+
"expo-router",
|
|
36
|
+
[
|
|
37
|
+
"expo-font",
|
|
38
|
+
{
|
|
39
|
+
"fonts": [
|
|
40
|
+
"./assets/fonts/Caveat-Regular.ttf",
|
|
41
|
+
"./assets/fonts/Caveat-Bold.ttf"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
],
|
|
46
|
+
"experiments": {
|
|
47
|
+
"typedRoutes": true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cli": {
|
|
3
|
+
"version": ">= 7.0.0"
|
|
4
|
+
},
|
|
5
|
+
"build": {
|
|
6
|
+
"development": {
|
|
7
|
+
"android": {
|
|
8
|
+
"buildType": "apk"
|
|
9
|
+
},
|
|
10
|
+
"developmentClient": true,
|
|
11
|
+
"distribution": "internal"
|
|
12
|
+
},
|
|
13
|
+
"preview": {
|
|
14
|
+
"distribution": "internal"
|
|
15
|
+
},
|
|
16
|
+
"production": {}
|
|
17
|
+
},
|
|
18
|
+
"submit": {
|
|
19
|
+
"production": {}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "uniwind";
|
|
3
|
+
|
|
4
|
+
@theme {
|
|
5
|
+
--font-caveat: 'Caveat-Regular';
|
|
6
|
+
--font-caveat-bold: 'Caveat-Bold';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@layer theme {
|
|
10
|
+
:root {
|
|
11
|
+
@variant light {
|
|
12
|
+
--color-background: #faf8f6;
|
|
13
|
+
--color-foreground: #2d2d2d;
|
|
14
|
+
|
|
15
|
+
--color-primary: #2d2d2d;
|
|
16
|
+
--color-primary-foreground: #ffffff;
|
|
17
|
+
|
|
18
|
+
--color-muted: #f0eeec;
|
|
19
|
+
--color-muted-foreground: #a8a8a8;
|
|
20
|
+
|
|
21
|
+
--color-card: #ffffff;
|
|
22
|
+
}
|
|
23
|
+
@variant dark {
|
|
24
|
+
--color-background: #1a1a1a;
|
|
25
|
+
--color-foreground: #f5f5f5;
|
|
26
|
+
|
|
27
|
+
--color-primary: #f5f5f5;
|
|
28
|
+
--color-primary-foreground: #1a1a1a;
|
|
29
|
+
|
|
30
|
+
--color-muted: #2d2d2d;
|
|
31
|
+
--color-muted-foreground: #888888;
|
|
32
|
+
|
|
33
|
+
--color-card: #242424;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const { withRozenite } = require("@rozenite/metro");
|
|
2
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
|
3
|
+
const { withUniwindConfig } = require("uniwind/metro");
|
|
4
|
+
|
|
5
|
+
const config = getDefaultConfig(__dirname);
|
|
6
|
+
|
|
7
|
+
module.exports = withRozenite(
|
|
8
|
+
withUniwindConfig(config, {
|
|
9
|
+
cssEntryFile: "./global.css",
|
|
10
|
+
dtsFile: "./uniwind-types.d.ts",
|
|
11
|
+
extraThemes: [],
|
|
12
|
+
}),
|
|
13
|
+
{ enabled: process.env.WITH_ROZENITE === "true" }
|
|
14
|
+
);
|
|
15
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cozynotes",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"main": "expo-router/entry",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "expo start --dev-client",
|
|
8
|
+
"android": "expo run:android",
|
|
9
|
+
"ios": "expo run:ios",
|
|
10
|
+
"prebuild": "expo prebuild"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@expo/vector-icons": "^15.0.3",
|
|
14
|
+
"@gorhom/bottom-sheet": "latest",
|
|
15
|
+
"@rozenite/mmkv-plugin": "^1.0.0-alpha.16",
|
|
16
|
+
"@rozenite/performance-monitor-plugin": "^1.0.0-alpha.16",
|
|
17
|
+
"@shopify/flash-list": "^2.2.0",
|
|
18
|
+
"expo": "54.0.23",
|
|
19
|
+
"expo-constants": "~18.0.10",
|
|
20
|
+
"expo-font": "~14.0.9",
|
|
21
|
+
"expo-linear-gradient": "^15.0.7",
|
|
22
|
+
"expo-linking": "~8.0.8",
|
|
23
|
+
"expo-router": "~6.0.14",
|
|
24
|
+
"expo-splash-screen": "~31.0.10",
|
|
25
|
+
"expo-status-bar": "~3.0.8",
|
|
26
|
+
"expo-system-ui": "~6.0.8",
|
|
27
|
+
"expo-web-browser": "~15.0.9",
|
|
28
|
+
"react": "19.1.0",
|
|
29
|
+
"react-dom": "19.1.0",
|
|
30
|
+
"react-native": "0.81.5",
|
|
31
|
+
"react-native-fast-squircle": "^1.0.11",
|
|
32
|
+
"react-native-gesture-handler": "~2.28.0",
|
|
33
|
+
"react-native-keyboard-controller": "latest",
|
|
34
|
+
"react-native-mmkv": "^4.0.0",
|
|
35
|
+
"react-native-reanimated": "~4.1.1",
|
|
36
|
+
"react-native-safe-area-context": "~5.6.0",
|
|
37
|
+
"react-native-screens": "~4.16.0",
|
|
38
|
+
"react-native-svg": "^15.14.0",
|
|
39
|
+
"react-native-web": "~0.21.0",
|
|
40
|
+
"react-native-worklets": "0.5.1",
|
|
41
|
+
"sonner-native": "latest",
|
|
42
|
+
"tailwind-merge": "latest",
|
|
43
|
+
"tailwindcss": "^4.1.16",
|
|
44
|
+
"uniwind": "^1.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@rozenite/metro": "^1.0.0-alpha.16",
|
|
48
|
+
"@types/react": "~19.1.0",
|
|
49
|
+
"babel-plugin-module-resolver": "latest",
|
|
50
|
+
"typescript": "~5.9.2"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import '../../global.css';
|
|
2
|
+
|
|
3
|
+
import { Slot } from 'expo-router';
|
|
4
|
+
import { StatusBar } from 'expo-status-bar';
|
|
5
|
+
|
|
6
|
+
export default function RootLayout() {
|
|
7
|
+
// TODO: Replace Slot with Stack navigator
|
|
8
|
+
// Example:
|
|
9
|
+
// import { Stack } from 'expo-router';
|
|
10
|
+
// return (
|
|
11
|
+
// <>
|
|
12
|
+
// <StatusBar style="dark" />
|
|
13
|
+
// <Stack screenOptions={{ headerShown: false }} />
|
|
14
|
+
// </>
|
|
15
|
+
// );
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<StatusBar style="dark" />
|
|
20
|
+
<Slot />
|
|
21
|
+
</>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import Screen from '~/components/ui/screen';
|
|
4
|
+
import Text from '~/components/ui/text';
|
|
5
|
+
|
|
6
|
+
export default function AboutScreen() {
|
|
7
|
+
// TODO: Build the about screen
|
|
8
|
+
// - Use Stack.Screen to configure native header
|
|
9
|
+
// - Set headerShown: true
|
|
10
|
+
// - Configure headerLeft with custom back button
|
|
11
|
+
// - Configure headerRight with share and info buttons
|
|
12
|
+
// - Display app icon, name, and description
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Screen>
|
|
16
|
+
<View className="flex-1 items-center justify-center px-8">
|
|
17
|
+
<Text variant="title">CozyNote</Text>
|
|
18
|
+
<Text variant="note" className="text-center mt-6 text-muted-foreground">
|
|
19
|
+
Build this screen with native header configuration
|
|
20
|
+
</Text>
|
|
21
|
+
</View>
|
|
22
|
+
</Screen>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
2
|
+
import { Link } from 'expo-router';
|
|
3
|
+
import { FlatList, ImageBackground, Pressable, StyleSheet, View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import NoteCard from '~/components/screens/home/note-card';
|
|
6
|
+
import Screen from '~/components/ui/screen';
|
|
7
|
+
import Squircle from '~/components/ui/squircle';
|
|
8
|
+
import Text from '~/components/ui/text';
|
|
9
|
+
import { NOTES } from '~/lib/constants';
|
|
10
|
+
|
|
11
|
+
const BACKGROUND_IMAGE =
|
|
12
|
+
'https://github.com/user-attachments/assets/ce07d991-098a-4e14-a759-ecbb0c159b6b';
|
|
13
|
+
|
|
14
|
+
export default function HomeScreen() {
|
|
15
|
+
return (
|
|
16
|
+
<Screen>
|
|
17
|
+
<ImageBackground
|
|
18
|
+
source={{ uri: BACKGROUND_IMAGE }}
|
|
19
|
+
style={StyleSheet.absoluteFill}
|
|
20
|
+
resizeMode="cover"
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
<View className="flex-row items-center justify-between px-6 pb-5 pt-2">
|
|
24
|
+
<View>
|
|
25
|
+
<Text variant="note">Cozy Notes</Text>
|
|
26
|
+
</View>
|
|
27
|
+
<Link href="/settings" asChild>
|
|
28
|
+
<Pressable>
|
|
29
|
+
<Squircle
|
|
30
|
+
cornerSmoothing={1}
|
|
31
|
+
className='size-11 items-center justify-center rounded-md bg-card'
|
|
32
|
+
|
|
33
|
+
>
|
|
34
|
+
<Ionicons name="settings-outline" size={22} color="black" />
|
|
35
|
+
</Squircle>
|
|
36
|
+
</Pressable>
|
|
37
|
+
</Link>
|
|
38
|
+
</View>
|
|
39
|
+
|
|
40
|
+
<FlatList
|
|
41
|
+
data={NOTES}
|
|
42
|
+
keyExtractor={(item) => item.id}
|
|
43
|
+
renderItem={({ item, index }) => <NoteCard note={item} index={index} />}
|
|
44
|
+
contentContainerClassName="px-6 pt-4 pb-60"
|
|
45
|
+
showsVerticalScrollIndicator={false}
|
|
46
|
+
/>
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
<Link href="/note/new" asChild className='absolute bottom-10 right-10 '>
|
|
50
|
+
<Pressable>
|
|
51
|
+
<Squircle
|
|
52
|
+
cornerSmoothing={1}
|
|
53
|
+
className='size-14 items-center justify-center rounded-2xl bg-primary'
|
|
54
|
+
>
|
|
55
|
+
<Ionicons name="add" size={28} color="#fff" />
|
|
56
|
+
</Squircle>
|
|
57
|
+
</Pressable>
|
|
58
|
+
</Link>
|
|
59
|
+
</Screen>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import { useLocalSearchParams } from 'expo-router';
|
|
3
|
+
|
|
4
|
+
import Screen from '~/components/ui/screen';
|
|
5
|
+
import Text from '~/components/ui/text';
|
|
6
|
+
import { getNoteById } from '~/lib/constants';
|
|
7
|
+
|
|
8
|
+
export default function NoteDetailScreen() {
|
|
9
|
+
const { id } = useLocalSearchParams<{ id: string }>();
|
|
10
|
+
const note = getNoteById(id);
|
|
11
|
+
|
|
12
|
+
// TODO: Build the note detail screen
|
|
13
|
+
// - Add BackButton component at top
|
|
14
|
+
// - Add edit button (Link to /note/edit with id param)
|
|
15
|
+
// - Display note title and content in a Squircle card
|
|
16
|
+
// - Use ScrollView for long content
|
|
17
|
+
|
|
18
|
+
if (!note) {
|
|
19
|
+
return (
|
|
20
|
+
<Screen>
|
|
21
|
+
<View className="flex-1 items-center justify-center">
|
|
22
|
+
<Text>Note not found</Text>
|
|
23
|
+
</View>
|
|
24
|
+
</Screen>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Screen>
|
|
30
|
+
<View className="flex-1 px-5 pt-2">
|
|
31
|
+
<Text variant="title">{note.title}</Text>
|
|
32
|
+
<Text className="mt-4 text-muted-foreground">
|
|
33
|
+
Build this screen to show note details
|
|
34
|
+
</Text>
|
|
35
|
+
</View>
|
|
36
|
+
</Screen>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import { useLocalSearchParams } from 'expo-router';
|
|
3
|
+
|
|
4
|
+
import Screen from '~/components/ui/screen';
|
|
5
|
+
import Text from '~/components/ui/text';
|
|
6
|
+
import { getNoteById } from '~/lib/constants';
|
|
7
|
+
|
|
8
|
+
export default function EditNoteScreen() {
|
|
9
|
+
const { id } = useLocalSearchParams<{ id: string }>();
|
|
10
|
+
const note = getNoteById(id);
|
|
11
|
+
|
|
12
|
+
// TODO: Build the edit note screen
|
|
13
|
+
// - Add BackButton with close icon at top left
|
|
14
|
+
// - Add "Edit Note" title in header center
|
|
15
|
+
// - Add "Save" button at top right
|
|
16
|
+
// - Pre-fill TextInputs with note.title and note.content
|
|
17
|
+
// - Handle save with console.log and router.back()
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Screen>
|
|
21
|
+
<View className="flex-1 px-5 pt-2">
|
|
22
|
+
<Text variant="title">Edit Note</Text>
|
|
23
|
+
<Text className="mt-4 text-muted-foreground">
|
|
24
|
+
Build this screen to edit: {note?.title ?? 'Unknown'}
|
|
25
|
+
</Text>
|
|
26
|
+
</View>
|
|
27
|
+
</Screen>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import Screen from '~/components/ui/screen';
|
|
4
|
+
import Text from '~/components/ui/text';
|
|
5
|
+
|
|
6
|
+
export default function NewNoteScreen() {
|
|
7
|
+
// TODO: Build the new note screen
|
|
8
|
+
// - Add BackButton with close icon at top left
|
|
9
|
+
// - Add "New Note" title in header center
|
|
10
|
+
// - Add "Create" button at top right
|
|
11
|
+
// - Add TextInput for title
|
|
12
|
+
// - Add TextInput for content (multiline)
|
|
13
|
+
// - Handle create with console.log and router.back()
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Screen>
|
|
17
|
+
<View className="flex-1 px-5 pt-2">
|
|
18
|
+
<Text variant="title">New Note</Text>
|
|
19
|
+
<Text className="mt-4 text-muted-foreground">
|
|
20
|
+
Build this screen with title and content inputs
|
|
21
|
+
</Text>
|
|
22
|
+
</View>
|
|
23
|
+
</Screen>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import Screen from '~/components/ui/screen';
|
|
4
|
+
import Text from '~/components/ui/text';
|
|
5
|
+
|
|
6
|
+
export default function SettingsScreen() {
|
|
7
|
+
// TODO: Build the settings screen
|
|
8
|
+
// - Add BackButton at top left
|
|
9
|
+
// - Add "Settings" title next to back button
|
|
10
|
+
// - Add app info card with icon and name
|
|
11
|
+
// - Add "Learn More About CozyNote" button linking to /about
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<Screen>
|
|
15
|
+
<View className="flex-1 px-5 pt-2">
|
|
16
|
+
<Text variant="title">Settings</Text>
|
|
17
|
+
<Text className="mt-4 text-muted-foreground">
|
|
18
|
+
Build this screen with app info and about link
|
|
19
|
+
</Text>
|
|
20
|
+
</View>
|
|
21
|
+
</Screen>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
2
|
+
import { Link } from 'expo-router';
|
|
3
|
+
import { Pressable, View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import Squircle from '~/components/ui/squircle';
|
|
6
|
+
import Text from '~/components/ui/text';
|
|
7
|
+
import { Note } from '~/lib/constants';
|
|
8
|
+
|
|
9
|
+
// Rotation patterns for variety
|
|
10
|
+
const getRotation = (index: number) => {
|
|
11
|
+
const rotations = [-4, 3, -2, 5, -3, 2, -5, 4];
|
|
12
|
+
return rotations[index % rotations.length];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Horizontal offset for staggered look (relative to center)
|
|
16
|
+
const getOffset = (index: number) => {
|
|
17
|
+
const offsets = [-50, 60, -40, 70, -55, 50, -35, 65];
|
|
18
|
+
return offsets[index % offsets.length];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const NoteCard = ({ note, index }: { note: Note; index: number }) => {
|
|
22
|
+
const rotation = getRotation(index);
|
|
23
|
+
const offsetX = getOffset(index);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Link href={{ pathname: '/note/[id]', params: { id: note.id } }} asChild>
|
|
27
|
+
<Pressable
|
|
28
|
+
style={{
|
|
29
|
+
marginBottom: -60,
|
|
30
|
+
alignSelf: 'center',
|
|
31
|
+
marginLeft: offsetX,
|
|
32
|
+
transform: [{ rotate: `${rotation}deg` }],
|
|
33
|
+
zIndex: index,
|
|
34
|
+
}}>
|
|
35
|
+
<Squircle
|
|
36
|
+
cornerSmoothing={1}
|
|
37
|
+
className="bg-card"
|
|
38
|
+
style={{
|
|
39
|
+
width: 240,
|
|
40
|
+
height: 324,
|
|
41
|
+
borderRadius: 24,
|
|
42
|
+
padding: 20,
|
|
43
|
+
}}>
|
|
44
|
+
{/* Menu dots */}
|
|
45
|
+
<View style={{ position: 'absolute', top: 16, right: 16 }}>
|
|
46
|
+
<Ionicons name="ellipsis-horizontal" size={18} color="var(--color-muted-foreground)" />
|
|
47
|
+
</View>
|
|
48
|
+
|
|
49
|
+
{/* Title */}
|
|
50
|
+
<Text variant="subtitle" className="mb-2 mr-10" numberOfLines={2}>
|
|
51
|
+
{note.title}
|
|
52
|
+
</Text>
|
|
53
|
+
|
|
54
|
+
{/* Content */}
|
|
55
|
+
<Text variant="note" className="opacity-90" numberOfLines={10}>
|
|
56
|
+
{note.content}
|
|
57
|
+
</Text>
|
|
58
|
+
</Squircle>
|
|
59
|
+
</Pressable>
|
|
60
|
+
</Link>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default NoteCard;
|
|
65
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Ionicons } from '@expo/vector-icons';
|
|
2
|
+
import { router } from 'expo-router';
|
|
3
|
+
import { Pressable } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import Squircle from './squircle';
|
|
6
|
+
|
|
7
|
+
interface BackButtonProps {
|
|
8
|
+
icon?: 'chevron-back' | 'close';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const BackButton = ({ icon = 'chevron-back' }: BackButtonProps) => {
|
|
12
|
+
return (
|
|
13
|
+
<Pressable onPress={() => router.back()}>
|
|
14
|
+
<Squircle
|
|
15
|
+
cornerSmoothing={1}
|
|
16
|
+
className="size-12 items-center justify-center bg-card rounded-[14px]">
|
|
17
|
+
<Ionicons name={icon} size={26} color="var(--color-foreground)" />
|
|
18
|
+
</Squircle>
|
|
19
|
+
</Pressable>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default BackButton;
|
|
24
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { withUniwind } from 'uniwind';
|
|
2
|
+
import { SafeAreaView as RNSafeAreaView } from 'react-native-safe-area-context';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
const SafeAreaView = withUniwind(RNSafeAreaView);
|
|
6
|
+
|
|
7
|
+
interface ScreenProps {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const Screen = ({
|
|
13
|
+
children,
|
|
14
|
+
className = 'flex-1 bg-background',
|
|
15
|
+
}: ScreenProps) => {
|
|
16
|
+
return <SafeAreaView className={className}>{children}</SafeAreaView>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default Screen;
|
|
20
|
+
|