feat: 로그인 화면 및 공통 속성 생성
This commit is contained in:
27
App.tsx
27
App.tsx
@@ -1,20 +1,17 @@
|
|||||||
import { StatusBar } from 'expo-status-bar';
|
import { NavigationContainer } from "@react-navigation/native";
|
||||||
import { StyleSheet, Text, View } from 'react-native';
|
import React from "react";
|
||||||
|
import { enableScreens } from "react-native-screens";
|
||||||
|
import AuthGate from "./src/navigation/AuthGate";
|
||||||
|
import { AuthProvider } from "./src/store/auth";
|
||||||
|
|
||||||
|
enableScreens();
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<AuthProvider>
|
||||||
<Text>Open up App.tsx to start working on your app!</Text>
|
<NavigationContainer>
|
||||||
<StatusBar style="auto" />
|
<AuthGate />
|
||||||
</View>
|
</NavigationContainer>
|
||||||
|
</AuthProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
backgroundColor: '#fff',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
312
package-lock.json
generated
312
package-lock.json
generated
@@ -8,10 +8,14 @@
|
|||||||
"name": "audiobook-app",
|
"name": "audiobook-app",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-navigation/native": "^7.1.26",
|
||||||
|
"@react-navigation/native-stack": "^7.9.0",
|
||||||
"expo": "~54.0.30",
|
"expo": "~54.0.30",
|
||||||
"expo-status-bar": "~3.0.9",
|
"expo-status-bar": "~3.0.9",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-native": "0.81.5"
|
"react-native": "0.81.5",
|
||||||
|
"react-native-safe-area-context": "~5.6.0",
|
||||||
|
"react-native-screens": "~4.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.1.0",
|
"@types/react": "~19.1.0",
|
||||||
@@ -2972,6 +2976,123 @@
|
|||||||
"integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==",
|
"integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-navigation/core": {
|
||||||
|
"version": "7.13.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.13.7.tgz",
|
||||||
|
"integrity": "sha512-k2ABo3250vq1ovOh/iVwXS6Hwr5PVRGXoPh/ewVFOOuEKTvOx9i//OBzt8EF+HokBxS2HBRlR2b+aCOmscRqBw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-navigation/routers": "^7.5.3",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"nanoid": "^3.3.11",
|
||||||
|
"query-string": "^7.1.3",
|
||||||
|
"react-is": "^19.1.0",
|
||||||
|
"use-latest-callback": "^0.2.4",
|
||||||
|
"use-sync-external-store": "^1.5.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 18.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/core/node_modules/escape-string-regexp": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/core/node_modules/react-is": {
|
||||||
|
"version": "19.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz",
|
||||||
|
"integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/elements": {
|
||||||
|
"version": "2.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.3.tgz",
|
||||||
|
"integrity": "sha512-3+eyvWiVPIEf6tN9UdduhOEHcTuNe3R5WovgiVkfH9+jApHMTZDc2loePTpY/i2HDJhObhhChpJzO6BVjrpdYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color": "^4.2.3",
|
||||||
|
"use-latest-callback": "^0.2.4",
|
||||||
|
"use-sync-external-store": "^1.5.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@react-native-masked-view/masked-view": ">= 0.2.0",
|
||||||
|
"@react-navigation/native": "^7.1.26",
|
||||||
|
"react": ">= 18.2.0",
|
||||||
|
"react-native": "*",
|
||||||
|
"react-native-safe-area-context": ">= 4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@react-native-masked-view/masked-view": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/native": {
|
||||||
|
"version": "7.1.26",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.26.tgz",
|
||||||
|
"integrity": "sha512-RhKmeD0E2ejzKS6z8elAfdfwShpcdkYY8zJzvHYLq+wv183BBcElTeyMLcIX6wIn7QutXeI92Yi21t7aUWfqNQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-navigation/core": "^7.13.7",
|
||||||
|
"escape-string-regexp": "^4.0.0",
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"nanoid": "^3.3.11",
|
||||||
|
"use-latest-callback": "^0.2.4"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 18.2.0",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/native-stack": {
|
||||||
|
"version": "7.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-navigation/native-stack/-/native-stack-7.9.0.tgz",
|
||||||
|
"integrity": "sha512-C/mNPhI0Pnerl7C2cB+6fAkdgSmfKECMERrbyfjx3P6JmEuTC54o+GV1c62FUmlRaRUassVHbtw4EeaY2uLh0g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@react-navigation/elements": "^2.9.3",
|
||||||
|
"color": "^4.2.3",
|
||||||
|
"sf-symbols-typescript": "^2.1.0",
|
||||||
|
"warn-once": "^0.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@react-navigation/native": "^7.1.26",
|
||||||
|
"react": ">= 18.2.0",
|
||||||
|
"react-native": "*",
|
||||||
|
"react-native-safe-area-context": ">= 4.0.0",
|
||||||
|
"react-native-screens": ">= 4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/native/node_modules/escape-string-regexp": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@react-navigation/routers": {
|
||||||
|
"version": "7.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.5.3.tgz",
|
||||||
|
"integrity": "sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sinclair/typebox": {
|
"node_modules/@sinclair/typebox": {
|
||||||
"version": "0.27.8",
|
"version": "0.27.8",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
|
||||||
@@ -3916,6 +4037,19 @@
|
|||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/color": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1",
|
||||||
|
"color-string": "^1.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
@@ -3931,6 +4065,34 @@
|
|||||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/color-string": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "^1.0.0",
|
||||||
|
"simple-swizzle": "^0.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color/node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color/node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||||
@@ -4096,6 +4258,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/decode-uri-component": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/deep-extend": {
|
"node_modules/deep-extend": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||||
@@ -4301,6 +4472,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/expo/-/expo-54.0.30.tgz",
|
"resolved": "https://registry.npmjs.org/expo/-/expo-54.0.30.tgz",
|
||||||
"integrity": "sha512-6q+aFfKL0SpT8prfdpR3V8HcN51ov0mCGuwQTzyuk6eeO9rg7a7LWbgPv9rEVXGZEuyULstL8LGNwHqusand7Q==",
|
"integrity": "sha512-6q+aFfKL0SpT8prfdpR3V8HcN51ov0mCGuwQTzyuk6eeO9rg7a7LWbgPv9rEVXGZEuyULstL8LGNwHqusand7Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.0",
|
"@babel/runtime": "^7.20.0",
|
||||||
"@expo/cli": "54.0.20",
|
"@expo/cli": "54.0.20",
|
||||||
@@ -4885,6 +5057,12 @@
|
|||||||
"integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
|
"integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-deep-equal": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-json-stable-stringify": {
|
"node_modules/fast-json-stable-stringify": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
@@ -4912,6 +5090,15 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/filter-obj": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||||
@@ -5284,6 +5471,12 @@
|
|||||||
"loose-envify": "^1.0.0"
|
"loose-envify": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-arrayish": {
|
||||||
|
"version": "0.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
|
||||||
|
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-core-module": {
|
"node_modules/is-core-module": {
|
||||||
"version": "2.16.1",
|
"version": "2.16.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||||
@@ -7222,6 +7415,24 @@
|
|||||||
"qrcode-terminal": "bin/qrcode-terminal.js"
|
"qrcode-terminal": "bin/qrcode-terminal.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/query-string": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"decode-uri-component": "^0.2.2",
|
||||||
|
"filter-obj": "^1.1.0",
|
||||||
|
"split-on-first": "^1.0.0",
|
||||||
|
"strict-uri-encode": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/queue": {
|
"node_modules/queue": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
||||||
@@ -7274,6 +7485,18 @@
|
|||||||
"ws": "^7"
|
"ws": "^7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-freeze": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=17.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "18.3.1",
|
"version": "18.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||||
@@ -7347,6 +7570,33 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-safe-area-context": {
|
||||||
|
"version": "5.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz",
|
||||||
|
"integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-native-screens": {
|
||||||
|
"version": "4.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.16.0.tgz",
|
||||||
|
"integrity": "sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"react-freeze": "^1.0.0",
|
||||||
|
"react-native-is-edge-to-edge": "^1.2.1",
|
||||||
|
"warn-once": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native/node_modules/@react-native/virtualized-lists": {
|
"node_modules/react-native/node_modules/@react-native/virtualized-lists": {
|
||||||
"version": "0.81.5",
|
"version": "0.81.5",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz",
|
||||||
@@ -7820,6 +8070,15 @@
|
|||||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/sf-symbols-typescript": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sf-symbols-typescript/-/sf-symbols-typescript-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -7870,6 +8129,15 @@
|
|||||||
"plist": "^3.0.5"
|
"plist": "^3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-swizzle": {
|
||||||
|
"version": "0.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
|
||||||
|
"integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-arrayish": "^0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sisteransi": {
|
"node_modules/sisteransi": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||||
@@ -7931,6 +8199,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/split-on-first": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sprintf-js": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
@@ -7994,6 +8271,15 @@
|
|||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strict-uri-encode": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
@@ -8499,6 +8785,24 @@
|
|||||||
"browserslist": ">= 4.21.0"
|
"browserslist": ">= 4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-latest-callback": {
|
||||||
|
"version": "0.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.6.tgz",
|
||||||
|
"integrity": "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/use-sync-external-store": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/utils-merge": {
|
"node_modules/utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
@@ -8550,6 +8854,12 @@
|
|||||||
"makeerror": "1.0.12"
|
"makeerror": "1.0.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/warn-once": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/wcwidth": {
|
"node_modules/wcwidth": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||||
|
|||||||
@@ -9,10 +9,14 @@
|
|||||||
"web": "expo start --web"
|
"web": "expo start --web"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-navigation/native": "^7.1.26",
|
||||||
|
"@react-navigation/native-stack": "^7.9.0",
|
||||||
"expo": "~54.0.30",
|
"expo": "~54.0.30",
|
||||||
"expo-status-bar": "~3.0.9",
|
"expo-status-bar": "~3.0.9",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-native": "0.81.5"
|
"react-native": "0.81.5",
|
||||||
|
"react-native-safe-area-context": "~5.6.0",
|
||||||
|
"react-native-screens": "~4.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.1.0",
|
"@types/react": "~19.1.0",
|
||||||
|
|||||||
27
src/components/ui/AppText.tsx
Normal file
27
src/components/ui/AppText.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Text, type TextProps, type TextStyle } from "react-native";
|
||||||
|
import { Theme } from "../../theme/theme";
|
||||||
|
|
||||||
|
type Variant = "logo" | "title" | "body" | "muted" | "error";
|
||||||
|
|
||||||
|
type Props = TextProps & {
|
||||||
|
variant?: Variant;
|
||||||
|
style?: TextStyle | TextStyle[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function AppText({ variant = "body", style, ...props }: Props) {
|
||||||
|
const base: TextStyle = {
|
||||||
|
color: Theme.Colors.text,
|
||||||
|
fontSize: Theme.FontSize.md,
|
||||||
|
};
|
||||||
|
|
||||||
|
const variants: Record<Variant, TextStyle> = {
|
||||||
|
logo: { fontSize: Theme.FontSize.xxl, fontWeight: Theme.FontWeight.bold },
|
||||||
|
title: { fontSize: Theme.FontSize.xl, fontWeight: Theme.FontWeight.bold },
|
||||||
|
body: { fontSize: Theme.FontSize.md },
|
||||||
|
muted: { color: Theme.Colors.mutedText, fontSize: Theme.FontSize.sm },
|
||||||
|
error: { color: Theme.Colors.danger, fontSize: Theme.FontSize.sm },
|
||||||
|
};
|
||||||
|
|
||||||
|
return <Text {...props} style={[base, variants[variant], style]} />;
|
||||||
|
}
|
||||||
73
src/components/ui/Button.tsx
Normal file
73
src/components/ui/Button.tsx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Pressable, type PressableProps, StyleSheet, View } from "react-native";
|
||||||
|
import { Theme } from "../../theme/theme";
|
||||||
|
import AppText from "./AppText";
|
||||||
|
|
||||||
|
type Props = PressableProps & {
|
||||||
|
title: string;
|
||||||
|
variant?: "primary" | "secondary";
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Button({
|
||||||
|
title,
|
||||||
|
variant = "primary",
|
||||||
|
style,
|
||||||
|
...props
|
||||||
|
}: Props) {
|
||||||
|
const isPrimary = variant === "primary";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
{...props}
|
||||||
|
style={({ pressed }) => [
|
||||||
|
styles.base,
|
||||||
|
isPrimary ? styles.primary : styles.secondary,
|
||||||
|
pressed &&
|
||||||
|
(isPrimary ? styles.primaryPressed : styles.secondaryPressed),
|
||||||
|
typeof style === "function" ? style({ pressed }) : style,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<AppText
|
||||||
|
style={{
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: Theme.FontWeight.bold,
|
||||||
|
color: isPrimary ? Theme.Colors.text : Theme.Colors.text,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</AppText>
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
base: {
|
||||||
|
height: 48,
|
||||||
|
paddingVertical: 0,
|
||||||
|
paddingHorizontal: Theme.Spacing.lg,
|
||||||
|
borderRadius: Theme.Radius.md,
|
||||||
|
alignItems: "center", // 가로 가운데
|
||||||
|
justifyContent: "center", // 세로 가운데
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
textAlign: "center",
|
||||||
|
fontWeight: Theme.FontWeight.bold,
|
||||||
|
lineHeight: 20,
|
||||||
|
},
|
||||||
|
primary: {
|
||||||
|
backgroundColor: Theme.Colors.primary,
|
||||||
|
},
|
||||||
|
primaryPressed: {
|
||||||
|
backgroundColor: Theme.Colors.primaryPressed,
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
backgroundColor: Theme.Colors.surface,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: Theme.Colors.border,
|
||||||
|
},
|
||||||
|
secondaryPressed: {
|
||||||
|
opacity: 0.9,
|
||||||
|
},
|
||||||
|
});
|
||||||
32
src/components/ui/Input.tsx
Normal file
32
src/components/ui/Input.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { StyleSheet, TextInput, type TextInputProps, View } from "react-native";
|
||||||
|
import { Theme } from "../../theme/theme";
|
||||||
|
|
||||||
|
type Props = TextInputProps;
|
||||||
|
|
||||||
|
export default function Input(props: Props) {
|
||||||
|
return (
|
||||||
|
<View style={styles.wrap}>
|
||||||
|
<TextInput
|
||||||
|
{...props}
|
||||||
|
placeholderTextColor={Theme.Colors.placeholder}
|
||||||
|
style={[styles.input, props.style]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
wrap: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: Theme.Colors.border,
|
||||||
|
borderRadius: Theme.Radius.md,
|
||||||
|
backgroundColor: Theme.Colors.inputBg,
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
paddingHorizontal: Theme.Spacing.md,
|
||||||
|
paddingVertical: Theme.Spacing.md,
|
||||||
|
color: Theme.Colors.text,
|
||||||
|
fontSize: Theme.FontSize.md,
|
||||||
|
},
|
||||||
|
});
|
||||||
17
src/navigation/AppStack.tsx
Normal file
17
src/navigation/AppStack.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||||
|
import React from "react";
|
||||||
|
import HomeScreen from "../screens/HomeScreen";
|
||||||
|
|
||||||
|
export type AppStackParamList = {
|
||||||
|
Home: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stack = createNativeStackNavigator<AppStackParamList>();
|
||||||
|
|
||||||
|
export default function AppStack() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||||
|
<Stack.Screen name="Home" component={HomeScreen} />
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
10
src/navigation/AuthGate.tsx
Normal file
10
src/navigation/AuthGate.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import React from "react";
|
||||||
|
import AppStack from "./AppStack";
|
||||||
|
import AuthStack from "./AuthStack";
|
||||||
|
|
||||||
|
export default function AuthGate() {
|
||||||
|
// const { isAuthed } = useAuth();
|
||||||
|
const isAuthed = true;
|
||||||
|
// return <AuthStack />;
|
||||||
|
return isAuthed ? <AppStack /> : <AuthStack />;
|
||||||
|
}
|
||||||
17
src/navigation/AuthStack.tsx
Normal file
17
src/navigation/AuthStack.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { createNativeStackNavigator } from "@react-navigation/native-stack";
|
||||||
|
import React from "react";
|
||||||
|
import LoginScreen from "../screens/LoginScreen";
|
||||||
|
|
||||||
|
export type AuthStackParamList = {
|
||||||
|
Login: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Stack = createNativeStackNavigator<AuthStackParamList>();
|
||||||
|
|
||||||
|
export default function AuthStack() {
|
||||||
|
return (
|
||||||
|
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||||
|
<Stack.Screen name="Login" component={LoginScreen} />
|
||||||
|
</Stack.Navigator>
|
||||||
|
);
|
||||||
|
}
|
||||||
18
src/screens/HomeScreen.tsx
Normal file
18
src/screens/HomeScreen.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { StyleSheet, Text, View } from "react-native";
|
||||||
|
|
||||||
|
export default function HomeScreen() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>feawfewa</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "red",
|
||||||
|
alignContent: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
});
|
||||||
74
src/screens/LoginScreen.tsx
Normal file
74
src/screens/LoginScreen.tsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Pressable, StyleSheet, View } from "react-native";
|
||||||
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
import AppText from "../components/ui/AppText";
|
||||||
|
import Button from "../components/ui/Button";
|
||||||
|
import Input from "../components/ui/Input";
|
||||||
|
import { Theme } from "../theme/theme";
|
||||||
|
|
||||||
|
export default function LoginScreen() {
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={styles.safe}>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<AppText variant="title">Your personal growth podcast</AppText>
|
||||||
|
<AppText variant="muted">Sign in to continue</AppText>
|
||||||
|
|
||||||
|
<View style={{ height: Theme.Spacing.lg }} />
|
||||||
|
|
||||||
|
<Input
|
||||||
|
placeholder="Username"
|
||||||
|
autoCapitalize="none"
|
||||||
|
autoCorrect={false}
|
||||||
|
textContentType="username"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View style={{ height: Theme.Spacing.sm }} />
|
||||||
|
|
||||||
|
<Input
|
||||||
|
placeholder="Password"
|
||||||
|
secureTextEntry
|
||||||
|
autoCapitalize="none"
|
||||||
|
autoCorrect={false}
|
||||||
|
textContentType="password"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View style={{ height: Theme.Spacing.lg }} />
|
||||||
|
|
||||||
|
<Button title="Continue" onPress={() => {}} />
|
||||||
|
|
||||||
|
<View style={{ height: Theme.Spacing.md }} />
|
||||||
|
|
||||||
|
<Pressable
|
||||||
|
onPress={() => {
|
||||||
|
console.log("feawf");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AppText variant="muted" style={styles.signupLine}>
|
||||||
|
Don't have an account?{" "}
|
||||||
|
<AppText style={styles.signupLink}>Sign up</AppText>
|
||||||
|
</AppText>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
safe: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: Theme.Colors.bg,
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: Theme.Spacing.xl,
|
||||||
|
justifyContent: "center",
|
||||||
|
gap: Theme.Spacing.sm,
|
||||||
|
},
|
||||||
|
signupLine: {
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
|
signupLink: {
|
||||||
|
color: Theme.Colors.primary,
|
||||||
|
fontWeight: Theme.FontWeight.bold,
|
||||||
|
},
|
||||||
|
});
|
||||||
31
src/store/auth.tsx
Normal file
31
src/store/auth.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import React, { createContext, useContext, useMemo, useState } from "react";
|
||||||
|
|
||||||
|
export type AuthContextValue = {
|
||||||
|
isAuthed: boolean;
|
||||||
|
login: () => void;
|
||||||
|
logout: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AuthContext = createContext<AuthContextValue | null>(null);
|
||||||
|
|
||||||
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||||
|
const [isAuthed, setIsAuthed] = useState<boolean>(false);
|
||||||
|
console.log("isAuthed: " + isAuthed);
|
||||||
|
|
||||||
|
const value = useMemo<AuthContextValue>(
|
||||||
|
() => ({
|
||||||
|
isAuthed,
|
||||||
|
login: () => setIsAuthed(true),
|
||||||
|
logout: () => setIsAuthed(false),
|
||||||
|
}),
|
||||||
|
[isAuthed]
|
||||||
|
);
|
||||||
|
|
||||||
|
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useAuth(): AuthContextValue {
|
||||||
|
const ctx = useContext(AuthContext);
|
||||||
|
if (!ctx) throw new Error("useAuth must be used within AuthProvider");
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
22
src/theme/colors.ts
Normal file
22
src/theme/colors.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
export const Colors = {
|
||||||
|
// base
|
||||||
|
bg: "#0B1220",
|
||||||
|
surface: "#111827",
|
||||||
|
card: "#0F172A",
|
||||||
|
|
||||||
|
// text
|
||||||
|
text: "#FFFFFF",
|
||||||
|
mutedText: "#9CA3AF",
|
||||||
|
placeholder: "#6B7280",
|
||||||
|
|
||||||
|
// brand
|
||||||
|
primary: "#4F46E5",
|
||||||
|
primaryPressed: "#4338CA",
|
||||||
|
|
||||||
|
// status
|
||||||
|
danger: "#EF4444",
|
||||||
|
|
||||||
|
// lines
|
||||||
|
border: "#22304A",
|
||||||
|
inputBg: "#0B1220",
|
||||||
|
} as const;
|
||||||
6
src/theme/radius.ts
Normal file
6
src/theme/radius.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export const Radius = {
|
||||||
|
sm: 10,
|
||||||
|
md: 12,
|
||||||
|
lg: 16,
|
||||||
|
xl: 20,
|
||||||
|
} as const;
|
||||||
8
src/theme/spacing.ts
Normal file
8
src/theme/spacing.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export const Spacing = {
|
||||||
|
xs: 4,
|
||||||
|
sm: 8,
|
||||||
|
md: 12,
|
||||||
|
lg: 16,
|
||||||
|
xl: 20,
|
||||||
|
"2xl": 24,
|
||||||
|
} as const;
|
||||||
12
src/theme/theme.ts
Normal file
12
src/theme/theme.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Colors } from "./colors";
|
||||||
|
import { Radius } from "./radius";
|
||||||
|
import { Spacing } from "./spacing";
|
||||||
|
import { FontSize, FontWeight } from "./typography";
|
||||||
|
|
||||||
|
export const Theme = {
|
||||||
|
Colors,
|
||||||
|
Spacing,
|
||||||
|
Radius,
|
||||||
|
FontSize,
|
||||||
|
FontWeight,
|
||||||
|
} as const;
|
||||||
14
src/theme/typography.ts
Normal file
14
src/theme/typography.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export const FontSize = {
|
||||||
|
sm: 13,
|
||||||
|
md: 15,
|
||||||
|
lg: 18,
|
||||||
|
xl: 22,
|
||||||
|
xxl: 26,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const FontWeight = {
|
||||||
|
regular: "400",
|
||||||
|
medium: "500",
|
||||||
|
semibold: "600",
|
||||||
|
bold: "700",
|
||||||
|
} as const;
|
||||||
Reference in New Issue
Block a user