newcandies 0.1.24 ā 0.1.26
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 +16 -0
- package/templates/app-briefs/expo-router/cozynotes/src/app/index.tsx +16 -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 +125 -0
- package/templates/app-briefs/expo-router/cozynotes/src/types/types.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 +38 -0
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,16 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import Screen from '~/components/ui/screen';
|
|
3
|
+
import Text from '~/components/ui/text';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export default function HomeScreen() {
|
|
8
|
+
return (
|
|
9
|
+
<Screen>
|
|
10
|
+
<View>
|
|
11
|
+
<Text>Home</Text>
|
|
12
|
+
</View>
|
|
13
|
+
</Screen>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
@@ -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
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Text as RNText, TextProps } from 'react-native';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
type TypographyVariant =
|
|
5
|
+
| 'display'
|
|
6
|
+
| 'title'
|
|
7
|
+
| 'subtitle'
|
|
8
|
+
| 'body'
|
|
9
|
+
| 'body-secondary'
|
|
10
|
+
| 'caption'
|
|
11
|
+
| 'caption-secondary'
|
|
12
|
+
| 'button'
|
|
13
|
+
| 'note';
|
|
14
|
+
|
|
15
|
+
interface TextComponentProps extends TextProps {
|
|
16
|
+
className?: string;
|
|
17
|
+
variant?: TypographyVariant;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const variantStyles: Record<TypographyVariant, string> = {
|
|
21
|
+
display: 'text-[34px] font-bold text-foreground',
|
|
22
|
+
title: 'text-[28px] font-bold text-foreground',
|
|
23
|
+
subtitle: 'text-xl font-semibold text-foreground',
|
|
24
|
+
body: 'text-base text-foreground',
|
|
25
|
+
'body-secondary': 'text-base text-muted-foreground',
|
|
26
|
+
caption: 'text-sm text-foreground',
|
|
27
|
+
'caption-secondary': 'text-sm text-muted-foreground',
|
|
28
|
+
button: 'text-base font-semibold text-primary-foreground',
|
|
29
|
+
note: 'font-caveat text-2xl text-foreground',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const Text = ({
|
|
33
|
+
variant = 'body',
|
|
34
|
+
children,
|
|
35
|
+
className,
|
|
36
|
+
...props
|
|
37
|
+
}: TextComponentProps) => {
|
|
38
|
+
const textStyle = twMerge(variantStyles[variant], className);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<RNText className={textStyle} {...props}>
|
|
42
|
+
{children}
|
|
43
|
+
</RNText>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default Text;
|
|
48
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export const NOTES: Note[] = [
|
|
2
|
+
{
|
|
3
|
+
id: '1',
|
|
4
|
+
title: 'Welcome to CozyNote',
|
|
5
|
+
content:
|
|
6
|
+
'This is your first note! CozyNote is a simple and beautiful note-taking app. Start capturing your thoughts, ideas, and memories.',
|
|
7
|
+
createdAt: '2025-02-23T08:00:00Z',
|
|
8
|
+
updatedAt: '2025-02-23T08:00:00Z',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: '2',
|
|
12
|
+
title: 'Meeting Notes',
|
|
13
|
+
content:
|
|
14
|
+
'Discussed Q1 goals and project timelines. Action items: Review budget proposal, Schedule follow-up with design team, Prepare presentation for Friday.',
|
|
15
|
+
createdAt: '2025-02-22T14:30:00Z',
|
|
16
|
+
updatedAt: '2025-02-22T15:45:00Z',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: '3',
|
|
20
|
+
title: 'Shopping List',
|
|
21
|
+
content:
|
|
22
|
+
'- Organic milk\n- Fresh bread\n- Avocados\n- Coffee beans\n- Dark chocolate\n- Olive oil\n- Pasta\n- Tomatoes',
|
|
23
|
+
createdAt: '2025-02-21T09:15:00Z',
|
|
24
|
+
updatedAt: '2025-02-21T09:15:00Z',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: '4',
|
|
28
|
+
title: 'Book Recommendations',
|
|
29
|
+
content:
|
|
30
|
+
'1. Atomic Habits by James Clear\n2. Deep Work by Cal Newport\n3. The Psychology of Money\n4. Thinking, Fast and Slow\n5. The Almanack of Naval Ravikant',
|
|
31
|
+
createdAt: '2025-02-20T19:00:00Z',
|
|
32
|
+
updatedAt: '2025-02-20T19:00:00Z',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: '5',
|
|
36
|
+
title: 'Workout Routine',
|
|
37
|
+
content:
|
|
38
|
+
'Monday: Upper body\nTuesday: Cardio\nWednesday: Lower body\nThursday: Rest\nFriday: Full body\nSaturday: Yoga\nSunday: Rest',
|
|
39
|
+
createdAt: '2025-02-19T07:00:00Z',
|
|
40
|
+
updatedAt: '2025-02-19T07:00:00Z',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: '6',
|
|
44
|
+
title: 'Recipe: Morning Smoothie',
|
|
45
|
+
content:
|
|
46
|
+
'Ingredients:\n- 1 banana\n- 1 cup spinach\n- 1/2 cup frozen berries\n- 1 tbsp almond butter\n- 1 cup oat milk\n\nBlend until smooth. Enjoy!',
|
|
47
|
+
createdAt: '2025-02-18T06:30:00Z',
|
|
48
|
+
updatedAt: '2025-02-18T06:30:00Z',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: '7',
|
|
52
|
+
title: 'Project Ideas',
|
|
53
|
+
content:
|
|
54
|
+
'- Personal portfolio website redesign\n- Mobile app for habit tracking\n- Open source contribution\n- Learn Rust programming\n- Build a CLI tool',
|
|
55
|
+
createdAt: '2025-02-17T21:00:00Z',
|
|
56
|
+
updatedAt: '2025-02-17T21:00:00Z',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: '8',
|
|
60
|
+
title: 'Travel Bucket List',
|
|
61
|
+
content:
|
|
62
|
+
'šÆšµ Japan - Cherry blossom season\nš®šø Iceland - Northern lights\nš³šæ New Zealand - Hobbiton\nš®š¹ Italy - Amalfi Coast\nš¬š· Greece - Santorini',
|
|
63
|
+
createdAt: '2025-02-16T16:00:00Z',
|
|
64
|
+
updatedAt: '2025-02-16T16:00:00Z',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: '9',
|
|
68
|
+
title: 'Daily Affirmations',
|
|
69
|
+
content:
|
|
70
|
+
'I am capable of achieving my goals.\nI embrace challenges as opportunities.\nI am grateful for today.\nI choose positivity and growth.\nI am worthy of success and happiness.',
|
|
71
|
+
createdAt: '2025-02-15T05:00:00Z',
|
|
72
|
+
updatedAt: '2025-02-15T05:00:00Z',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: '10',
|
|
76
|
+
title: 'App Features to Add',
|
|
77
|
+
content:
|
|
78
|
+
'- Dark mode toggle\n- Note categories/tags\n- Search functionality\n- Cloud sync\n- Share notes\n- Rich text formatting\n- Voice notes',
|
|
79
|
+
createdAt: '2025-02-14T11:30:00Z',
|
|
80
|
+
updatedAt: '2025-02-14T11:30:00Z',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: '11',
|
|
84
|
+
title: 'Gratitude Journal',
|
|
85
|
+
content:
|
|
86
|
+
'Today I am grateful for:\n1. A warm cup of coffee\n2. Supportive friends and family\n3. Good health\n4. The opportunity to learn new things\n5. A cozy home',
|
|
87
|
+
createdAt: '2025-02-13T22:00:00Z',
|
|
88
|
+
updatedAt: '2025-02-13T22:00:00Z',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: '12',
|
|
92
|
+
title: 'Podcast Episodes',
|
|
93
|
+
content:
|
|
94
|
+
'Must listen:\n- Huberman Lab: Sleep optimization\n- Lex Fridman: AI discussion\n- Tim Ferriss: Productivity hacks',
|
|
95
|
+
createdAt: '2025-02-12T13:00:00Z',
|
|
96
|
+
updatedAt: '2025-02-12T13:00:00Z',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: '13',
|
|
100
|
+
title: 'Code Snippets',
|
|
101
|
+
content:
|
|
102
|
+
'Useful React patterns:\n- Custom hooks for data fetching\n- Context for global state\n- Memo for performance\n- Suspense for loading states',
|
|
103
|
+
createdAt: '2025-02-11T10:00:00Z',
|
|
104
|
+
updatedAt: '2025-02-11T10:00:00Z',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: '14',
|
|
108
|
+
title: 'Weekend Plans',
|
|
109
|
+
content:
|
|
110
|
+
'Saturday:\n- Morning run at 7am\n- Brunch with Sarah\n- Afternoon coding session\n\nSunday:\n- Sleep in\n- Farmers market\n- Movie night',
|
|
111
|
+
createdAt: '2025-02-10T18:00:00Z',
|
|
112
|
+
updatedAt: '2025-02-10T18:00:00Z',
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
export const getNoteById = (id: string): Note | undefined => {
|
|
118
|
+
return NOTES.find((note) => note.id === id);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
export const BACKGROUND_IMAGE =
|
|
125
|
+
'https://github.com/user-attachments/assets/ce07d991-098a-4e14-a759-ecbb0c159b6b';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "expo/tsconfig.base",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"strict": true,
|
|
5
|
+
"paths": {
|
|
6
|
+
"~/*": ["./src/*"]
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"**/*.ts",
|
|
11
|
+
"**/*.tsx",
|
|
12
|
+
".expo/types/**/*.ts",
|
|
13
|
+
"expo-env.d.ts",
|
|
14
|
+
"./uniwind-types.d.ts"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
|