{"id":30701535,"url":"https://github.com/harshsahuu1234/reactnative_restateapp","last_synced_at":"2026-05-03T23:31:57.323Z","repository":{"id":312115249,"uuid":"1046377005","full_name":"HarshSahuu1234/ReactNative_RestateApp","owner":"HarshSahuu1234","description":"Built a full-stack Real Estate app from scratch with Google Authentication, dynamic routing, and more. Mastered essential skills for scalable and clean React Native development.","archived":false,"fork":false,"pushed_at":"2025-08-28T16:11:52.000Z","size":204,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-28T22:46:00.747Z","etag":null,"topics":["appwrite","appwrite-auth","nativewind","react-native","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HarshSahuu1234.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-28T15:42:13.000Z","updated_at":"2025-08-28T16:23:40.000Z","dependencies_parsed_at":"2025-08-28T22:46:06.415Z","dependency_job_id":"8a57ac5a-d6c9-4071-9dba-f4d023670102","html_url":"https://github.com/HarshSahuu1234/ReactNative_RestateApp","commit_stats":null,"previous_names":["harshsahuu1234/reactnative_restateapp"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/HarshSahuu1234/ReactNative_RestateApp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshSahuu1234%2FReactNative_RestateApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshSahuu1234%2FReactNative_RestateApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshSahuu1234%2FReactNative_RestateApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshSahuu1234%2FReactNative_RestateApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HarshSahuu1234","download_url":"https://codeload.github.com/HarshSahuu1234/ReactNative_RestateApp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshSahuu1234%2FReactNative_RestateApp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273295007,"owners_count":25079904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appwrite","appwrite-auth","nativewind","react-native","typescript"],"created_at":"2025-09-02T14:00:42.750Z","updated_at":"2026-05-03T23:31:57.294Z","avatar_url":"https://github.com/HarshSahuu1234.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Expo-black?style=for-the-badge\u0026logoColor=white\u0026logo=expo\u0026color=000020\" alt=\"expo\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-TypeScript-black?style=for-the-badge\u0026logoColor=white\u0026logo=typescript\u0026color=3178C6\" alt=\"typescript\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Appwrite-black?style=for-the-badge\u0026logoColor=white\u0026logo=appwrite\u0026color=FD366E\" alt=\"appwrite\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Tailwind_CSS-black?style=for-the-badge\u0026logoColor=white\u0026logo=tailwindcss\u0026color=06B6D4\" alt=\"tailwindcss\" /\u003e\n  \u003c/div\u003e\n\n  \u003ch3 align=\"center\"\u003eA Real Estate App\u003c/h3\u003e\n\n\u003c/div\u003e\n\n## 📋 \u003ca name=\"table\"\u003eTable of Contents\u003c/a\u003e\n\n1. 🤖 [Introduction](#introduction)\n2. ⚙️ [Tech Stack](#tech-stack)\n3. 🔋 [Features](#features)\n4. 🕸️ [Snippets](#snippets)\n5. 🔗 [Assets](#links)\n\n## \u003ca name=\"introduction\"\u003e🤖 Introduction\u003c/a\u003e\n\nBuild a full-stack Real Estate application with React Native, featuring Google authentication, dynamic property listings, and user profiles. Designed with modern tools like Expo SDK 52, Appwrite, Tailwind CSS, and TypeScript for a seamless and scalable experience.\n\n## \u003ca name=\"tech-stack\"\u003e⚙️ Tech Stack\u003c/a\u003e\n\n- **[Expo](https://expo.dev/)** is an open-source platform for building universal native apps (Android, iOS, web) using JavaScript/TypeScript and React Native. It features file-based routing via Expo Router, fast refresh, native modules for camera/maps/notifications, over-the-air updates (EAS), and streamlined app deployment.\n\n- **[React Native](https://reactnative.dev/)** is a framework for building mobile UIs with React. It enables component‑based, cross-platform development with declarative UI, deep native API support, and is tightly integrated with Expo for navigation and native capabilities.\n\n- **[Appwrite](https://jsm.dev/rn25-appwrite)** is an open-source backend-as-a-service platform offering secure authentication (email/password, OAuth, SMS, magic links), databases, file storage with compression/encryption, real-time messaging, serverless functions, and static site hosting via Appwrite Sites—all managed through a unified console and microservices architecture.\n\n- **[TypeScript](https://www.typescriptlang.org/)** is a statically-typed superset of JavaScript providing type annotations, interfaces, enums, generics, and enhanced tooling. It improves error detection, code quality, and scalability—ideal for robust, maintainable projects.\n\n- **[NativeWind](https://www.nativewind.dev/)** brings Tailwind CSS to React Native and Expo, allowing you to style mobile components using utility-first classes for fast, consistent, and responsive UI design.\n\n- **[Tailwind CSS](https://tailwindcss.com/)** is a utility-first CSS framework enabling rapid UI design via low-level classes. In React Native/Expo, it’s commonly used with NativeWind to apply Tailwind-style utilities to mobile components.\n\n## \u003ca name=\"features\"\u003e🔋 Features\u003c/a\u003e\n\n👉 **Authentication with Google**: Secure and seamless user sign-ins using Google’s authentication service.\n\n👉 **Home Page**: Displays the latest and recommended properties with powerful search and filter functionality.\n\n👉 **Explore Page**: Allows users to browse all types of properties with a clean and intuitive interface.\n\n👉 **Property Details Page**: Provides comprehensive information about individual properties, including images and key details.\n\n👉 **Profile Page**: Customizable user settings and profile management\n\n👉 **Centralized Data Fetching**: Custom-built solution inspired by TanStack’s useQuery for efficient API calls.\n\nand many more, including code architecture and reusability \n\n**Prerequisites**\n\nMake sure you have the following installed on your machine:\n\n- [Git](https://git-scm.com/)\n- [Node.js](https://nodejs.org/en)\n- [npm](https://www.npmjs.com/) (Node Package Manager)\n\n**Cloning the Repository**\n\n```bash\ngit clone https://github.com/adrianhajdin/react_native-restate.git\ncd react_native-restate\n```\n\n**Installation** \n\n```bash\nnpm install\n```\n\n**Set Up Environment Variables**\n\nCreate a new file named `.env.local` in the root of your project and add the following content:\n\n```env\nEXPO_PUBLIC_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1\nEXPO_PUBLIC_APPWRITE_PROJECT_ID=\nEXPO_PUBLIC_APPWRITE_DATABASE_ID=\nEXPO_PUBLIC_APPWRITE_GALLERIES_COLLECTION_ID=\nEXPO_PUBLIC_APPWRITE_REVIEWS_COLLECTION_ID=\nEXPO_PUBLIC_APPWRITE_AGENTS_COLLECTION_ID=\nEXPO_PUBLIC_APPWRITE_PROPERTIES_COLLECTION_ID=\n```\n\nReplace the values with your actual Appwrite credentials. You can obtain these credentials by signing up \u0026 creating a new project on the [**Appwrite Dashboard**](https://jsm.dev/rn25-appwrite).\n\n**Start the app**\n   \n```bash\n npx expo start\n```\n\nIn the output, you'll find options to open the app in a\n\n- [development build](https://docs.expo.dev/develop/development-builds/introduction/)\n- [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)\n- [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)\n- [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo\n\nYou can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).\n\n## \u003ca name=\"snippets\"\u003e🕸️ Snippets\u003c/a\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003elib/data.ts\u003c/code\u003e\u003c/summary\u003e\n\n```ts\nexport const galleryImages = [\n  \"https://images.unsplash.com/photo-1507089947368-19c1da9775ae?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://unsplash.com/photos/comfort-room-with-white-bathtub-and-brown-wooden-cabinets-CMejBwGAdGk\",\n  \"https://images.unsplash.com/photo-1638799869566-b17fa794c4de?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1560185009-dddeb820c7b7?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1641910532059-ad684fd3049c?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1621293954908-907159247fc8?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1604328702728-d26d2062c20b?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1600435335786-d74d2bb6de37?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1560448204-603b3fc33ddc?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1635108198979-9806fdf275c6?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n];\n\nexport const agentImages = [\n  \"https://images.unsplash.com/photo-1691335053879-02096d6ee2ca?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1544723495-432537d12f6c?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1492562080023-ab3db95bfbce?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1542507464418-09c375b86bbe?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1534308143481-c55f00be8bd7?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n];\n\nexport const reviewImages = [\n  \"https://images.unsplash.com/photo-1517331671191-ddc2c6d3ebd1?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1474176857210-7287d38d27c6?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1511551203524-9a24350a5771?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1507591064344-4c6ce005b128?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1438761681033-6461ffad8d80?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n];\n\nexport const propertiesImages = [\n  \"https://images.unsplash.com/photo-1580587771525-78b9dba3b914?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1605146768851-eda79da39897?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1568605114967-8130f3a36994?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1564013799919-ab600027ffc6?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1561753757-d8880c5a3551?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1551241090-67de81d3541c?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1697299262049-e9b5fa1e9761?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1719299225324-301bad5c333c?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1582063289852-62e3ba2747f8?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1516095901529-0ef7be431a4f?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1600585153490-76fb20a32601?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1605276373954-0c4a0dac5b12?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1583608205776-bfd35f0d9f83?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n  \"https://images.unsplash.com/photo-1720432972486-2d53db5badf0?q=60\u0026w=640\u0026auto=format\u0026fit=crop\u0026ixlib=rb-4.0.3\u0026ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D\",\n];\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003elib/seed.ts\u003c/code\u003e\u003c/summary\u003e\n\n```ts\nimport { ID } from \"react-native-appwrite\";\nimport { databases, config } from \"./appwrite\";\nimport {\n  agentImages,\n  galleryImages,\n  propertiesImages,\n  reviewImages,\n} from \"./data\";\n\nconst COLLECTIONS = {\n  AGENT: config.agentsCollectionId,\n  REVIEWS: config.reviewsCollectionId,\n  GALLERY: config.galleriesCollectionId,\n  PROPERTY: config.propertiesCollectionId,\n};\n\nconst propertyTypes = [\n  \"House\",\n  \"Townhomes\",\n  \"Condos\",\n  \"Duplexes\",\n  \"Studios\",\n  \"Villa\",\n  \"Apartments\",\n  \"Others\",\n];\n\nconst facilities = [\n  \"Laundry\",\n  \"Car Parking\",\n  \"Sports Center\",\n  \"Cutlery\",\n  \"Gym\",\n  \"Swimming pool\",\n  \"Wifi\",\n  \"Pet Center\",\n];\n\nfunction getRandomSubset\u003cT\u003e(\n  array: T[],\n  minItems: number,\n  maxItems: number\n): T[] {\n  if (minItems \u003e maxItems) {\n    throw new Error(\"minItems cannot be greater than maxItems\");\n  }\n  if (minItems \u003c 0 || maxItems \u003e array.length) {\n    throw new Error(\n      \"minItems or maxItems are out of valid range for the array\"\n    );\n  }\n\n  // Generate a random size for the subset within the range [minItems, maxItems]\n  const subsetSize =\n    Math.floor(Math.random() * (maxItems - minItems + 1)) + minItems;\n\n  // Create a copy of the array to avoid modifying the original\n  const arrayCopy = [...array];\n\n  // Shuffle the array copy using Fisher-Yates algorithm\n  for (let i = arrayCopy.length - 1; i \u003e 0; i--) {\n    const randomIndex = Math.floor(Math.random() * (i + 1));\n    [arrayCopy[i], arrayCopy[randomIndex]] = [\n      arrayCopy[randomIndex],\n      arrayCopy[i],\n    ];\n  }\n\n  // Return the first `subsetSize` elements of the shuffled array\n  return arrayCopy.slice(0, subsetSize);\n}\n\nasync function seed() {\n  try {\n    // Clear existing data from all collections\n    for (const key in COLLECTIONS) {\n      const collectionId = COLLECTIONS[key as keyof typeof COLLECTIONS];\n      const documents = await databases.listDocuments(\n        config.databaseId!,\n        collectionId!\n      );\n      for (const doc of documents.documents) {\n        await databases.deleteDocument(\n          config.databaseId!,\n          collectionId!,\n          doc.$id\n        );\n      }\n    }\n\n    console.log(\"Cleared all existing data.\");\n\n    // Seed Agents\n    const agents = [];\n    for (let i = 1; i \u003c= 5; i++) {\n      const agent = await databases.createDocument(\n        config.databaseId!,\n        COLLECTIONS.AGENT!,\n        ID.unique(),\n        {\n          name: `Agent ${i}`,\n          email: `agent${i}@example.com`,\n          avatar: agentImages[Math.floor(Math.random() * agentImages.length)],\n        }\n      );\n      agents.push(agent);\n    }\n    console.log(`Seeded ${agents.length} agents.`);\n\n    // Seed Reviews\n    const reviews = [];\n    for (let i = 1; i \u003c= 20; i++) {\n      const review = await databases.createDocument(\n        config.databaseId!,\n        COLLECTIONS.REVIEWS!,\n        ID.unique(),\n        {\n          name: `Reviewer ${i}`,\n          avatar: reviewImages[Math.floor(Math.random() * reviewImages.length)],\n          review: `This is a review by Reviewer ${i}.`,\n          rating: Math.floor(Math.random() * 5) + 1, // Rating between 1 and 5\n        }\n      );\n      reviews.push(review);\n    }\n    console.log(`Seeded ${reviews.length} reviews.`);\n\n    // Seed Galleries\n    const galleries = [];\n    for (const image of galleryImages) {\n      const gallery = await databases.createDocument(\n        config.databaseId!,\n        COLLECTIONS.GALLERY!,\n        ID.unique(),\n        { image }\n      );\n      galleries.push(gallery);\n    }\n\n    console.log(`Seeded ${galleries.length} galleries.`);\n\n    // Seed Properties\n    for (let i = 1; i \u003c= 20; i++) {\n      const assignedAgent = agents[Math.floor(Math.random() * agents.length)];\n\n      const assignedReviews = getRandomSubset(reviews, 5, 7); // 5 to 7 reviews\n      const assignedGalleries = getRandomSubset(galleries, 3, 8); // 3 to 8 galleries\n\n      const selectedFacilities = facilities\n        .sort(() =\u003e 0.5 - Math.random())\n        .slice(0, Math.floor(Math.random() * facilities.length) + 1);\n\n      const image =\n        propertiesImages.length - 1 \u003e= i\n          ? propertiesImages[i]\n          : propertiesImages[\n              Math.floor(Math.random() * propertiesImages.length)\n            ];\n\n      const property = await databases.createDocument(\n        config.databaseId!,\n        COLLECTIONS.PROPERTY!,\n        ID.unique(),\n        {\n          name: `Property ${i}`,\n          type: propertyTypes[Math.floor(Math.random() * propertyTypes.length)],\n          description: `This is the description for Property ${i}.`,\n          address: `123 Property Street, City ${i}`,\n          geolocation: `192.168.1.${i}, 192.168.1.${i}`,\n          price: Math.floor(Math.random() * 9000) + 1000,\n          area: Math.floor(Math.random() * 3000) + 500,\n          bedrooms: Math.floor(Math.random() * 5) + 1,\n          bathrooms: Math.floor(Math.random() * 5) + 1,\n          rating: Math.floor(Math.random() * 5) + 1,\n          facilities: selectedFacilities,\n          image: image,\n          agent: assignedAgent.$id,\n          reviews: assignedReviews.map((review) =\u003e review.$id),\n          gallery: assignedGalleries.map((gallery) =\u003e gallery.$id),\n        }\n      );\n\n      console.log(`Seeded property: ${property.name}`);\n    }\n\n    console.log(\"Data seeding completed.\");\n  } catch (error) {\n    console.error(\"Error seeding data:\", error);\n  }\n}\n\nexport default seed;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003elib/useAppwrite.ts\u003c/code\u003e\u003c/summary\u003e\n\n```ts\nimport { Alert } from \"react-native\";\nimport { useEffect, useState, useCallback } from \"react\";\n\ninterface UseAppwriteOptions\u003cT, P extends Record\u003cstring, string | number\u003e\u003e {\n  fn: (params: P) =\u003e Promise\u003cT\u003e;\n  params?: P;\n  skip?: boolean;\n}\n\ninterface UseAppwriteReturn\u003cT, P\u003e {\n  data: T | null;\n  loading: boolean;\n  error: string | null;\n  refetch: (newParams: P) =\u003e Promise\u003cvoid\u003e;\n}\n\nexport const useAppwrite = \u003cT, P extends Record\u003cstring, string | number\u003e\u003e({\n  fn,\n  params = {} as P,\n  skip = false,\n}: UseAppwriteOptions\u003cT, P\u003e): UseAppwriteReturn\u003cT, P\u003e =\u003e {\n  const [data, setData] = useState\u003cT | null\u003e(null);\n  const [loading, setLoading] = useState(!skip);\n  const [error, setError] = useState\u003cstring | null\u003e(null);\n\n  const fetchData = useCallback(\n    async (fetchParams: P) =\u003e {\n      setLoading(true);\n      setError(null);\n\n      try {\n        const result = await fn(fetchParams);\n        setData(result);\n      } catch (err: unknown) {\n        const errorMessage =\n          err instanceof Error ? err.message : \"An unknown error occurred\";\n        setError(errorMessage);\n        Alert.alert(\"Error\", errorMessage);\n      } finally {\n        setLoading(false);\n      }\n    },\n    [fn]\n  );\n\n  useEffect(() =\u003e {\n    if (!skip) {\n      fetchData(params);\n    }\n  }, []);\n\n  const refetch = async (newParams: P) =\u003e await fetchData(newParams);\n\n  return { data, loading, error, refetch };\n};\n```\n\n\u003c/details\u003e\n\n## \u003ca name=\"links\"\u003e🔗 Assets\u003c/a\u003e\n\nAssets and snippets used in the project can be found in the **[video kit](https://jsm.dev/rn25-restate)**.\n\nAppwrite Database Setup can be found [here](https://jsmastery.notion.site/Database-Setup-16260f3cbaf3807f8fb6cbed8d1e84fd)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharshsahuu1234%2Freactnative_restateapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharshsahuu1234%2Freactnative_restateapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharshsahuu1234%2Freactnative_restateapp/lists"}