Compare commits
	
		
			26 Commits
		
	
	
		
			04833277e1
			...
			fr/testing
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 82a24efd91 | |||
| 5f29773b4a | |||
| 7eb548e138 | |||
| 6c2ebe7d7a | |||
| 1dd7952976 | |||
| 922a11b23b | |||
| 5a2a2db5e2 | |||
| 61449caef1 | |||
| c9b8246218 | |||
| c89dfa6786 | |||
| 8f3e442077 | |||
| 0430710522 | |||
| c1805643c8 | |||
| f1c296c0d3 | |||
| 2041c8998a | |||
| cff010f2b4 | |||
| 986aca3931 | |||
| a57a059c2a | |||
| b7dc6af2e4 | |||
| 4fc58aedd7 | |||
| bf08eefe57 | |||
| 6d6afc6274 | |||
| 82c90c1ceb | |||
| 4fe4808b3c | |||
| b6b9b989c7 | |||
| 13b223ed5f | 
							
								
								
									
										32
									
								
								.gitea/workflows/build.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					name: Build DeguApp backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on: pull_request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - name: Checkout Repository
 | 
				
			||||||
 | 
					        uses: actions/checkout@v2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: Set up Node.js and TypeScript
 | 
				
			||||||
 | 
					        uses: actions/setup-node@v1
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: "20.14.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: npm install
 | 
				
			||||||
 | 
					        working-directory: api/
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          npm install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: npm run build
 | 
				
			||||||
 | 
					        working-directory: api/
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          npm run build --if-present
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: npm run test
 | 
				
			||||||
 | 
					        working-directory: api/
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          npm run test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										28
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -35,7 +35,12 @@ To get started with DeguApp, follow these steps:
 | 
				
			|||||||
2. Install dependencies:
 | 
					2. Install dependencies:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   ```bash
 | 
					   ```bash
 | 
				
			||||||
   cd deguapp
 | 
					   # frontend
 | 
				
			||||||
 | 
					   cd deguapp/frontend
 | 
				
			||||||
 | 
					   npm install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   # backend
 | 
				
			||||||
 | 
					   cd deguapp/api
 | 
				
			||||||
   npm install
 | 
					   npm install
 | 
				
			||||||
   ```
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,11 +48,6 @@ To get started with DeguApp, follow these steps:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
5. Open the app in your browser or Android emulator and start exploring!
 | 
					5. Open the app in your browser or Android emulator and start exploring!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Contributing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Contributions are welcome! If you'd like to contribute to DeguApp, please fork the repository and submit a pull request with your changes.
 | 
					 | 
				
			||||||
Use the upstream of the project, which can be found at https:/git.filiprojek.cz/fr/deguapp. **GitHub repository is just a mirror!**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Local builds
 | 
					## Local builds
 | 
				
			||||||
### Android
 | 
					### Android
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,12 +74,24 @@ bundletool build-apks --bundle=./frontend/android/app/build/outputs/bundle/relea
 | 
				
			|||||||
bundletool install-apks --apks=./deguapp.apks
 | 
					bundletool install-apks --apks=./deguapp.apks
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Resources:
 | 
				
			||||||
### Resources:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
- https://github.com/expo/eas-cli/issues/1300
 | 
					- https://github.com/expo/eas-cli/issues/1300
 | 
				
			||||||
- https://reactnative.dev/docs/signed-apk-android#generating-the-release-aab
 | 
					- https://reactnative.dev/docs/signed-apk-android#generating-the-release-aab
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					cd api/
 | 
				
			||||||
 | 
					npm i
 | 
				
			||||||
 | 
					npm run build
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Contributions are welcome! If you'd like to contribute to DeguApp, please fork the repository and submit a pull request with your changes.
 | 
				
			||||||
 | 
					Use the upstream of the project, which can be found at https:/git.filiprojek.cz/fr/deguapp. **GitHub repository is just a mirror!**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## License
 | 
					## License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This project is licensed under the GNU GPLv3 License - see the [LICENSE](LICENSE) file for details.
 | 
					This project is licensed under the GNU GPLv3 License - see the [LICENSE](LICENSE) file for details.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								api/.gitea/workflows/build.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					name: Build DeguApp backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on: pull_request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - name: Checkout Repository
 | 
				
			||||||
 | 
					        uses: actions/checkout@v2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: Set up Node.js and TypeScript
 | 
				
			||||||
 | 
					        uses: actions/setup-node@v1
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          node-version: "20.14.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: npm install, build and test
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          npm install
 | 
				
			||||||
 | 
					          npm run build --if-present
 | 
				
			||||||
 | 
					          npm run test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								api/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -3,3 +3,4 @@ dist/
 | 
				
			|||||||
package-lock.json
 | 
					package-lock.json
 | 
				
			||||||
.env
 | 
					.env
 | 
				
			||||||
test-report.html
 | 
					test-report.html
 | 
				
			||||||
 | 
					uploads/
 | 
				
			||||||
@@ -36,7 +36,10 @@ app.use(morgan("dev"));
 | 
				
			|||||||
app.use(express.urlencoded({ extended: true }));
 | 
					app.use(express.urlencoded({ extended: true }));
 | 
				
			||||||
app.use(express.json());
 | 
					app.use(express.json());
 | 
				
			||||||
app.use(express.static(path.join(__dirname, "public")));
 | 
					app.use(express.static(path.join(__dirname, "public")));
 | 
				
			||||||
 | 
					app.use('/public/uploads', express.static(path.join(__dirname, '../uploads')));
 | 
				
			||||||
app.use(cookieParser());
 | 
					app.use(cookieParser());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Routes
 | 
					// Routes
 | 
				
			||||||
app.use(routes);
 | 
					app.use(routes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//test
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ new Docs(
 | 
				
			|||||||
export async function add_post(req: Request, res: Response) {
 | 
					export async function add_post(req: Request, res: Response) {
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		const data: IReview = req.body;
 | 
							const data: IReview = req.body;
 | 
				
			||||||
 | 
							data.user_id = res.locals.user._id
 | 
				
			||||||
		const review = new Review(data);
 | 
							const review = new Review(data);
 | 
				
			||||||
		await review.save();
 | 
							await review.save();
 | 
				
			||||||
		res.status(201).json(Log.info(201, "review was added", review));
 | 
							res.status(201).json(Log.info(201, "review was added", review));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,14 @@ const schema = new Schema<IReview | any>(
 | 
				
			|||||||
			type: Boolean,
 | 
								type: Boolean,
 | 
				
			||||||
			required: true,
 | 
								required: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							beer_id: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							user_id: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
 | 
								required: true,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		timestamps: true,
 | 
							timestamps: true,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
{"version":"2.0.0","endpoints":{"user":{"signup":{"name":"user","operation":"signup","route":"/api/v1/auth/signup","method":"POST","description":"user signup api","body":{"username":"testuser","email":"text@example.com","password":"Test1234"},"response":"status object"},"signin":{"name":"user","operation":"signin","route":"/api/v1/auth/signin","method":"POST","description":"user signin api","body":{"email":"text@example.com","password":"Test1234"},"response":"status object"},"logout":{"name":"user","operation":"logout","route":"/api/v1/auth/logout","method":"POST","description":"user logout api","body":{},"response":"status object"},"status":{"name":"user","operation":"status","route":"/api/v1/auth/status","method":"GET","description":"user login status api","response":"status code | user object"}},"beer":{"add":{"name":"beer","operation":"add","route":"/api/v1/beer/add","method":"POST","description":"beer add api","body":{"brand":"Pilsner Urqell","name":"Kozel","degree":11,"packaging":"can","photos":"optional field | max 4 images | formData"},"response":"status object | beer object"},"get":{"name":"beer","operation":"get","route":"/api/v1/beer/get","method":"GET","description":"beer get api","response":"status object | array of beer objects"},"del":{"name":"beer","operation":"del","route":"/api/v1/beer/del","method":"POST","description":"beer del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"},"edit":{"name":"beer","operation":"edit","route":"/api/v1/beer/edit","method":"POST","description":"beer edit api","body":{"_id":"6355b95dc03fad77bc380146","brand":"Pilsner Urqell","name":"Radegast","degree":12,"packaging":"bottle","imgs":[],"photos":"optional field | max 4 images | formData"},"response":"status object |  beer data"}},"docs":{"get_all":{"name":"docs","operation":"get_all","route":"/api/v1","method":"GET","description":"Get docs json","response":"docs json"}}}}
 | 
					{"version":"2.0.0","endpoints":{"user":{"signup":{"name":"user","operation":"signup","route":"/api/v1/auth/signup","method":"POST","description":"user signup api","body":{"username":"testuser","email":"text@example.com","password":"Test1234"},"response":"status object"},"signin":{"name":"user","operation":"signin","route":"/api/v1/auth/signin","method":"POST","description":"user signin api","body":{"email":"text@example.com","password":"Test1234"},"response":"status object"},"logout":{"name":"user","operation":"logout","route":"/api/v1/auth/logout","method":"POST","description":"user logout api","body":{},"response":"status object"},"status":{"name":"user","operation":"status","route":"/api/v1/auth/status","method":"GET","description":"user login status api","response":"status code | user object"}},"beer":{"add":{"name":"beer","operation":"add","route":"/api/v1/beer/add","method":"POST","description":"beer add api","body":{"brand":"Pilsner Urqell","name":"Kozel","degree":11,"packaging":"can","photos":"optional field | max 4 images | formData"},"response":"status object | beer object"},"get":{"name":"beer","operation":"get","route":"/api/v1/beer/get","method":"GET","description":"beer get api","response":"status object | array of beer objects"},"del":{"name":"beer","operation":"del","route":"/api/v1/beer/del","method":"POST","description":"beer del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"},"edit":{"name":"beer","operation":"edit","route":"/api/v1/beer/edit","method":"POST","description":"beer edit api","body":{"_id":"6355b95dc03fad77bc380146","brand":"Pilsner Urqell","name":"Radegast","degree":12,"packaging":"bottle","imgs":[],"photos":"optional field | max 4 images | formData"},"response":"status object |  beer data"}},"docs":{"get_all":{"name":"docs","operation":"get_all","route":"/api/v1","method":"GET","description":"Get docs json","response":"docs json"}},"review":{"add":{"name":"review","operation":"add","route":"/api/v1/review/add","method":"POST","description":"review add api","body":{"beer_id":"6352b303b71cb62222f39895","foam":3,"bitter_sweetness":2,"taste":5,"packaging":3,"sourness":false,"would_again":true},"response":"status object | review object"},"get":{"name":"review","operation":"get","route":"/api/v1/review/get","method":"GET","description":"review get api","response":"status object | array of review objects"},"del":{"name":"review","operation":"del","route":"/api/v1/review/del","method":"POST","description":"review del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"}}}}
 | 
				
			||||||
@@ -5,9 +5,9 @@ export const router = Router();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
router.use("/api/v1", api_v1);
 | 
					router.use("/api/v1", api_v1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//router.get("*", (req: Request, res: Response) => {
 | 
					router.get("*", (req: Request, res: Response) => {
 | 
				
			||||||
//  res.sendFile(path.join(__dirname, "../views/index.html"));
 | 
					  res.sendFile(path.join(__dirname, "../public/index.html"));
 | 
				
			||||||
//});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 404
 | 
					// 404
 | 
				
			||||||
router.use((req: Request, res: Response) => {
 | 
					router.use((req: Request, res: Response) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ export const add = yup.object({
 | 
				
			|||||||
	packaging: yup.number().min(1).max(5).required(),
 | 
						packaging: yup.number().min(1).max(5).required(),
 | 
				
			||||||
	sourness: yup.boolean().required(),
 | 
						sourness: yup.boolean().required(),
 | 
				
			||||||
	would_again: yup.boolean().required(),
 | 
						would_again: yup.boolean().required(),
 | 
				
			||||||
 | 
						user_id: yup.string().notRequired()
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
export interface IReview extends yup.InferType<typeof add>, mongooseAddition {}
 | 
					export interface IReview extends yup.InferType<typeof add>, mongooseAddition {}
 | 
				
			||||||
export const addExam: IReview = {
 | 
					export const addExam: IReview = {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								frontend/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -37,3 +37,4 @@ yarn-error.*
 | 
				
			|||||||
.env
 | 
					.env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.vscode/
 | 
					.vscode/
 | 
				
			||||||
 | 
					*.swp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,43 +1,41 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "expo": {
 | 
						"expo": {
 | 
				
			||||||
    "name": "deguapp",
 | 
							"name": "deguapp",
 | 
				
			||||||
    "slug": "deguapp",
 | 
							"slug": "deguapp",
 | 
				
			||||||
    "scheme": "deguapp",
 | 
							"scheme": "deguapp",
 | 
				
			||||||
    "version": "1.0.0",
 | 
							"version": "1.0.0",
 | 
				
			||||||
    "orientation": "portrait",
 | 
							"orientation": "portrait",
 | 
				
			||||||
    "icon": "./assets/icon.png",
 | 
							"icon": "./assets/icon.png",
 | 
				
			||||||
    "userInterfaceStyle": "light",
 | 
							"userInterfaceStyle": "light",
 | 
				
			||||||
    "splash": {
 | 
							"splash": {
 | 
				
			||||||
      "image": "./assets/splash.png",
 | 
								"image": "./assets/splash.png",
 | 
				
			||||||
      "resizeMode": "contain",
 | 
								"resizeMode": "contain",
 | 
				
			||||||
      "backgroundColor": "#ffffff"
 | 
								"backgroundColor": "#ffffff"
 | 
				
			||||||
    },
 | 
							},
 | 
				
			||||||
    "assetBundlePatterns": [
 | 
							"assetBundlePatterns": ["**/*"],
 | 
				
			||||||
      "**/*"
 | 
							"ios": {
 | 
				
			||||||
    ],
 | 
								"supportsTablet": true
 | 
				
			||||||
    "ios": {
 | 
							},
 | 
				
			||||||
      "supportsTablet": true
 | 
							"android": {
 | 
				
			||||||
    },
 | 
								"adaptiveIcon": {
 | 
				
			||||||
    "android": {
 | 
									"foregroundImage": "./assets/adaptive-icon.png",
 | 
				
			||||||
      "adaptiveIcon": {
 | 
									"backgroundColor": "#ffffff"
 | 
				
			||||||
        "foregroundImage": "./assets/adaptive-icon.png",
 | 
								}
 | 
				
			||||||
        "backgroundColor": "#ffffff"
 | 
							},
 | 
				
			||||||
      }
 | 
							"web": {
 | 
				
			||||||
    },
 | 
								"favicon": "./assets/favicon.png"
 | 
				
			||||||
    "web": {
 | 
							},
 | 
				
			||||||
      "favicon": "./assets/favicon.png"
 | 
							"plugins": [
 | 
				
			||||||
    },
 | 
								"expo-router",
 | 
				
			||||||
    "plugins": [
 | 
								[
 | 
				
			||||||
      "expo-router",
 | 
									"expo-image-picker",
 | 
				
			||||||
      [
 | 
									{
 | 
				
			||||||
        "expo-image-picker",
 | 
										"photosPermission": "The app accesses your photos to let you share them with your friends.",
 | 
				
			||||||
        {
 | 
										"cameraPermission": "The app accesses your camera to let you take photos of your beer and share them with your friends.",
 | 
				
			||||||
          "photosPermission": "The app accesses your photos to let you share them with your friends.",
 | 
										"microphonePermission": "The app accesses your microphone to let you record audio and share it with your friends."
 | 
				
			||||||
          "cameraPermission": "The app accesses your camera to let you take photos of your beer and share them with your friends.",
 | 
									}
 | 
				
			||||||
          "microphonePermission": "The app accesses your microphone to let you record audio and share it with your friends."
 | 
								],
 | 
				
			||||||
        }
 | 
								"expo-secure-store"
 | 
				
			||||||
      ],
 | 
							]
 | 
				
			||||||
      "expo-secure-store"
 | 
						}
 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ export default function TabLayout() {
 | 
				
			|||||||
					}}
 | 
										}}
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
				<Tabs.Screen
 | 
									<Tabs.Screen
 | 
				
			||||||
					name="review"
 | 
										name="review/index"
 | 
				
			||||||
					options={{
 | 
										options={{
 | 
				
			||||||
						title: "Reviews",
 | 
											title: "Reviews",
 | 
				
			||||||
						tabBarIcon: ({ color }) => (
 | 
											tabBarIcon: ({ color }) => (
 | 
				
			||||||
@@ -66,6 +66,10 @@ export default function TabLayout() {
 | 
				
			|||||||
					name="beer/add"
 | 
										name="beer/add"
 | 
				
			||||||
					options={{ href: null, title: "Add beer" }}
 | 
										options={{ href: null, title: "Add beer" }}
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
 | 
									<Tabs.Screen
 | 
				
			||||||
 | 
										name="review/add/[beer_id]"
 | 
				
			||||||
 | 
										options={{ href: null, title: "Add review" }}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
			</Tabs>
 | 
								</Tabs>
 | 
				
			||||||
		</View>
 | 
							</View>
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,8 +5,8 @@ import Text from "@components/Text";
 | 
				
			|||||||
import { colors } from "@components/style";
 | 
					import { colors } from "@components/style";
 | 
				
			||||||
import * as ImagePicker from "expo-image-picker";
 | 
					import * as ImagePicker from "expo-image-picker";
 | 
				
			||||||
import DropDownPicker from "react-native-dropdown-picker";
 | 
					import DropDownPicker from "react-native-dropdown-picker";
 | 
				
			||||||
/* import DropdownTheme from "@components/DropdownTheme"; */
 | 
					 | 
				
			||||||
const DropdownTheme = require("@components/DropdownTheme");
 | 
					const DropdownTheme = require("@components/DropdownTheme");
 | 
				
			||||||
 | 
					import { Platform } from "react-native";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function BeerAdd() {
 | 
					export default function BeerAdd() {
 | 
				
			||||||
	const [b_name, setBName] = useState("");
 | 
						const [b_name, setBName] = useState("");
 | 
				
			||||||
@@ -49,7 +49,7 @@ export default function BeerAdd() {
 | 
				
			|||||||
		console.log(result);
 | 
							console.log(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!result.canceled) {
 | 
							if (!result.canceled) {
 | 
				
			||||||
			setImage(result.assets[0].uri);
 | 
								setImage(result.assets[0]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,7 +68,7 @@ export default function BeerAdd() {
 | 
				
			|||||||
		console.log(result);
 | 
							console.log(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!result.canceled) {
 | 
							if (!result.canceled) {
 | 
				
			||||||
			setImage(result.assets[0].uri);
 | 
								setImage(result.assets[0]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -87,29 +87,60 @@ export default function BeerAdd() {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						function dataURItoBlob(dataURI) {
 | 
				
			||||||
 | 
							// convert base64/URLEncoded data component to raw binary data held in a string
 | 
				
			||||||
 | 
							var byteString;
 | 
				
			||||||
 | 
							if (dataURI.split(",")[0].indexOf("base64") >= 0)
 | 
				
			||||||
 | 
								byteString = atob(dataURI.split(",")[1]);
 | 
				
			||||||
 | 
							else byteString = unescape(dataURI.split(",")[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// separate out the mime component
 | 
				
			||||||
 | 
							var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// write the bytes of the string to a typed array
 | 
				
			||||||
 | 
							var ia = new Uint8Array(byteString.length);
 | 
				
			||||||
 | 
							for (var i = 0; i < byteString.length; i++) {
 | 
				
			||||||
 | 
								ia[i] = byteString.charCodeAt(i);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return new Blob([ia], { type: mimeString });
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async function addBeer() {
 | 
						async function addBeer() {
 | 
				
			||||||
		// TODO: after the request - redirect to /beer/{new_beer_id}?; plus some modal about successful state
 | 
							// TODO: after the request - redirect to /beer/{new_beer_id}?; plus some modal about successful state
 | 
				
			||||||
		const req = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/beer/add`, {
 | 
					 | 
				
			||||||
			method: "POST",
 | 
					 | 
				
			||||||
			credentials: "include",
 | 
					 | 
				
			||||||
			headers: { "Content-Type": "application/json" },
 | 
					 | 
				
			||||||
			body: JSON.stringify({
 | 
					 | 
				
			||||||
				brand: b_brand,
 | 
					 | 
				
			||||||
				name: b_name,
 | 
					 | 
				
			||||||
				degree: b_degree,
 | 
					 | 
				
			||||||
				packaging: b_packaging,
 | 
					 | 
				
			||||||
				photos: null,
 | 
					 | 
				
			||||||
			}),
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		const res = await req.json();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (res.code == 201 && res.data._id) {
 | 
							const data = new FormData();
 | 
				
			||||||
			window.location.href = `/beer/${res.data._id}`;
 | 
							if (Platform.OS == "web") {
 | 
				
			||||||
		} else {
 | 
								// TODO: On phone its imposibble to upload an image
 | 
				
			||||||
 | 
								data.append("photos", dataURItoBlob(image.uri));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							data.append("brand", b_brand);
 | 
				
			||||||
 | 
							data.append("name", b_name);
 | 
				
			||||||
 | 
							data.append("degree", b_degree);
 | 
				
			||||||
 | 
							data.append("packaging", "can");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								const req = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/beer/add`, {
 | 
				
			||||||
 | 
									method: "POST",
 | 
				
			||||||
 | 
									credentials: "include",
 | 
				
			||||||
 | 
									body: data,
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
								const res = await req.json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (res.code == 201 && res.data._id) {
 | 
				
			||||||
 | 
									// TODO: reditect using expo router
 | 
				
			||||||
 | 
									// window.location.href = `/beer/${res.data._id}`;
 | 
				
			||||||
 | 
									alert("Added");
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									alert(
 | 
				
			||||||
 | 
										"Beer was not added successfully. Please check your data and try again.",
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} catch (err) {
 | 
				
			||||||
			alert(
 | 
								alert(
 | 
				
			||||||
				"Beer was not added successfully. Please check your data and try again.",
 | 
									"Beer was not added successfully. Please check your data and try again.",
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
								console.error(err);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -140,6 +171,7 @@ export default function BeerAdd() {
 | 
				
			|||||||
					onChangeText={(text) => validateDegreeInput(text)}
 | 
										onChangeText={(text) => validateDegreeInput(text)}
 | 
				
			||||||
					placeholderTextColor="#aaaaaa"
 | 
										placeholderTextColor="#aaaaaa"
 | 
				
			||||||
					keyboardType="numeric"
 | 
										keyboardType="numeric"
 | 
				
			||||||
 | 
										maxLength={3}
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<DropDownPicker
 | 
									<DropDownPicker
 | 
				
			||||||
@@ -153,6 +185,7 @@ export default function BeerAdd() {
 | 
				
			|||||||
					theme="DropdownTheme"
 | 
										theme="DropdownTheme"
 | 
				
			||||||
					//searchable={true} //maybe we can use it later...
 | 
										//searchable={true} //maybe we can use it later...
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<View style={styles.imageContainer}>
 | 
									<View style={styles.imageContainer}>
 | 
				
			||||||
					<Button
 | 
										<Button
 | 
				
			||||||
						title="Open gallery"
 | 
											title="Open gallery"
 | 
				
			||||||
@@ -161,14 +194,18 @@ export default function BeerAdd() {
 | 
				
			|||||||
						textStyle={styles.imageTextButton}
 | 
											textStyle={styles.imageTextButton}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<Button
 | 
										{Platform.OS != "web" ? (
 | 
				
			||||||
						onPress={openCamera}
 | 
											<Button
 | 
				
			||||||
						title="Open camera"
 | 
												title="Open camera"
 | 
				
			||||||
						buttonStyle={styles.imageButton}
 | 
												onPress={openCamera}
 | 
				
			||||||
						textStyle={styles.imageTextButton}
 | 
												buttonStyle={styles.imageButton}
 | 
				
			||||||
					/>
 | 
												textStyle={styles.imageTextButton}
 | 
				
			||||||
 | 
											/>
 | 
				
			||||||
 | 
										) : (
 | 
				
			||||||
 | 
											false
 | 
				
			||||||
 | 
										)}
 | 
				
			||||||
				</View>
 | 
									</View>
 | 
				
			||||||
				{image && <Image source={{ uri: image }} style={styles.image} />}
 | 
									{image && <Image source={{ uri: image.uri }} style={styles.image} />}
 | 
				
			||||||
				<Button title="Add beer" color={colors.gold} onPress={addBeer} />
 | 
									<Button title="Add beer" color={colors.gold} onPress={addBeer} />
 | 
				
			||||||
			</View>
 | 
								</View>
 | 
				
			||||||
		</View>
 | 
							</View>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,20 @@
 | 
				
			|||||||
import { StyleSheet, View, FlatList } from "react-native";
 | 
					import {
 | 
				
			||||||
 | 
						StyleSheet,
 | 
				
			||||||
 | 
						View,
 | 
				
			||||||
 | 
						FlatList,
 | 
				
			||||||
 | 
						Dimensions,
 | 
				
			||||||
 | 
						StatusBar,
 | 
				
			||||||
 | 
						Image,
 | 
				
			||||||
 | 
					} from "react-native";
 | 
				
			||||||
import Text from "@components/Text";
 | 
					import Text from "@components/Text";
 | 
				
			||||||
import Button from "@components/Button";
 | 
					import Button from "@components/Button";
 | 
				
			||||||
import { colors } from "@components/style";
 | 
					import { colors } from "@components/style";
 | 
				
			||||||
import { router } from "expo-router";
 | 
					import { router } from "expo-router";
 | 
				
			||||||
import { useEffect, useState } from "react";
 | 
					import { useEffect, useState } from "react";
 | 
				
			||||||
 | 
					// import { FlashList } from "@shopify/flash-list";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Tab() {
 | 
					export default function Tab() {
 | 
				
			||||||
 | 
						const API_HOST = process.env.EXPO_PUBLIC_API_URL.replace("/api/v1", "");
 | 
				
			||||||
	const [data, setData] = useState([]);
 | 
						const [data, setData] = useState([]);
 | 
				
			||||||
	useEffect(() => {
 | 
						useEffect(() => {
 | 
				
			||||||
		fetchData();
 | 
							fetchData();
 | 
				
			||||||
@@ -28,23 +37,60 @@ export default function Tab() {
 | 
				
			|||||||
	return (
 | 
						return (
 | 
				
			||||||
		<View style={styles.container}>
 | 
							<View style={styles.container}>
 | 
				
			||||||
			<Button
 | 
								<Button
 | 
				
			||||||
				title="Add Beer"
 | 
									title="Add new beer"
 | 
				
			||||||
				color={colors.gold}
 | 
									color={colors.gold}
 | 
				
			||||||
				onPress={() => {
 | 
									onPress={() => {
 | 
				
			||||||
					router.replace("/beer/add");
 | 
										router.replace("/beer/add");
 | 
				
			||||||
				}}
 | 
									}}
 | 
				
			||||||
			/>
 | 
								/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								{/* 				<FlashList
 | 
				
			||||||
 | 
										data={data}
 | 
				
			||||||
 | 
										estimatedItemSize={100}
 | 
				
			||||||
 | 
										keyExtractor={(item) => String(item._id)}
 | 
				
			||||||
 | 
										renderItem={({ item }) => (
 | 
				
			||||||
 | 
											<View style={styles.item}>
 | 
				
			||||||
 | 
												<Text>Name: {item.name}</Text>
 | 
				
			||||||
 | 
												<Text>Brand: {item.brand}</Text>
 | 
				
			||||||
 | 
												<Text>Degree: {item.degree}</Text>
 | 
				
			||||||
 | 
												<Text>Packaging: {item.packaging}</Text>
 | 
				
			||||||
 | 
											</View>
 | 
				
			||||||
 | 
										)}
 | 
				
			||||||
 | 
									/> */}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<FlatList
 | 
								<FlatList
 | 
				
			||||||
				data={data}
 | 
									data={data}
 | 
				
			||||||
				style={styles.beerList}
 | 
									style={styles.beerList}
 | 
				
			||||||
				keyExtractor={(item) => String(item._id)}
 | 
									keyExtractor={(item) => String(item._id)}
 | 
				
			||||||
				renderItem={({ item }) => (
 | 
									renderItem={({ item }) => (
 | 
				
			||||||
					<View style={styles.item}>
 | 
										<View style={styles.item}>
 | 
				
			||||||
						<Text>Name: {item.name}</Text>
 | 
											<Image
 | 
				
			||||||
						<Text>Brand: {item.brand}</Text>
 | 
												source={
 | 
				
			||||||
						<Text>Degree: {item.degree}</Text>
 | 
													item.imgs[0]
 | 
				
			||||||
						<Text>Packaging: {item.packaging}</Text>
 | 
														? {
 | 
				
			||||||
 | 
																uri: `${API_HOST}/public/uploads/${item.imgs[0]}`,
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														: {
 | 
				
			||||||
 | 
																uri: "https://imagesvc.meredithcorp.io/v3/mm/image?url=https:%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2020%2F09%2F29%2Flight-beer.jpg",
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
												style={styles.itemImg}
 | 
				
			||||||
 | 
											/>
 | 
				
			||||||
 | 
											<View style={styles.itemDesc}>
 | 
				
			||||||
 | 
												<Text>Name: {item.name}</Text>
 | 
				
			||||||
 | 
												<Text>Brand: {item.brand}</Text>
 | 
				
			||||||
 | 
												<Text>Degree: {item.degree}</Text>
 | 
				
			||||||
 | 
												<Text>Packaging: {item.packaging}</Text>
 | 
				
			||||||
 | 
											</View>
 | 
				
			||||||
 | 
											<View style={styles.itemAddReview}>
 | 
				
			||||||
 | 
												<Button
 | 
				
			||||||
 | 
													title="Add review"
 | 
				
			||||||
 | 
													color={colors.gold}
 | 
				
			||||||
 | 
													onPress={() => {
 | 
				
			||||||
 | 
														router.push(`/review/add/${item._id}`);
 | 
				
			||||||
 | 
													}}
 | 
				
			||||||
 | 
												/>
 | 
				
			||||||
 | 
											</View>
 | 
				
			||||||
					</View>
 | 
										</View>
 | 
				
			||||||
				)}
 | 
									)}
 | 
				
			||||||
			/>
 | 
								/>
 | 
				
			||||||
@@ -57,12 +103,12 @@ export const styles = StyleSheet.create({
 | 
				
			|||||||
		flex: 1,
 | 
							flex: 1,
 | 
				
			||||||
		justifyContent: "center",
 | 
							justifyContent: "center",
 | 
				
			||||||
		alignItems: "center",
 | 
							alignItems: "center",
 | 
				
			||||||
		marginTop: "5%",
 | 
							marginTop: "2%",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	beerList: {
 | 
						beerList: {
 | 
				
			||||||
		width: "100%",
 | 
							width: "100%",
 | 
				
			||||||
		paddingHorizontal: "15%",
 | 
							paddingHorizontal: "15%",
 | 
				
			||||||
		marginTop: "5%",
 | 
							marginTop: "2%",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	item: {
 | 
						item: {
 | 
				
			||||||
		borderColor: "gray",
 | 
							borderColor: "gray",
 | 
				
			||||||
@@ -71,4 +117,12 @@ export const styles = StyleSheet.create({
 | 
				
			|||||||
		padding: 13,
 | 
							padding: 13,
 | 
				
			||||||
		marginBottom: "5%",
 | 
							marginBottom: "5%",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						itemImg: {
 | 
				
			||||||
 | 
							height: 300,
 | 
				
			||||||
 | 
							resizeMode: "contain",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						itemDesc: {
 | 
				
			||||||
 | 
							alignItems: "center",
 | 
				
			||||||
 | 
							paddingBottom: "2%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
import { View } from "react-native";
 | 
					 | 
				
			||||||
import Text from "@components/Text";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function Tab() {
 | 
					 | 
				
			||||||
	return (
 | 
					 | 
				
			||||||
		<View style={{ justifyContent: "center", alignItems: "center", flex: 1 }}>
 | 
					 | 
				
			||||||
			<Text>Tab REVIEW</Text>
 | 
					 | 
				
			||||||
		</View>
 | 
					 | 
				
			||||||
	);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										521
									
								
								frontend/app/(app)/(tabs)/review/add/[beer_id].js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,521 @@
 | 
				
			|||||||
 | 
					import { StyleSheet, TextInput, View, Image } from "react-native";
 | 
				
			||||||
 | 
					import { useCallback, useState } from "react";
 | 
				
			||||||
 | 
					import Button from "@components/Button";
 | 
				
			||||||
 | 
					import Text from "@components/Text";
 | 
				
			||||||
 | 
					import { colors } from "@components/style";
 | 
				
			||||||
 | 
					import * as ImagePicker from "expo-image-picker";
 | 
				
			||||||
 | 
					import DropDownPicker from "react-native-dropdown-picker";
 | 
				
			||||||
 | 
					const DropdownTheme = require("@components/DropdownTheme");
 | 
				
			||||||
 | 
					import { Platform } from "react-native";
 | 
				
			||||||
 | 
					import { useLocalSearchParams } from "expo-router";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function reviewAdd() {
 | 
				
			||||||
 | 
						// States for each dropdown
 | 
				
			||||||
 | 
						const routeParams = useLocalSearchParams();
 | 
				
			||||||
 | 
						const [openFoam, setOpenFoam] = useState(false);
 | 
				
			||||||
 | 
						const [openBitterSweetness, setOpenBitterSweetness] = useState(false);
 | 
				
			||||||
 | 
						const [openTaste, setOpenTaste] = useState(false);
 | 
				
			||||||
 | 
						const [openPackaging, setOpenPackaging] = useState(false);
 | 
				
			||||||
 | 
						const [openSourness, setOpenSourness] = useState(false);
 | 
				
			||||||
 | 
						const [openAgain, setOpenAgain] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// pěna
 | 
				
			||||||
 | 
						const [itemFoam, setFoamValue] = useState(null);
 | 
				
			||||||
 | 
						const [foam, setFoam] = useState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Bad",
 | 
				
			||||||
 | 
								value: "1",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-x-eyes.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Medium",
 | 
				
			||||||
 | 
								value: "2",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-meh.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Excellent",
 | 
				
			||||||
 | 
								value: "3",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// hořkost / sladkost
 | 
				
			||||||
 | 
						const [itemBitter_sweetness, setBitter_sweetnessValue] = useState(null);
 | 
				
			||||||
 | 
						const [bitter_sweetness, setBitter_sweetness] = useState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Bad",
 | 
				
			||||||
 | 
								value: "1",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-x-eyes.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Medium",
 | 
				
			||||||
 | 
								value: "2",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-meh.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Excellent",
 | 
				
			||||||
 | 
								value: "3",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//chuť
 | 
				
			||||||
 | 
						const [itemTaste, setTasteValue] = useState(null);
 | 
				
			||||||
 | 
						const [taste, setTaste] = useState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Disgust",
 | 
				
			||||||
 | 
								value: "1",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-blank.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Not great, not terrible",
 | 
				
			||||||
 | 
								value: "2",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-nervous.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Good",
 | 
				
			||||||
 | 
								value: "3",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-meh.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Why not",
 | 
				
			||||||
 | 
								value: "4",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-wink.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Excellent!",
 | 
				
			||||||
 | 
								value: "5",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// packaging
 | 
				
			||||||
 | 
						const [itemPackaging, setPackagingValue] = useState(null);
 | 
				
			||||||
 | 
						const [packaging, setPackaging] = useState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Disgust",
 | 
				
			||||||
 | 
								value: "1",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-blank.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Not great, not terrible",
 | 
				
			||||||
 | 
								value: "2",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-nervous.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Good",
 | 
				
			||||||
 | 
								value: "3",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-meh.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Why not",
 | 
				
			||||||
 | 
								value: "4",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-wink.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Excellent!",
 | 
				
			||||||
 | 
								value: "5",
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//kyselost
 | 
				
			||||||
 | 
						const [itemSourness, setSournessValue] = useState(null);
 | 
				
			||||||
 | 
						const [sourness, setSourness] = useState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "True",
 | 
				
			||||||
 | 
								value: true,
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-blank.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "False",
 | 
				
			||||||
 | 
								value: false,
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-nervous.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//dal bych si znovu?
 | 
				
			||||||
 | 
						const [itemAgain, setAgainValue] = useState(null);
 | 
				
			||||||
 | 
						const [again, setAgain] = useState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "Yes",
 | 
				
			||||||
 | 
								value: true,
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								label: "No",
 | 
				
			||||||
 | 
								value: false,
 | 
				
			||||||
 | 
								icon: () => (
 | 
				
			||||||
 | 
									<Image
 | 
				
			||||||
 | 
										source={require("@assets/smileys/smiley-x-eyes.png")}
 | 
				
			||||||
 | 
										style={styles.iconStyle}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//podmínky pro zavření ostatních dropdownů, pokud je jiný otevřený
 | 
				
			||||||
 | 
						const onOpenFoam = useCallback(() => {
 | 
				
			||||||
 | 
							setOpenBitterSweetness(false);
 | 
				
			||||||
 | 
							setOpenTaste(false);
 | 
				
			||||||
 | 
							setOpenPackaging(false);
 | 
				
			||||||
 | 
							setOpenSourness(false);
 | 
				
			||||||
 | 
							setOpenAgain(false);
 | 
				
			||||||
 | 
							setOpenFoam(true);
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const onOpenBitterSweetness = useCallback(() => {
 | 
				
			||||||
 | 
							setOpenFoam(false);
 | 
				
			||||||
 | 
							setOpenTaste(false);
 | 
				
			||||||
 | 
							setOpenPackaging(false);
 | 
				
			||||||
 | 
							setOpenSourness(false);
 | 
				
			||||||
 | 
							setOpenAgain(false);
 | 
				
			||||||
 | 
							setOpenBitterSweetness(true);
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const onOpenTaste = useCallback(() => {
 | 
				
			||||||
 | 
							setOpenFoam(false);
 | 
				
			||||||
 | 
							setOpenBitterSweetness(false);
 | 
				
			||||||
 | 
							setOpenPackaging(false);
 | 
				
			||||||
 | 
							setOpenSourness(false);
 | 
				
			||||||
 | 
							setOpenAgain(false);
 | 
				
			||||||
 | 
							setOpenTaste(true);
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const onOpenPackaging = useCallback(() => {
 | 
				
			||||||
 | 
							setOpenFoam(false);
 | 
				
			||||||
 | 
							setOpenBitterSweetness(false);
 | 
				
			||||||
 | 
							setOpenTaste(false);
 | 
				
			||||||
 | 
							setOpenSourness(false);
 | 
				
			||||||
 | 
							setOpenAgain(false);
 | 
				
			||||||
 | 
							setOpenPackaging(true);
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const onOpenSourness = useCallback(() => {
 | 
				
			||||||
 | 
							setOpenFoam(false);
 | 
				
			||||||
 | 
							setOpenBitterSweetness(false);
 | 
				
			||||||
 | 
							setOpenTaste(false);
 | 
				
			||||||
 | 
							setOpenPackaging(false);
 | 
				
			||||||
 | 
							setOpenAgain(false);
 | 
				
			||||||
 | 
							setOpenSourness(true);
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const onOpenAgain = useCallback(() => {
 | 
				
			||||||
 | 
							setOpenFoam(false);
 | 
				
			||||||
 | 
							setOpenBitterSweetness(false);
 | 
				
			||||||
 | 
							setOpenTaste(false);
 | 
				
			||||||
 | 
							setOpenPackaging(false);
 | 
				
			||||||
 | 
							setOpenSourness(false);
 | 
				
			||||||
 | 
							setOpenAgain(true);
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DropDownPicker.addTheme("DropdownTheme", DropdownTheme);
 | 
				
			||||||
 | 
						DropDownPicker.setTheme("DropdownTheme");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async function addBeer() {
 | 
				
			||||||
 | 
							const req = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/review/add`, {
 | 
				
			||||||
 | 
								method: "POST",
 | 
				
			||||||
 | 
								credentials: "include",
 | 
				
			||||||
 | 
								headers: { "Content-Type": "application/json" },
 | 
				
			||||||
 | 
								body: JSON.stringify({
 | 
				
			||||||
 | 
									beer_id: routeParams.beer_id,
 | 
				
			||||||
 | 
									foam: itemFoam,
 | 
				
			||||||
 | 
									bitter_sweetness: itemBitter_sweetness,
 | 
				
			||||||
 | 
									taste: itemTaste,
 | 
				
			||||||
 | 
									packaging: itemPackaging,
 | 
				
			||||||
 | 
									sourness: itemSourness,
 | 
				
			||||||
 | 
									would_again: itemAgain,
 | 
				
			||||||
 | 
								}),
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							const res = await req.json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (res.code == 201 && res.data._id) {
 | 
				
			||||||
 | 
								// window.location.href = `/review/${res.data._id}`;
 | 
				
			||||||
 | 
								// TODO: use react router for redirect
 | 
				
			||||||
 | 
								alert("Review was added!");
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								alert(
 | 
				
			||||||
 | 
									"Review was not added successfully. Please check your data and try again.",
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
							<View style={styles.container}>
 | 
				
			||||||
 | 
								<View style={styles.form}>
 | 
				
			||||||
 | 
									<Text style={styles.text}>
 | 
				
			||||||
 | 
										How does your beer taste? Write a review!
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<Text style={styles.dropdownText} zIndex={6000} zIndexInverse={1000}>
 | 
				
			||||||
 | 
										How does the foam look like?
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<DropDownPicker
 | 
				
			||||||
 | 
										open={openFoam}
 | 
				
			||||||
 | 
										onOpen={onOpenFoam}
 | 
				
			||||||
 | 
										value={itemFoam}
 | 
				
			||||||
 | 
										items={foam}
 | 
				
			||||||
 | 
										setOpen={setOpenFoam}
 | 
				
			||||||
 | 
										setValue={setFoamValue}
 | 
				
			||||||
 | 
										setItems={setFoam}
 | 
				
			||||||
 | 
										placeholder="Please select..."
 | 
				
			||||||
 | 
										theme="DropdownTheme"
 | 
				
			||||||
 | 
										zIndex={6000}
 | 
				
			||||||
 | 
										zIndexInverse={1000}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
									<Text style={styles.dropdownText} zIndex={5000} zIndexInverse={2000}>
 | 
				
			||||||
 | 
										More bitter, or more sweet?
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<DropDownPicker
 | 
				
			||||||
 | 
										open={openBitterSweetness}
 | 
				
			||||||
 | 
										onOpen={onOpenBitterSweetness}
 | 
				
			||||||
 | 
										value={itemBitter_sweetness}
 | 
				
			||||||
 | 
										items={bitter_sweetness}
 | 
				
			||||||
 | 
										setOpen={setOpenBitterSweetness}
 | 
				
			||||||
 | 
										setValue={setBitter_sweetnessValue}
 | 
				
			||||||
 | 
										setItems={setBitter_sweetness}
 | 
				
			||||||
 | 
										placeholder="Please select..."
 | 
				
			||||||
 | 
										theme="DropdownTheme"
 | 
				
			||||||
 | 
										zIndex={5000}
 | 
				
			||||||
 | 
										zIndexInverse={2000}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<Text style={styles.dropdownText} zIndex={4000} zIndexInverse={3000}>
 | 
				
			||||||
 | 
										How does it taste?
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<DropDownPicker
 | 
				
			||||||
 | 
										open={openTaste}
 | 
				
			||||||
 | 
										onOpen={onOpenTaste}
 | 
				
			||||||
 | 
										value={itemTaste}
 | 
				
			||||||
 | 
										items={taste}
 | 
				
			||||||
 | 
										setOpen={setOpenTaste}
 | 
				
			||||||
 | 
										setValue={setTasteValue}
 | 
				
			||||||
 | 
										setItems={setTaste}
 | 
				
			||||||
 | 
										placeholder="Please select..."
 | 
				
			||||||
 | 
										theme="DropdownTheme"
 | 
				
			||||||
 | 
										zIndex={4000}
 | 
				
			||||||
 | 
										zIndexInverse={3000}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<Text style={styles.dropdownText} zIndex={5000} zIndexInverse={4000}>
 | 
				
			||||||
 | 
										How do you like the packaging?
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<DropDownPicker
 | 
				
			||||||
 | 
										open={openPackaging}
 | 
				
			||||||
 | 
										onOpen={onOpenPackaging}
 | 
				
			||||||
 | 
										value={itemPackaging}
 | 
				
			||||||
 | 
										items={packaging}
 | 
				
			||||||
 | 
										setOpen={setOpenPackaging}
 | 
				
			||||||
 | 
										setValue={setPackagingValue}
 | 
				
			||||||
 | 
										setItems={setPackaging}
 | 
				
			||||||
 | 
										placeholder="Please select..."
 | 
				
			||||||
 | 
										theme="DropdownTheme"
 | 
				
			||||||
 | 
										zIndex={3000}
 | 
				
			||||||
 | 
										zIndexInverse={4000}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<Text style={styles.dropdownText} zIndex={4000} zIndexInverse={5000}>
 | 
				
			||||||
 | 
										Is it sour?
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<DropDownPicker
 | 
				
			||||||
 | 
										open={openSourness}
 | 
				
			||||||
 | 
										onOpen={onOpenSourness}
 | 
				
			||||||
 | 
										value={itemSourness}
 | 
				
			||||||
 | 
										items={sourness}
 | 
				
			||||||
 | 
										setOpen={setOpenSourness}
 | 
				
			||||||
 | 
										setValue={setSournessValue}
 | 
				
			||||||
 | 
										setItems={setSourness}
 | 
				
			||||||
 | 
										placeholder="Please select..."
 | 
				
			||||||
 | 
										theme="DropdownTheme"
 | 
				
			||||||
 | 
										zIndex={2000}
 | 
				
			||||||
 | 
										zIndexInverse={5000}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<Text style={styles.dropdownText} zIndex={5000} zIndexInverse={6000}>
 | 
				
			||||||
 | 
										Would you drink it again?
 | 
				
			||||||
 | 
									</Text>
 | 
				
			||||||
 | 
									<DropDownPicker
 | 
				
			||||||
 | 
										open={openAgain}
 | 
				
			||||||
 | 
										onOpen={onOpenAgain}
 | 
				
			||||||
 | 
										value={itemAgain}
 | 
				
			||||||
 | 
										items={again}
 | 
				
			||||||
 | 
										setOpen={setOpenAgain}
 | 
				
			||||||
 | 
										setValue={setAgainValue}
 | 
				
			||||||
 | 
										setItems={setAgain}
 | 
				
			||||||
 | 
										placeholder="Please select..."
 | 
				
			||||||
 | 
										theme="DropdownTheme"
 | 
				
			||||||
 | 
										zIndex={1000}
 | 
				
			||||||
 | 
										zIndexInverse={6000}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<View style={styles.buttonSend}>
 | 
				
			||||||
 | 
										<Button title="Add review" color={colors.gold} onPress={addBeer} />
 | 
				
			||||||
 | 
									</View>
 | 
				
			||||||
 | 
								</View>
 | 
				
			||||||
 | 
							</View>
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
 | 
						container: {
 | 
				
			||||||
 | 
							width: "100%",
 | 
				
			||||||
 | 
							height: "100%",
 | 
				
			||||||
 | 
							alignItems: "center",
 | 
				
			||||||
 | 
							display: "flex",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						form: {
 | 
				
			||||||
 | 
							gap: 5,
 | 
				
			||||||
 | 
							width: "80%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						buttonSend: {
 | 
				
			||||||
 | 
							display: "flex",
 | 
				
			||||||
 | 
							alignItems: "center",
 | 
				
			||||||
 | 
							marginTop: "2%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						input: {
 | 
				
			||||||
 | 
							height: "auto",
 | 
				
			||||||
 | 
							width: "100%",
 | 
				
			||||||
 | 
							borderColor: "gray",
 | 
				
			||||||
 | 
							borderWidth: 1,
 | 
				
			||||||
 | 
							borderRadius: 10,
 | 
				
			||||||
 | 
							padding: 13,
 | 
				
			||||||
 | 
							color: "#fff",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						imageContainer: {
 | 
				
			||||||
 | 
							alignItems: "center",
 | 
				
			||||||
 | 
							justifyContent: "center",
 | 
				
			||||||
 | 
							display: "flex",
 | 
				
			||||||
 | 
							flexDirection: "row",
 | 
				
			||||||
 | 
							gap: 10,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						imageButton: {
 | 
				
			||||||
 | 
							backgroundColor: colors.dark,
 | 
				
			||||||
 | 
							borderColor: "gray",
 | 
				
			||||||
 | 
							borderWidth: 1,
 | 
				
			||||||
 | 
							borderRadius: 10,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						imageTextButton: {
 | 
				
			||||||
 | 
							color: colors.white,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						image: {
 | 
				
			||||||
 | 
							width: 150,
 | 
				
			||||||
 | 
							height: 150,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						text: {
 | 
				
			||||||
 | 
							color: colors.white,
 | 
				
			||||||
 | 
							fontSize: 24,
 | 
				
			||||||
 | 
							textAlign: "center",
 | 
				
			||||||
 | 
							paddingBottom: "3%",
 | 
				
			||||||
 | 
							paddingTop: "10%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						iconStyle: {
 | 
				
			||||||
 | 
							width: 30,
 | 
				
			||||||
 | 
							height: 30,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						dropdownContainer: {
 | 
				
			||||||
 | 
							width: "100%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						dropdownText: {
 | 
				
			||||||
 | 
							color: colors.white,
 | 
				
			||||||
 | 
							fontSize: 16,
 | 
				
			||||||
 | 
							paddingBottom: 1,
 | 
				
			||||||
 | 
							paddingTop: "1%",
 | 
				
			||||||
 | 
							display: "flex",
 | 
				
			||||||
 | 
							alignItems: "flex-start",
 | 
				
			||||||
 | 
							flexDirection: "column",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										139
									
								
								frontend/app/(app)/(tabs)/review/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					import { View, StyleSheet, FlatList, Image } from "react-native";
 | 
				
			||||||
 | 
					import Text from "@components/Text";
 | 
				
			||||||
 | 
					import Button from "@components/Button";
 | 
				
			||||||
 | 
					import { colors } from "@components/style";
 | 
				
			||||||
 | 
					import { router } from "expo-router";
 | 
				
			||||||
 | 
					import { useEffect, useState } from "react";
 | 
				
			||||||
 | 
					import { useAuth } from "@context/AuthContext";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function Tab() {
 | 
				
			||||||
 | 
						const { authState } = useAuth();
 | 
				
			||||||
 | 
						const user = authState.user;
 | 
				
			||||||
 | 
						const [data, setData] = useState([]);
 | 
				
			||||||
 | 
						useEffect(() => {
 | 
				
			||||||
 | 
							fetchData();
 | 
				
			||||||
 | 
						}, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const API_HOST = process.env.EXPO_PUBLIC_API_URL.replace("/api/v1", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						async function fetchData() {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								const res = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/review/get`, {
 | 
				
			||||||
 | 
									method: "GET",
 | 
				
			||||||
 | 
									credentials: "include",
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
								let data = await res.json();
 | 
				
			||||||
 | 
								// show only logged in user's data
 | 
				
			||||||
 | 
								data = data.data.filter((review) => review.user_id == user._id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								let beers = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/beer/get`, {
 | 
				
			||||||
 | 
									method: "GET",
 | 
				
			||||||
 | 
									credentials: "include",
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
								beers = await beers.json();
 | 
				
			||||||
 | 
								beers = beers.data;
 | 
				
			||||||
 | 
								console.log(beers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								async function getBeerParam(search, beers) {
 | 
				
			||||||
 | 
									for (let i = 0; i < beers.length; i++) {
 | 
				
			||||||
 | 
										if (beers[i]._id == search) {
 | 
				
			||||||
 | 
											return beers[i];
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return null;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								data.forEach(async (el) => {
 | 
				
			||||||
 | 
									el.beer = await getBeerParam(el.beer_id, beers);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								console.log("reviews", data);
 | 
				
			||||||
 | 
								setData(data);
 | 
				
			||||||
 | 
							} catch (err) {
 | 
				
			||||||
 | 
								console.error(err);
 | 
				
			||||||
 | 
								alert("Something went wrong");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const opt3 = ["Bad", "Medium", "Excellent!"];
 | 
				
			||||||
 | 
						const opt5 = [
 | 
				
			||||||
 | 
							"Disgust",
 | 
				
			||||||
 | 
							"Not great, not terrible",
 | 
				
			||||||
 | 
							"Good",
 | 
				
			||||||
 | 
							"Why not?",
 | 
				
			||||||
 | 
							"Excellent!",
 | 
				
			||||||
 | 
						];
 | 
				
			||||||
 | 
						const opt2 = ["Yes", "No"];
 | 
				
			||||||
 | 
						const sourness = ["Good", "Bad"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
							<View style={styles.container}>
 | 
				
			||||||
 | 
								<FlatList
 | 
				
			||||||
 | 
									data={data}
 | 
				
			||||||
 | 
									style={styles.reviewList}
 | 
				
			||||||
 | 
									keyExtractor={(item) => String(item._id)}
 | 
				
			||||||
 | 
									renderItem={({ item }) => (
 | 
				
			||||||
 | 
										<View style={styles.itemContainer}>
 | 
				
			||||||
 | 
											<View>
 | 
				
			||||||
 | 
												<Text>{item.beer.name}</Text>
 | 
				
			||||||
 | 
												<Text>{item.beer.brand}</Text>
 | 
				
			||||||
 | 
												<Text>{item.beer.degree}°</Text>
 | 
				
			||||||
 | 
												<Text>{item.beer.packaging}</Text>
 | 
				
			||||||
 | 
												<Image
 | 
				
			||||||
 | 
													source={
 | 
				
			||||||
 | 
														item.beer.imgs[0]
 | 
				
			||||||
 | 
															? {
 | 
				
			||||||
 | 
																	uri: `${API_HOST}/public/uploads/${item.beer.imgs[0]}`,
 | 
				
			||||||
 | 
																}
 | 
				
			||||||
 | 
															: {
 | 
				
			||||||
 | 
																	uri: "https://imagesvc.meredithcorp.io/v3/mm/image?url=https:%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2020%2F09%2F29%2Flight-beer.jpg",
 | 
				
			||||||
 | 
																}
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													style={styles.itemImg}
 | 
				
			||||||
 | 
												/>
 | 
				
			||||||
 | 
											</View>
 | 
				
			||||||
 | 
											<View>
 | 
				
			||||||
 | 
												<Text>Foam → {opt3[item.foam - 1]}</Text>
 | 
				
			||||||
 | 
												<Text>
 | 
				
			||||||
 | 
													Bitter / Sweetness → {opt3[item.bitter_sweetness - 1]}
 | 
				
			||||||
 | 
												</Text>
 | 
				
			||||||
 | 
												<Text>Taste → {opt5[item.taste - 1]}</Text>
 | 
				
			||||||
 | 
												<Text>Packaging → {opt5[item.packaging - 1]}</Text>
 | 
				
			||||||
 | 
												<Text>Sourness → {sourness[item.sourness - 1]}</Text>
 | 
				
			||||||
 | 
												<Text>Would again? → {opt2[item.would_again - 1]}</Text>
 | 
				
			||||||
 | 
											</View>
 | 
				
			||||||
 | 
										</View>
 | 
				
			||||||
 | 
									)}
 | 
				
			||||||
 | 
								/>
 | 
				
			||||||
 | 
							</View>
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const styles = StyleSheet.create({
 | 
				
			||||||
 | 
						container: {
 | 
				
			||||||
 | 
							flex: 1,
 | 
				
			||||||
 | 
							justifyContent: "center",
 | 
				
			||||||
 | 
							alignItems: "center",
 | 
				
			||||||
 | 
							marginTop: "5%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						reviewList: {
 | 
				
			||||||
 | 
							width: "100%",
 | 
				
			||||||
 | 
							paddingHorizontal: "15%",
 | 
				
			||||||
 | 
							marginTop: "5%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						itemContainer: {
 | 
				
			||||||
 | 
							borderColor: "gray",
 | 
				
			||||||
 | 
							borderWidth: 1,
 | 
				
			||||||
 | 
							borderRadius: 10,
 | 
				
			||||||
 | 
							padding: 13,
 | 
				
			||||||
 | 
							marginBottom: "5%",
 | 
				
			||||||
 | 
							flex: 1,
 | 
				
			||||||
 | 
							flexDirection: "row",
 | 
				
			||||||
 | 
							justifyContent: "space-between",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						itemImg: {
 | 
				
			||||||
 | 
							width: 150,
 | 
				
			||||||
 | 
							aspectRatio: 1,
 | 
				
			||||||
 | 
							resizeMode: "contain",
 | 
				
			||||||
 | 
							marginTop: "5%",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -16,23 +16,28 @@ function SignupPage() {
 | 
				
			|||||||
	const { onSignin } = useAuth();
 | 
						const { onSignin } = useAuth();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async function signin() {
 | 
						async function signin() {
 | 
				
			||||||
		if (pass1 == pass2) {
 | 
							if (pass1 != pass2) {
 | 
				
			||||||
			const res = await onSignin(username, email, pass1);
 | 
								alert("Passwords are not same!");
 | 
				
			||||||
			if (res.error) {
 | 
								return;
 | 
				
			||||||
				if (res.msg.message == "validation error") {
 | 
							}
 | 
				
			||||||
					alert(res.msg.data.message);
 | 
					
 | 
				
			||||||
				} else {
 | 
							const res = await onSignin(username, email, pass1);
 | 
				
			||||||
					alert(res.msg.message);
 | 
							const data = await res.json();
 | 
				
			||||||
				}
 | 
					
 | 
				
			||||||
			}
 | 
							if (res.status == 400) {
 | 
				
			||||||
			if (!res.error) {
 | 
								if (data.message == "validation error") {
 | 
				
			||||||
				alert("You have been successfully registered. Please Log In");
 | 
									alert(data.data.message);
 | 
				
			||||||
				router.replace("/login");
 | 
								} else {
 | 
				
			||||||
 | 
									alert("Something went wrong");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		alert("Passwords are not same!");
 | 
							if (res.status == 201) {
 | 
				
			||||||
 | 
								alert("You have been successfully registered. Please Log In");
 | 
				
			||||||
 | 
								router.replace("/login");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley-blank.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley-meh.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley-nervous.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley-sad.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley-wink.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley-x-eyes.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 8.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/assets/smileys/smiley.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 9.0 KiB  | 
@@ -1,7 +1,7 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
 | 
						"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
 | 
				
			||||||
	"files": {
 | 
						"files": {
 | 
				
			||||||
		"ignore": [".expo/", ".vscode/", "node_modules/"]
 | 
							"ignore": [".expo/", ".vscode/", "node_modules/", "dist/"]
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"organizeImports": {
 | 
						"organizeImports": {
 | 
				
			||||||
		"enabled": true
 | 
							"enabled": true
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										244
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@@ -10,6 +10,7 @@
 | 
				
			|||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@expo/metro-runtime": "~3.2.1",
 | 
					        "@expo/metro-runtime": "~3.2.1",
 | 
				
			||||||
        "@react-native-async-storage/async-storage": "^1.23.1",
 | 
					        "@react-native-async-storage/async-storage": "^1.23.1",
 | 
				
			||||||
 | 
					        "@shopify/flash-list": "1.6.4",
 | 
				
			||||||
        "@types/react": "~18.2.45",
 | 
					        "@types/react": "~18.2.45",
 | 
				
			||||||
        "axios": "^1.6.8",
 | 
					        "axios": "^1.6.8",
 | 
				
			||||||
        "expo": "^51.0.2",
 | 
					        "expo": "^51.0.2",
 | 
				
			||||||
@@ -25,6 +26,7 @@
 | 
				
			|||||||
        "react-dom": "18.2.0",
 | 
					        "react-dom": "18.2.0",
 | 
				
			||||||
        "react-native": "0.74.1",
 | 
					        "react-native": "0.74.1",
 | 
				
			||||||
        "react-native-dropdown-picker": "^5.4.6",
 | 
					        "react-native-dropdown-picker": "^5.4.6",
 | 
				
			||||||
 | 
					        "react-native-range-slider-expo": "^1.4.3",
 | 
				
			||||||
        "react-native-safe-area-context": "4.10.1",
 | 
					        "react-native-safe-area-context": "4.10.1",
 | 
				
			||||||
        "react-native-screens": "3.31.1",
 | 
					        "react-native-screens": "3.31.1",
 | 
				
			||||||
        "react-native-web": "~0.19.6"
 | 
					        "react-native-web": "~0.19.6"
 | 
				
			||||||
@@ -2256,6 +2258,18 @@
 | 
				
			|||||||
        "node": ">=14.21.3"
 | 
					        "node": ">=14.21.3"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@egjs/hammerjs": {
 | 
				
			||||||
 | 
					      "version": "2.0.17",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "@types/hammerjs": "^2.0.36"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=0.8.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@expo/bunyan": {
 | 
					    "node_modules/@expo/bunyan": {
 | 
				
			||||||
      "version": "4.0.0",
 | 
					      "version": "4.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@expo/bunyan/-/bunyan-4.0.0.tgz",
 | 
				
			||||||
@@ -6303,6 +6317,25 @@
 | 
				
			|||||||
        "join-component": "^1.1.0"
 | 
					        "join-component": "^1.1.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@shopify/flash-list": {
 | 
				
			||||||
 | 
					      "version": "1.6.4",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@shopify/flash-list/-/flash-list-1.6.4.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-M2momcnY7swsvmpHIFDVbdOaFw4aQocJXA/lFP0Gpz+alQjFylqVKvszxl4atYO2SNbjxlb2L6hEP9WEcAknGQ==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "recyclerlistview": "4.2.0",
 | 
				
			||||||
 | 
					        "tslib": "2.4.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "@babel/runtime": "*",
 | 
				
			||||||
 | 
					        "react": "*",
 | 
				
			||||||
 | 
					        "react-native": "*"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@shopify/flash-list/node_modules/tslib": {
 | 
				
			||||||
 | 
					      "version": "2.4.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@sideway/address": {
 | 
					    "node_modules/@sideway/address": {
 | 
				
			||||||
      "version": "4.1.5",
 | 
					      "version": "4.1.5",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
 | 
				
			||||||
@@ -6347,6 +6380,12 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
 | 
					      "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/@types/hammerjs": {
 | 
				
			||||||
 | 
					      "version": "2.0.45",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.45.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-qkcUlZmX6c4J8q45taBKTL3p+LbITgyx7qhlPYOdOHZB7B31K0mXbP5YA7i7SgDeEGuI9MnumiKPEMrxg8j3KQ==",
 | 
				
			||||||
 | 
					      "peer": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/istanbul-lib-coverage": {
 | 
					    "node_modules/@types/istanbul-lib-coverage": {
 | 
				
			||||||
      "version": "2.0.6",
 | 
					      "version": "2.0.6",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
 | 
				
			||||||
@@ -6988,6 +7027,12 @@
 | 
				
			|||||||
        "node": ">= 6"
 | 
					        "node": ">= 6"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/boolbase": {
 | 
				
			||||||
 | 
					      "version": "1.0.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
 | 
				
			||||||
 | 
					      "peer": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/bplist-creator": {
 | 
					    "node_modules/bplist-creator": {
 | 
				
			||||||
      "version": "0.1.0",
 | 
					      "version": "0.1.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz",
 | 
				
			||||||
@@ -7691,6 +7736,56 @@
 | 
				
			|||||||
        "hyphenate-style-name": "^1.0.3"
 | 
					        "hyphenate-style-name": "^1.0.3"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/css-select": {
 | 
				
			||||||
 | 
					      "version": "5.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "boolbase": "^1.0.0",
 | 
				
			||||||
 | 
					        "css-what": "^6.1.0",
 | 
				
			||||||
 | 
					        "domhandler": "^5.0.2",
 | 
				
			||||||
 | 
					        "domutils": "^3.0.1",
 | 
				
			||||||
 | 
					        "nth-check": "^2.0.1"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/sponsors/fb55"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/css-tree": {
 | 
				
			||||||
 | 
					      "version": "1.1.3",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "mdn-data": "2.0.14",
 | 
				
			||||||
 | 
					        "source-map": "^0.6.1"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=8.0.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/css-tree/node_modules/source-map": {
 | 
				
			||||||
 | 
					      "version": "0.6.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/css-what": {
 | 
				
			||||||
 | 
					      "version": "6.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 6"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/sponsors/fb55"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/csstype": {
 | 
					    "node_modules/csstype": {
 | 
				
			||||||
      "version": "3.1.3",
 | 
					      "version": "3.1.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
 | 
				
			||||||
@@ -7968,6 +8063,61 @@
 | 
				
			|||||||
        "node": ">=8"
 | 
					        "node": ">=8"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/dom-serializer": {
 | 
				
			||||||
 | 
					      "version": "2.0.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "domelementtype": "^2.3.0",
 | 
				
			||||||
 | 
					        "domhandler": "^5.0.2",
 | 
				
			||||||
 | 
					        "entities": "^4.2.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/domelementtype": {
 | 
				
			||||||
 | 
					      "version": "2.3.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
 | 
				
			||||||
 | 
					      "funding": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          "type": "github",
 | 
				
			||||||
 | 
					          "url": "https://github.com/sponsors/fb55"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "peer": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/domhandler": {
 | 
				
			||||||
 | 
					      "version": "5.0.3",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "domelementtype": "^2.3.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">= 4"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/fb55/domhandler?sponsor=1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/domutils": {
 | 
				
			||||||
 | 
					      "version": "3.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "dom-serializer": "^2.0.0",
 | 
				
			||||||
 | 
					        "domelementtype": "^2.3.0",
 | 
				
			||||||
 | 
					        "domhandler": "^5.0.3"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/fb55/domutils?sponsor=1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/dotenv": {
 | 
					    "node_modules/dotenv": {
 | 
				
			||||||
      "version": "16.4.5",
 | 
					      "version": "16.4.5",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
 | 
				
			||||||
@@ -8024,6 +8174,18 @@
 | 
				
			|||||||
        "once": "^1.4.0"
 | 
					        "once": "^1.4.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/entities": {
 | 
				
			||||||
 | 
					      "version": "4.5.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "engines": {
 | 
				
			||||||
 | 
					        "node": ">=0.12"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/fb55/entities?sponsor=1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/env-editor": {
 | 
					    "node_modules/env-editor": {
 | 
				
			||||||
      "version": "0.4.2",
 | 
					      "version": "0.4.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz",
 | 
				
			||||||
@@ -9203,6 +9365,15 @@
 | 
				
			|||||||
        "node": ">=8"
 | 
					        "node": ">=8"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/hoist-non-react-statics": {
 | 
				
			||||||
 | 
					      "version": "3.3.2",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "react-is": "^16.7.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/hosted-git-info": {
 | 
					    "node_modules/hosted-git-info": {
 | 
				
			||||||
      "version": "3.0.8",
 | 
					      "version": "3.0.8",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz",
 | 
				
			||||||
@@ -10981,6 +11152,12 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/md5hex/-/md5hex-1.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/md5hex/-/md5hex-1.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-c2YOUbp33+6thdCUi34xIyOU/a7bvGKj/3DB1iaPMTuPHf/Q2d5s4sn1FaCOO43XkXggnb08y5W2PU8UNYNLKQ=="
 | 
					      "integrity": "sha512-c2YOUbp33+6thdCUi34xIyOU/a7bvGKj/3DB1iaPMTuPHf/Q2d5s4sn1FaCOO43XkXggnb08y5W2PU8UNYNLKQ=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/mdn-data": {
 | 
				
			||||||
 | 
					      "version": "2.0.14",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
 | 
				
			||||||
 | 
					      "peer": true
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/memoize-one": {
 | 
					    "node_modules/memoize-one": {
 | 
				
			||||||
      "version": "5.2.1",
 | 
					      "version": "5.2.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
 | 
				
			||||||
@@ -11846,6 +12023,18 @@
 | 
				
			|||||||
        "node": ">=4"
 | 
					        "node": ">=4"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/nth-check": {
 | 
				
			||||||
 | 
					      "version": "2.1.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "boolbase": "^1.0.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "funding": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/fb55/nth-check?sponsor=1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/nullthrows": {
 | 
					    "node_modules/nullthrows": {
 | 
				
			||||||
      "version": "1.1.1",
 | 
					      "version": "1.1.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
 | 
				
			||||||
@@ -12886,6 +13075,19 @@
 | 
				
			|||||||
        "react-native": "*"
 | 
					        "react-native": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/react-native-gesture-handler": {
 | 
				
			||||||
 | 
					      "version": "1.10.3",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "@egjs/hammerjs": "^2.0.17",
 | 
				
			||||||
 | 
					        "fbjs": "^3.0.0",
 | 
				
			||||||
 | 
					        "hoist-non-react-statics": "^3.3.0",
 | 
				
			||||||
 | 
					        "invariant": "^2.2.4",
 | 
				
			||||||
 | 
					        "prop-types": "^15.7.2"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/react-native-helmet-async": {
 | 
					    "node_modules/react-native-helmet-async": {
 | 
				
			||||||
      "version": "2.0.4",
 | 
					      "version": "2.0.4",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/react-native-helmet-async/-/react-native-helmet-async-2.0.4.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/react-native-helmet-async/-/react-native-helmet-async-2.0.4.tgz",
 | 
				
			||||||
@@ -12899,6 +13101,15 @@
 | 
				
			|||||||
        "react": "^16.6.0 || ^17.0.0 || ^18.0.0"
 | 
					        "react": "^16.6.0 || ^17.0.0 || ^18.0.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/react-native-range-slider-expo": {
 | 
				
			||||||
 | 
					      "version": "1.4.3",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/react-native-range-slider-expo/-/react-native-range-slider-expo-1.4.3.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-EAIXfuCxJYffi6yqOcmCMWzvPNRSJ7zgDhQtVXXe2fokYaXVLG1uq2jM+cpTStMusIIGIo9HGZAja94N+rnNyg==",
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "react-native-gesture-handler": "^1.6.1",
 | 
				
			||||||
 | 
					        "react-native-svg": "^12.1.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/react-native-safe-area-context": {
 | 
					    "node_modules/react-native-safe-area-context": {
 | 
				
			||||||
      "version": "4.10.1",
 | 
					      "version": "4.10.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.10.1.tgz",
 | 
				
			||||||
@@ -12921,6 +13132,20 @@
 | 
				
			|||||||
        "react-native": "*"
 | 
					        "react-native": "*"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/react-native-svg": {
 | 
				
			||||||
 | 
					      "version": "12.5.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.5.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-c374ENsq2MWCfr+7jC7TGwSeOAuC1Dp0osh2pw8PjpYFxmmB/toFIwcnCLz+SgBd6iLJClRhbATealqM05HOGg==",
 | 
				
			||||||
 | 
					      "peer": true,
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "css-select": "^5.1.0",
 | 
				
			||||||
 | 
					        "css-tree": "^1.1.3"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "react": "*",
 | 
				
			||||||
 | 
					        "react-native": ">=0.50.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/react-native-web": {
 | 
					    "node_modules/react-native-web": {
 | 
				
			||||||
      "version": "0.19.11",
 | 
					      "version": "0.19.11",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.11.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.11.tgz",
 | 
				
			||||||
@@ -13091,6 +13316,20 @@
 | 
				
			|||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/recyclerlistview": {
 | 
				
			||||||
 | 
					      "version": "4.2.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/recyclerlistview/-/recyclerlistview-4.2.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-uuBCi0c+ggqHKwrzPX4Z/mJOzsBbjZEAwGGmlwpD/sD7raXixdAbdJ6BTcAmuWG50Cg4ru9p12M94Njwhr/27A==",
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "lodash.debounce": "4.0.8",
 | 
				
			||||||
 | 
					        "prop-types": "15.8.1",
 | 
				
			||||||
 | 
					        "ts-object-utils": "0.0.5"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "peerDependencies": {
 | 
				
			||||||
 | 
					        "react": ">= 15.2.1",
 | 
				
			||||||
 | 
					        "react-native": ">= 0.30.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/regenerate": {
 | 
					    "node_modules/regenerate": {
 | 
				
			||||||
      "version": "1.4.2",
 | 
					      "version": "1.4.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
 | 
				
			||||||
@@ -14337,6 +14576,11 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
 | 
				
			||||||
      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
 | 
					      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/ts-object-utils": {
 | 
				
			||||||
 | 
					      "version": "0.0.5",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/ts-object-utils/-/ts-object-utils-0.0.5.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-iV0GvHqOmilbIKJsfyfJY9/dNHCs969z3so90dQWsO1eMMozvTpnB1MEaUbb3FYtZTGjv5sIy/xmslEz0Rg2TA=="
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/tslib": {
 | 
					    "node_modules/tslib": {
 | 
				
			||||||
      "version": "2.6.2",
 | 
					      "version": "2.6.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,39 +1,43 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "deguapp",
 | 
						"name": "deguapp",
 | 
				
			||||||
  "version": "1.0.0",
 | 
						"version": "1.0.0",
 | 
				
			||||||
  "main": "expo-router/entry",
 | 
						"main": "expo-router/entry",
 | 
				
			||||||
  "scripts": {
 | 
						"scripts": {
 | 
				
			||||||
    "start": "expo start",
 | 
							"start": "expo start",
 | 
				
			||||||
    "android": "expo start --android",
 | 
							"android": "expo start --android",
 | 
				
			||||||
    "ios": "expo start --ios",
 | 
							"ios": "expo start --ios",
 | 
				
			||||||
    "web": "expo start --web"
 | 
							"web": "expo start --web",
 | 
				
			||||||
  },
 | 
							"build:web": "npx expo export",
 | 
				
			||||||
  "dependencies": {
 | 
							"format": "npx @biomejs/biome format --write ."
 | 
				
			||||||
    "@expo/metro-runtime": "~3.2.1",
 | 
						},
 | 
				
			||||||
    "@react-native-async-storage/async-storage": "^1.23.1",
 | 
						"dependencies": {
 | 
				
			||||||
    "@types/react": "~18.2.45",
 | 
							"@expo/metro-runtime": "~3.2.1",
 | 
				
			||||||
    "axios": "^1.6.8",
 | 
							"@react-native-async-storage/async-storage": "^1.23.1",
 | 
				
			||||||
    "expo": "^51.0.2",
 | 
							"@types/react": "~18.2.45",
 | 
				
			||||||
    "expo-constants": "~16.0.1",
 | 
							"axios": "^1.6.8",
 | 
				
			||||||
    "expo-image-picker": "~15.0.4",
 | 
							"expo": "^51.0.2",
 | 
				
			||||||
    "expo-linear-gradient": "~13.0.2",
 | 
							"expo-constants": "~16.0.1",
 | 
				
			||||||
    "expo-linking": "~6.3.1",
 | 
							"expo-image-picker": "~15.0.4",
 | 
				
			||||||
    "expo-router": "~3.5.11",
 | 
							"expo-linear-gradient": "~13.0.2",
 | 
				
			||||||
    "expo-secure-store": "~13.0.1",
 | 
							"expo-linking": "~6.3.1",
 | 
				
			||||||
    "expo-status-bar": "~1.12.1",
 | 
							"expo-router": "~3.5.11",
 | 
				
			||||||
    "expo-system-ui": "~3.0.4",
 | 
							"expo-secure-store": "~13.0.1",
 | 
				
			||||||
    "react": "18.2.0",
 | 
							"expo-status-bar": "~1.12.1",
 | 
				
			||||||
    "react-dom": "18.2.0",
 | 
							"expo-system-ui": "~3.0.4",
 | 
				
			||||||
    "react-native": "0.74.1",
 | 
							"react": "18.2.0",
 | 
				
			||||||
    "react-native-dropdown-picker": "^5.4.6",
 | 
							"react-dom": "18.2.0",
 | 
				
			||||||
    "react-native-safe-area-context": "4.10.1",
 | 
							"react-native": "0.74.1",
 | 
				
			||||||
    "react-native-screens": "3.31.1",
 | 
							"react-native-dropdown-picker": "^5.4.6",
 | 
				
			||||||
    "react-native-web": "~0.19.6"
 | 
							"react-native-range-slider-expo": "^1.4.3",
 | 
				
			||||||
  },
 | 
							"react-native-safe-area-context": "4.10.1",
 | 
				
			||||||
  "devDependencies": {
 | 
							"react-native-screens": "3.31.1",
 | 
				
			||||||
    "@babel/core": "^7.20.0",
 | 
							"react-native-web": "~0.19.6",
 | 
				
			||||||
    "@biomejs/biome": "1.7.3",
 | 
							"@shopify/flash-list": "1.6.4"
 | 
				
			||||||
    "babel-plugin-module-resolver": "^5.0.2"
 | 
						},
 | 
				
			||||||
  },
 | 
						"devDependencies": {
 | 
				
			||||||
  "private": true
 | 
							"@babel/core": "^7.20.0",
 | 
				
			||||||
 | 
							"@biomejs/biome": "1.7.3",
 | 
				
			||||||
 | 
							"babel-plugin-module-resolver": "^5.0.2"
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"private": true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||