diff --git a/.env b/.env new file mode 100644 index 000000000..235eceac7 --- /dev/null +++ b/.env @@ -0,0 +1,13 @@ +# Application Environment (development | preview | production) +EXPO_PUBLIC_APP_ENV=development + +# API Configuration +EXPO_PUBLIC_API_URL=https://dummyjson.com/ + +# Example Variables +EXPO_PUBLIC_VAR_NUMBER=10 +EXPO_PUBLIC_VAR_BOOL=true + +# Build-time only secrets (no EXPO_PUBLIC prefix - NOT accessible in src folder) +SECRET_KEY=my-secret-key +APP_BUILD_ONLY_VAR=build-only-value diff --git a/.github/actions/eas-build/action.yml b/.github/actions/eas-build/action.yml new file mode 100644 index 000000000..2db6e4d15 --- /dev/null +++ b/.github/actions/eas-build/action.yml @@ -0,0 +1,85 @@ +# ๐Ÿ”— Links: +# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/actions/eas-build/action.yml +# EAS Build docs: https://docs.expo.dev/eas-update/github-actions/ + +# โœ๏ธ Description: +# This is a composite action, which means it can be used in other actions. +# This action is used to trigger an EAS Build for a specific environment (development, staging, production). +# This action accepts those inputs: +# `APP_ENV`, which is used to generate an APK for a specific environment (development, staging, production). We use staging by default. +# `AUTO_SUBMIT`, false by default, set to true if you want to automatically submit your build to stores. +# `EXPO_TOKEN`, required, access token for your Expo account. https://expo.dev/settings/access-tokens +# `VERSION`, required, version of the app to build. used as the build message. +# `ANDROID`, true by default, set to true if you don't want to trigger build for Android. +# `IOS`, false by default, set to true if you want to trigger build for IOS. + +# Before triggering the build, we run a pre-build script to generate the necessary native folders based on the APP_ENV. +# Based on the ANDROID and IOS inputs, we trigger the build for the corresponding platform with the corresponding flags. + +# ๐Ÿ‘€ Example usage: +# - name: โฑ๏ธ EAS Build +# uses: ./.github/actions/eas-build +# with: +# APP_ENV: staging +# EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} +# VERSION: ${{ github.event.release.tag_name }} +# IOS: false + +name: 'Setup EAS Build + Trigger Build' +description: 'Setup EAS Build + Trigger Build' +inputs: + APP_ENV: + description: 'APP_ENV (one of): development, staging, production' + required: true + default: staging + AUTO_SUBMIT: # # TODO: we need to handle this too + description: 'AUTO_SUBMIT (one of): true, false' + required: true + default: 'false' + ANDROID: + description: 'run for ANDROID (one of): true, false' + required: true + default: 'true' + VERSION: + description: VERSION + required: true + default: 0.0.0 + IOS: + description: 'run for IOS (one of): true, false' + required: true + default: 'false' + EXPO_TOKEN: + description: EXPO_TOKEN + required: true + default: 'false' + +runs: + using: composite + steps: + - name: ๐Ÿ’ฏ Check for EXPO_TOKEN + run: | + if [ -z "${{ inputs.EXPO_TOKEN }}" ]; then + echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions" + exit 1 + fi + shell: bash + + - name: ๐Ÿ“ฆ Setup Expo and EAS + uses: expo/expo-github-action@v8 + with: + eas-version: latest + token: ${{ inputs.EXPO_TOKEN }} + + - name: โš™๏ธ Run Prebuild + run: pnpm prebuild:${{ inputs.APP_ENV }} + shell: bash + + - name: ๐Ÿ“ฑ Run Android Build + if: ${{ inputs.ANDROID == 'true' }} + run: pnpm build:${{ inputs.APP_ENV }}:android --non-interactive --no-wait --message "Build ${{ inputs.APP_ENV }} ${{ inputs.VERSION }}" + shell: bash + + - name: ๐Ÿ“ฑ Run IOS Build + if: ${{ inputs.IOS == 'true' }} + run: pnpm build:${{ inputs.APP_ENV }}:ios --non-interactive --no-wait --message "Build ${{ inputs.APP_ENV }} ${{ inputs.VERSION }}" + shell: bash diff --git a/.github/actions/setup-jdk-generate-apk/action.yml b/.github/actions/setup-jdk-generate-apk/action.yml index ab8a457f7..27d1dfa85 100644 --- a/.github/actions/setup-jdk-generate-apk/action.yml +++ b/.github/actions/setup-jdk-generate-apk/action.yml @@ -21,15 +21,15 @@ inputs: APP_ENV: description: 'APP_ENV (one of): development, staging, production' required: true - default: 'staging' + default: staging runs: - using: 'composite' + using: composite steps: - name: Set Up JDK uses: actions/setup-java@v3 with: - distribution: 'zulu' # See 'Supported distributions' for available options + distribution: zulu # See 'Supported distributions' for available options java-version: '17' - name: Setup Gradle uses: gradle/gradle-build-action@v2 diff --git a/.github/actions/setup-node-pnpm-install/action.yml b/.github/actions/setup-node-pnpm-install/action.yml index 92c402d41..679595b70 100644 --- a/.github/actions/setup-node-pnpm-install/action.yml +++ b/.github/actions/setup-node-pnpm-install/action.yml @@ -14,7 +14,7 @@ name: 'Setup Node + PNPM + Install Dependencies' description: 'Setup Node + PNPM + Install Dependencies' runs: - using: 'composite' + using: composite steps: - uses: pnpm/action-setup@v4 name: Install pnpm @@ -24,7 +24,7 @@ runs: name: Install Node.js with: node-version: 20 - cache: 'pnpm' + cache: pnpm - name: ๐Ÿ“ฆ Install Project Dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/e2e-android-eas-build.yml b/.github/workflows/e2e-android-eas-build.yml index 4dfd7e992..358d85f05 100644 --- a/.github/workflows/e2e-android-eas-build.yml +++ b/.github/workflows/e2e-android-eas-build.yml @@ -17,7 +17,7 @@ on: inputs: apk-url: type: string - description: 'EAS APK URL' + description: EAS APK URL required: true default: '' @@ -49,7 +49,7 @@ jobs: fetch-depth: 0 - name: ๐Ÿ“ฆ Install Maestro - run: npm run install-maestro ## We use npm because we don't need to install deps again + run: npm run install-maestro # # We use npm because we don't need to install deps again - name: Download Test APK uses: actions/download-artifact@v3 diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml index 7d1f8d6d0..be2073da6 100644 --- a/.github/workflows/e2e-android.yml +++ b/.github/workflows/e2e-android.yml @@ -57,7 +57,7 @@ jobs: fetch-depth: 0 - name: ๐Ÿ“ฆ Install Maestro - run: npm run install-maestro ## We use npm because we don't need to install deps again + run: npm run install-maestro # # We use npm because we don't need to install deps again - name: Download Test APK uses: actions/download-artifact@v3 diff --git a/.github/workflows/expo-doctor.yml b/.github/workflows/expo-doctor.yml index 60d64fd73..f202e8e5a 100644 --- a/.github/workflows/expo-doctor.yml +++ b/.github/workflows/expo-doctor.yml @@ -16,17 +16,17 @@ on: - main - master paths: - - 'package.json' - - 'pnpm-lock.yaml' + - package.json + - pnpm-lock.yaml pull_request: paths: - - 'package.json' - - 'pnpm-lock.yaml' + - package.json + - pnpm-lock.yaml permissions: contents: read pull-requests: write - + jobs: doctor: name: Expo Doctor (expo) diff --git a/.github/workflows/lint-ts.yml b/.github/workflows/lint-ts.yml index 07535c547..45c7271cf 100644 --- a/.github/workflows/lint-ts.yml +++ b/.github/workflows/lint-ts.yml @@ -21,7 +21,7 @@ on: permissions: contents: read pull-requests: write - + jobs: lint: name: Lint TS (eslint, prettier) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 3fbbdea6d..4bcf53efc 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,7 +7,7 @@ on: permissions: contents: read pull-requests: write - + jobs: stale: runs-on: ubuntu-latest @@ -16,9 +16,9 @@ jobs: - uses: actions/stale@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days' - stale-pr-message: 'This PR is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days' - stale-issue-label: 'no-issue-activity' - stale-pr-label: 'no-pr-activity' + stale-issue-message: This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days + stale-pr-message: This PR is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days + stale-issue-label: no-issue-activity + stale-pr-label: no-pr-activity days-before-stale: 60 days-before-close: 14 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 42cc78667..f2d90f0f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,7 +43,7 @@ jobs: if: (success() || failure()) && github.event_name == 'pull_request' with: coverage-summary-path: ./coverage/coverage-summary.json - summary-title: '๐Ÿ’ฏ Test Coverage' + summary-title: ๐Ÿ’ฏ Test Coverage badge-title: Coverage create-new-comment: false junitxml-title: ๐Ÿ˜Ž Tests Results diff --git a/.gitignore b/.gitignore index f8533c509..e7f5e50b6 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,8 @@ yarn-error.log # macOS .DS_Store +/ios +/android # artifacts *.apks diff --git a/.maestro/app/create-post.yaml b/.maestro/app/create-post.yaml index 89772e95d..f371f511e 100644 --- a/.maestro/app/create-post.yaml +++ b/.maestro/app/create-post.yaml @@ -1,6 +1,6 @@ appId: ${APP_ID} env: - Title: 'Post title' + Title: Post title CONTENT: "It is a long established fact that a reader will be distracted by the\ \ readable content of a page when looking at its layout. The point of using Lorem\ @@ -9,21 +9,21 @@ env: --- - launchApp - runFlow: ../utils/onboarding-and-login.yaml -- assertVisible: 'Feed' -- assertVisible: 'Create' -- tapOn: 'Create' -- assertVisible: 'Add Post' +- assertVisible: Feed +- assertVisible: Create +- tapOn: Create +- assertVisible: Add Post - tapOn: - id: 'title' + id: title - inputText: ${Title} - tapOn: - id: 'body-input' -- inputText: 'short content' + id: body-input +- inputText: short content - tapOn: - id: 'add-post-button' -- assertVisible: 'String must contain at least 120 character(s)' + id: add-post-button +- assertVisible: String must contain at least 120 character(s) - inputText: ${CONTENT} - runFlow: ../utils/hide-keyboard.yaml - tapOn: - id: 'add-post-button' -- assertVisible: 'Post added successfully' + id: add-post-button +- assertVisible: Post added successfully diff --git a/.maestro/app/tabs.yaml b/.maestro/app/tabs.yaml index 741d92fed..eaffdd98e 100644 --- a/.maestro/app/tabs.yaml +++ b/.maestro/app/tabs.yaml @@ -1,19 +1,19 @@ appId: ${APP_ID} env: - Name: 'User' - EMAIL: 'user@test.com' - PASSWORD: 'password' + Name: User + EMAIL: user@test.com + PASSWORD: password --- - launchApp - runFlow: ../utils/onboarding-and-login.yaml -- assertVisible: 'Feed' +- assertVisible: Feed - assertVisible: - id: 'style-tab' + id: style-tab - tapOn: - id: 'style-tab' -- assertVisible: 'Typography' + id: style-tab +- assertVisible: Typography - tapOn: - id: 'settings-tab' -- assertVisible: 'Settings' + id: settings-tab +- assertVisible: Settings - scroll -- assertVisible: 'Logout' +- assertVisible: Logout diff --git a/.maestro/auth/login-with-validation.yaml b/.maestro/auth/login-with-validation.yaml index a669e39b7..5cb1fdb69 100644 --- a/.maestro/auth/login-with-validation.yaml +++ b/.maestro/auth/login-with-validation.yaml @@ -1,35 +1,35 @@ appId: ${APP_ID} env: - Name: 'User' - EMAIL: 'user@test.com' - PASSWORD: 'password' + Name: User + EMAIL: user@test.com + PASSWORD: password --- - launchApp - runFlow: when: - visible: 'Obytes Starter' + visible: Obytes Starter file: ../utils/onboarding.yaml -- assertVisible: 'Sign In' +- assertVisible: Sign In - assertVisible: - id: 'login-button' + id: login-button - tapOn: - id: 'login-button' -- assertVisible: 'Email is required' -- assertVisible: 'Password is required' + id: login-button +- assertVisible: Email is required +- assertVisible: Password is required - tapOn: - id: 'name' + id: name - inputText: ${Name} - runFlow: ../utils/hide-keyboard.yaml - tapOn: - id: 'email-input' -- inputText: 'email' -- assertVisible: 'Invalid email format' + id: email-input +- inputText: email +- assertVisible: Invalid email format - inputText: ${EMAIL} - runFlow: ../utils/hide-keyboard.yaml - tapOn: - id: 'password-input' + id: password-input - inputText: ${PASSWORD} - runFlow: ../utils/hide-keyboard.yaml - tapOn: - id: 'login-button' -- assertVisible: 'Feed' + id: login-button +- assertVisible: Feed diff --git a/.maestro/auth/onboarding.yaml b/.maestro/auth/onboarding.yaml index b52203dfd..d3adc8e7b 100644 --- a/.maestro/auth/onboarding.yaml +++ b/.maestro/auth/onboarding.yaml @@ -2,7 +2,7 @@ appId: ${APP_ID} --- - clearState - launchApp -- assertVisible: "Obytes Starter" +- assertVisible: Obytes Starter - assertVisible: "Let's Get Started " - tapOn: "Let's Get Started " -- assertVisible: "Sign In" \ No newline at end of file +- assertVisible: Sign In diff --git a/.maestro/config.yaml b/.maestro/config.yaml index 6961b7e01..01923b3d0 100644 --- a/.maestro/config.yaml +++ b/.maestro/config.yaml @@ -6,7 +6,7 @@ excludeTags: - util executionOrder: - continueOnFailure: false # default is true - flowsOrder: - - onboarding - - login-with-validation \ No newline at end of file + continueOnFailure: false # default is true + flowsOrder: + - onboarding + - login-with-validation diff --git a/.maestro/utils/hide-keyboard-android.yaml b/.maestro/utils/hide-keyboard-android.yaml index 07025331e..b92bc02dd 100644 --- a/.maestro/utils/hide-keyboard-android.yaml +++ b/.maestro/utils/hide-keyboard-android.yaml @@ -2,4 +2,4 @@ appId: ${APP_ID} tags: - util --- -- hideKeyboard \ No newline at end of file +- hideKeyboard diff --git a/.maestro/utils/hide-keyboard-ios.yaml b/.maestro/utils/hide-keyboard-ios.yaml index f22dc286f..bcb47c3ed 100644 --- a/.maestro/utils/hide-keyboard-ios.yaml +++ b/.maestro/utils/hide-keyboard-ios.yaml @@ -3,4 +3,4 @@ tags: - util --- - tapOn: - id: "Return" # Keyboard Return \ No newline at end of file + id: Return # Keyboard Return diff --git a/.maestro/utils/hide-keyboard.yaml b/.maestro/utils/hide-keyboard.yaml index dfd1cf9a2..ca3323107 100644 --- a/.maestro/utils/hide-keyboard.yaml +++ b/.maestro/utils/hide-keyboard.yaml @@ -9,4 +9,4 @@ tags: - runFlow: when: platform: Android - file: ./hide-keyboard-android.yaml \ No newline at end of file + file: ./hide-keyboard-android.yaml diff --git a/.maestro/utils/login.yaml b/.maestro/utils/login.yaml index 6e2b32046..c2f03a36f 100644 --- a/.maestro/utils/login.yaml +++ b/.maestro/utils/login.yaml @@ -1,22 +1,22 @@ appId: ${APP_ID} env: - Name: "User" - EMAIL: "user@test.com" - PASSWORD: "password" + Name: User + EMAIL: user@test.com + PASSWORD: password tags: - util --- - tapOn: - id: "name" + id: name - inputText: ${Name} - tapOn: - id: "email-input" + id: email-input - inputText: ${EMAIL} - runFlow: ../utils/hide-keyboard.yaml - tapOn: - id: "password-input" + id: password-input - inputText: ${PASSWORD} - runFlow: ../utils/hide-keyboard.yaml - tapOn: - id: "login-button" -- assertVisible: "Typography" + id: login-button +- assertVisible: Typography diff --git a/.maestro/utils/onboarding-and-login.yaml b/.maestro/utils/onboarding-and-login.yaml index 707c945c1..190ede9ad 100644 --- a/.maestro/utils/onboarding-and-login.yaml +++ b/.maestro/utils/onboarding-and-login.yaml @@ -4,9 +4,9 @@ tags: --- - runFlow: when: - visible: "Obytes Starter" + visible: Obytes Starter file: onboarding.yaml - runFlow: when: visible: Sign In - file: login.yaml \ No newline at end of file + file: login.yaml diff --git a/.maestro/utils/onboarding.yaml b/.maestro/utils/onboarding.yaml index bb1b8937e..5562d77f2 100644 --- a/.maestro/utils/onboarding.yaml +++ b/.maestro/utils/onboarding.yaml @@ -2,7 +2,7 @@ appId: ${APP_ID} tags: - util --- -- assertVisible: 'Obytes Starter' +- assertVisible: Obytes Starter - assertVisible: "Let's Get Started " - tapOn: "Let's Get Started " -- assertVisible: 'Sign In' +- assertVisible: Sign In diff --git a/.vscode/settings.json b/.vscode/settings.json index 1120468a6..de8030428 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,9 +4,57 @@ "search.exclude": { "yarn.lock": true }, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, + + // Disable Prettier completely + "prettier.enable": false, + "editor.formatOnSave": false, + + // Enable ESLint auto-fix on save + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + + // Silence stylistic rules in IDE while still auto-fixing them + "eslint.rules.customizations": [ + { "rule": "style/*", "severity": "off", "fixable": true }, + { "rule": "format/*", "severity": "off", "fixable": true }, + { "rule": "*-indent", "severity": "off", "fixable": true }, + { "rule": "*-spacing", "severity": "off", "fixable": true }, + { "rule": "*-spaces", "severity": "off", "fixable": true }, + { "rule": "*-order", "severity": "off", "fixable": true }, + { "rule": "*-dangle", "severity": "off", "fixable": true }, + { "rule": "*-newline", "severity": "off", "fixable": true }, + { "rule": "*quotes", "severity": "off", "fixable": true }, + { "rule": "*semi", "severity": "off", "fixable": true } + ], + + // Enable ESLint for various file types + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "jsonc", + "yaml", + "toml", + "xml", + "gql", + "graphql", + "astro", + "css", + "less", + "scss", + "pcss", + "postcss" + ], + "typescript.tsdk": "node_modules/typescript/lib", +<<<<<<< HEAD "eslint.format.enable": true, "[javascript][typescript][typescriptreact]": { "editor.formatOnSave": true, @@ -25,6 +73,9 @@ "editor.defaultFormatter": "astro-build.astro-vscode" }, "cSpell.words": ["Flashlist", "Lato", "rootstrap"], +======= + "cSpell.words": ["Flashlist", "Lato"], +>>>>>>> f6309e9 "i18n-ally.localesPaths": ["src/translations/"], "i18n-ally.keystyle": "nested", "i18n-ally.disabled": false, // make sure to disable i18n-ally in your global setting and only enable it for such projects diff --git a/README.md b/README.md index a93fddb37..38fc5528a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,11 @@ ![expo](https://img.shields.io/github/package-json/dependency-version/rootstrap/react-native-template/expo?label=expo) ![react-native](https://img.shields.io/github/package-json/dependency-version/rootstrap/react-native-template/react-native?label=react-native) ![GitHub Repo stars](https://img.shields.io/github/stars/rootstrap/react-native-template) ![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/rootstrap/react-native-template) ![GitHub issues](https://img.shields.io/github/issues/rootstrap/react-native-template) ![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/rootstrap/react-native-template) +<<<<<<< HEAD ๐Ÿ“ฑ A template for your next React Native project ๐Ÿš€, Made with developer experience and performance first: Expo, TypeScript, NativeWind, Husky, Lint-Staged, expo-router, react-query, react-hook-form, I18n and preconfigured for EAS. +======= +๐Ÿ“ฑ A template for your next React Native project ๐Ÿš€, Made with developer experience and performance first: Expo, TypeScript, TailwindCSS, Husky, Lint-Staged, expo-router, react-query, TanStack Form, I18n. +>>>>>>> f6309e9 This repository is a fork of [Obytes Starter](https://github.com/obytes/react-native-template-obytes), which provides a solid foundation. We periodically sync with the original repo to stay up-to-date with their improvements, while making our own adjustments and optimizations to streamline our setup process. @@ -42,6 +46,7 @@ This template brings several key advantages. It provides our team with a consist ## โญ Key Features +<<<<<<< HEAD - ๐ŸŽ‰ [TypeScript](https://www.typescriptlang.org/) for type checking, to help you catch bugs and improve code quality. - ๐Ÿ’… A minimal UI kit built with [NativeWind](https://www.nativewind.dev/), which provides a range of pre-defined classes for styling your app. - โš™๏ธ Support for multiple environment builds, including Production, Staging, QA and Development, using Expo configuration. @@ -56,6 +61,24 @@ This template brings several key advantages. It provides our team with a consist - ๐Ÿงต A good approach for handling forms with [react-hook-form](https://react-hook-form.com/) and [zod](https://github.com/colinhacks/zod) for validation + keyboard handling. - ๐ŸŽฏ Localization with [i18next](https://www.i18next.com/), along with Eslint for validation. - Unit testing with [Jest](https://jestjs.io/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) setup to help you write tests for your app. +======= +- โœ… Latest Expo SDK with Custom Dev Client: Leverage the best of the Expo ecosystem while maintaining full control over your app. +- ๐ŸŽ‰ [TypeScript](https://www.typescriptlang.org/) for enhanced code quality and bug prevention through static type checking. +- ๐Ÿ’… Minimal UI kit built with [TailwindCSS](https://www.nativewind.dev/), featuring common components essential for your app. +- โš™๏ธ Multi-environment build support (Production, Staging, Development) using Expo configuration. +- ๐ŸฆŠ Husky for Git Hooks: Automate your git hooks and enforce code standards. +- ๐Ÿ’ก Clean project structure with Absolute Imports for easier code navigation and management. +- ๐Ÿšซ Lint-staged: Run Eslint and TypeScript checks on Git staged files to maintain code quality. +- ๐Ÿ—‚ VSCode recommended extensions, settings, and snippets for an enhanced developer experience. +- โ˜‚๏ธ Pre-installed [Expo Router](https://docs.expo.dev/router/introduction/) with examples for comprehensive app navigation. +- ๐Ÿ’ซ Auth flow implementation using [Zustand](https://github.com/pmndrs/zustand) for state management and [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) for secure data storage. +- ๐Ÿ›  10+ [Github Actions](https://github.com/features/actions) workflows for building, releasing, testing, and distributing your app. +- ๐Ÿ”ฅ [React Query](https://react-query.tanstack.com/) and [axios](https://github.com/axios/axios) for efficient data fetching and state management. +- ๐Ÿงต Robust form handling with [TanStack Form](https://tanstack.com/form/latest) and [zod](https://github.com/colinhacks/zod) for validation, plus keyboard handling. +- ๐ŸŽฏ Localization support with [i18next](https://www.i18next.com/), including Eslint for validation. +- ๐Ÿงช Unit testing setup with [Jest](https://jestjs.io/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/). +- ๐Ÿ” E2E testing capabilities with [Maestro](https://maestro.mobile.dev/) for comprehensive app testing. +>>>>>>> f6309e9 ## โœ๏ธ Documentation ๐Ÿšง UNDER CONSTRUCTION ๐Ÿšง @@ -102,7 +125,7 @@ Check this [file](https://github.com/rootstrap/rs-gpt-review/blob/main/.github/w - [Flash list](https://github.com/Shopify/flash-list) - [React Query](https://tanstack.com/query/v4) - [Axios](https://axios-http.com/docs/intro) -- [React Hook Form](https://react-hook-form.com/) +- [TanStack Form](https://tanstack.com/form/latest) - [i18next](https://www.i18next.com/) - [zustand](https://github.com/pmndrs/zustand) - [React Native MMKV](https://github.com/mrousavy/react-native-mmkv) diff --git a/__tests__/components/ui/button.test.tsx b/__tests__/components/ui/button.test.tsx index 236316d62..acc868303 100644 --- a/__tests__/components/ui/button.test.tsx +++ b/__tests__/components/ui/button.test.tsx @@ -1,4 +1,8 @@ +<<<<<<< HEAD:__tests__/components/ui/button.test.tsx /* eslint-disable max-lines-per-function */ +======= +import * as React from 'react'; +>>>>>>> f6309e9:src/components/ui/button.test.tsx import { Text } from 'react-native'; import { cleanup, render, screen, setup } from '@/lib/test-utils'; @@ -7,7 +11,7 @@ import { Button } from '../../../src/components/ui/button'; afterEach(cleanup); -describe('Button component ', () => { +describe('button component ', () => { it('should render correctly ', () => { render(