diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 71e127dce80a1a1cd1128f23dfd55924b85cdf76..0000000000000000000000000000000000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,13 +0,0 @@ -# Summary: - -## Steps to reproduce: - -## Expected behavior: - -## Additional notes: - -#### Tasks - -- [ ] Task 1 -- [ ] Task 2 -- [ ] Task 3 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 8f3fb4fc96b7939364c6c5ef46e695830d680810..0000000000000000000000000000000000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,23 +0,0 @@ -## What does this do? - - - -## Why did you do this? - - - -## Who/what does this impact? - - - -## How did you test this? - - diff --git a/.github/actions/eas-build/action.yml b/.github/actions/eas-build/action.yml deleted file mode 100644 index 3a9be920d67f8c1269cd77270259727f4ae33a4b..0000000000000000000000000000000000000000 --- a/.github/actions/eas-build/action.yml +++ /dev/null @@ -1,85 +0,0 @@ -# 🔗 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 deleted file mode 100644 index 0aaa26d7cac547cc05bf198a543acc0c4e9ae72e..0000000000000000000000000000000000000000 --- a/.github/actions/setup-jdk-generate-apk/action.yml +++ /dev/null @@ -1,48 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/actions/setup-jdk-generate-apk/action.yml -# Composite actions docs: https://docs.github.com/en/actions/creating-actions/creating-a-composite-action - -# ✍️ Description: -# This is a composite action, which means it can be used in other actions. -# This action is used to set up the JDK environment and generate an Android APK for testing. -# This action accepts one input: `APP_ENV`, which is used to generate an APK for a specific environment (development, staging, production). We use staging by default. -# Before generating the APK, we run a pre-build script to generate the necessary native folders based on the APP_ENV. -# On success, the APK is generated at `./android/app/build/outputs/apk/release/app-release.apk`. - -# 👀 Example usage: -# - name : 📦 Set Up JDK + Generate Test APK -# uses: ./.github/actions/setup-jdk-generate-apk -# with: -# APP_ENV: 'staging' - -name: 'Setup JDK + GRADLE + Generate APK' -description: 'Setup JDK + GRADLE + Generate APK' -inputs: - APP_ENV: - description: 'APP_ENV (one of): development, staging, production' - required: true - default: 'staging' - -runs: - using: 'composite' - steps: - - name: Set Up JDK - uses: actions/setup-java@v3 - with: - distribution: 'zulu' # See 'Supported distributions' for available options - java-version: '17' - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 - - - name: Generate Test APK - run: | - pnpm prebuild:${{ inputs.APP_ENV }} - cd android - chmod +x ./gradlew - ./gradlew assembleRelease --no-daemon - cd .. - shell: bash - env: - EXPO_NO_DOTENV: '1' - APP_ENV: ${{ inputs.APP_ENV }} - CI: 'true' diff --git a/.github/actions/setup-node-pnpm-install/action.yml b/.github/actions/setup-node-pnpm-install/action.yml deleted file mode 100644 index 7026bda74d718127b8d181a8d7cd2c65a2f8daad..0000000000000000000000000000000000000000 --- a/.github/actions/setup-node-pnpm-install/action.yml +++ /dev/null @@ -1,29 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/actions/setup-node-pnpm-install/action.yml -# Composite actions docs: https://docs.github.com/en/actions/creating-actions/creating-a-composite-action - -# ✍️ Description: -# This is a composite action, which means it can be used in other actions. -# It is used in almost all workflows to set up the environment and install dependencies. -# Updating the package manager or Node version here will be reflected in all workflows. - -# 👀 Example usage: -# - name : 📦 Setup Node + PNPM + install deps -# uses: ./.github/actions/setup-node-pnpm-install - -name: 'Setup Node + PNPM + Install Dependencies' -description: 'Setup Node + PNPM + Install Dependencies' -runs: - using: 'composite' - steps: - - uses: pnpm/action-setup@v4 - with: - run_install: false - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'pnpm' - - - name: 📦 Install Project Dependencies - run: pnpm install --frozen-lockfile - shell: bash diff --git a/.github/scripts/expo-doctor.sh b/.github/scripts/expo-doctor.sh deleted file mode 100644 index 507bad7db41e1521693fce46b766d94b186f4486..0000000000000000000000000000000000000000 --- a/.github/scripts/expo-doctor.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Run expo-doctor and capture output and exit code -output=$(npx expo-doctor@latest 2>&1) -exit_code=$? - -# Output file location -output_file=".expo/expo-doctor.md" -{ - # Add summary based on exit code - if [ $exit_code -eq 0 ]; then - echo "✅ **Good news!** We ran Expo Doctor for this PR and everything looks good, Great job!" > "$output_file" - else - echo "❌ **Action Required:** We ran Expo Doctor for this PR and found some issues that need to be addressed. Please review the complete report below 👇" > "$output_file" - echo >> "$output_file" # Add blank line - echo "\`\`\`shell" >> "$output_file" - echo "$output" >> "$output_file" - echo "\`\`\`" >> "$output_file" - fi -} - -# Show original output in terminal -echo "$output" - -# Return the original exit code -exit $exit_code diff --git a/.github/workflows/compress-images.yml b/.github/workflows/compress-images.yml deleted file mode 100644 index dab3998f69b968a8f0e86b74f40f5b205a0887bb..0000000000000000000000000000000000000000 --- a/.github/workflows/compress-images.yml +++ /dev/null @@ -1,48 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/compress-images.yml - -# ✍️ Description: -# This workflow is used to compress images in the repo. -# This workflow will trigger on a push to the "master" or "main" branch and only run when a new image is added or updated. -# If it's the case, it will compress those images and create a pull request with the compressed images. - -# 🚨 GITHUB SECRETS REQUIRED: None - -name: Compress images -on: - push: - branches: - - master - - main - paths: - - '**.jpg' - - '**.jpeg' - - '**.png' - - '**.webp' - workflow_dispatch: - -jobs: - build: - name: calibreapp/image-actions - runs-on: ubuntu-latest - steps: - - name: Checkout Branch - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Compress Images - id: calibre - uses: calibreapp/image-actions@main - with: - githubToken: ${{ secrets.GITHUB_TOKEN }} - compressOnly: true - ignorePaths: 'node_modules/**,ios/**,android/**' - - - name: Create Pull Request - if: steps.calibre.outputs.markdown != '' - uses: peter-evans/create-pull-request@v3 - with: - title: Auto Compress Images - branch-suffix: timestamp - commit-message: Compress Images - body: ${{ steps.calibre.outputs.markdown }} diff --git a/.github/workflows/e2e-android-eas-build.yml b/.github/workflows/e2e-android-eas-build.yml deleted file mode 100644 index 645b8d9868dfd8f4297afc4b3a596d7d37e4f4cb..0000000000000000000000000000000000000000 --- a/.github/workflows/e2e-android-eas-build.yml +++ /dev/null @@ -1,111 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/e2e-android-eas-build.yml -# End-to-end testing: https://starter.obytes.com/testing/end-to-end-testing/ - -# ✍️ Description: -# This workflow is used to run end-to-end tests for EAS build on Android. -# It uses Maestro Cloud to run tests on Android emulator. -# It downloads the APK from EAS build and triggers the tests on Maestro Cloud with the downloaded APK. - -# 🚨 GITHUB SECRETS REQUIRED: -# MAESTRO_CLOUD_API_KEY: API key for Maestro Cloud. You can get it from https://cloud.mobile.dev/ci-integration/github-actions#add-your-api-key-secret - -name: E2E Tests EAS Build Android (Maestro + Github Action) - -on: - workflow_dispatch: - inputs: - apk-url: - type: string - description: 'EAS APK URL' - required: true - default: '' - -jobs: - download-eas-apk: - if: github.event_name != 'pull_request' && github.event.inputs.apk-url != '' - name: Download Test APK From EAS Url (wget) - runs-on: ubuntu-latest - - steps: - - name: 📦 Download EAS APK - run: wget ${{ github.event.inputs.apk-url }} -O ./app-release.apk - - - name: Upload Test APK - uses: actions/upload-artifact@v3 - with: - name: test-apk - path: ./app-release.apk - - test-android: - name: E2E Tests EAS Build Android (Maestro + Github Action) - needs: download-eas-apk - runs-on: macOS-latest - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Install Maestro - 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 - with: - name: test-apk - path: ${{ github.workspace }} - - - name: Gradle cache - uses: gradle/gradle-build-action@v2 - - - name: AVD cache - uses: actions/cache@v3 - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: avd-cache - - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 29 - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - cores: 2 - ram-size: 4096M - profile: Nexus 6 - script: echo "Generated AVD snapshot for caching." - - - name: Run tests with Maestro - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 29 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - cores: 2 - ram-size: 4096M - profile: Nexus 6 - script: | - adb install "${{ github.workspace }}/app-release.apk" - $HOME/.maestro/bin/maestro test .maestro/ --env=APP_ID=com.obytes.staging --format junit - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v3 - with: - name: e2e-test-logs - path: ~/.maestro/tests/**/* - - - name: Store tests result - uses: actions/upload-artifact@v3 - with: - name: e2e_android_report - path: | - report.xml diff --git a/.github/workflows/e2e-android-maestro.yml b/.github/workflows/e2e-android-maestro.yml deleted file mode 100644 index 605a68cb1b4590c396268d64a30dbd7bf531867b..0000000000000000000000000000000000000000 --- a/.github/workflows/e2e-android-maestro.yml +++ /dev/null @@ -1,52 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/e2e-android.yml -# End-to-end testing: https://starter.obytes.com/testing/end-to-end-testing/ - -# ✍️ Description: -# This workflow is used to run end-to-end tests on Android using Maestro Cloud. -# As a first step, it will generate a test APK using the Gradle build and then trigger Maestro Cloud to run the tests on the generated APK. -# This workflow will be triggered on pull requests (PRs) with the label "android-test-maestro-cloud" or can be manually triggered from the Actions tab. - -# 🚨 GITHUB SECRETS REQUIRED: -# MAESTRO_CLOUD_API_KEY: API key for Maestro Cloud. You can get it from https://cloud.mobile.dev/ci-integration/github-actions#add-your-api-key-secret - -name: E2E Tests Android (Maestro Cloud) - -on: - workflow_dispatch: - pull_request: - branches: [main, master] - -jobs: - generate-and-test-apk: - if: github.event_name != 'pull_request' || ( github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'android-test-maestro-cloud')) - name: Generate and Test Test APK (Maestro Cloud) - runs-on: ubuntu-latest - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: 📦 Set Up JDK + Generate Test APK - uses: ./.github/actions/setup-jdk-generate-apk - with: - APP_ENV: staging - - - name: Upload Test APK - uses: actions/upload-artifact@v3 - with: - name: test-apk - path: ./android/app/build/outputs/apk/release/app-release.apk - - - name: 📱 Run E2E Tests with Maestro Cloud - uses: mobile-dev-inc/action-maestro-cloud@v1.4.1 - with: - api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }} - app-file: ./android/app/build/outputs/apk/release/app-release.apk - env: | - APP_ID=com.obytes.staging diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml deleted file mode 100644 index 11a830eb5775e36947e43be52b535324eb190d4d..0000000000000000000000000000000000000000 --- a/.github/workflows/e2e-android.yml +++ /dev/null @@ -1,119 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/e2e-android.yml -# End-to-end testing: https://starter.obytes.com/testing/end-to-end-testing/ - -# ✍️ Description: -# This workflow is used to run end-to-end tests on Android using Maestro. -# As a first step, it will generate a test APK using the Gradle build and then upload it as an artifact. -# A new job will be started to run the tests using the test APK generated in the previous job. -# To test the app, we set up an Android emulator using the `reactivecircus/android-emulator-runner` action. This runner requires macOS as the operating system for the runner. -# This workflow will be triggered on pull requests (PRs) with the label "android-test-github" or can be manually triggered from the Actions tab. -# - -# 🚨 GITHUB SECRETS REQUIRED: None - -name: E2E Tests Android (Maestro + Github Action) - -on: - workflow_dispatch: - pull_request: - branches: [main, master] - -jobs: - generate-test-apk: - if: github.event_name != 'pull_request' || ( github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'android-test-github')) - name: Generate Test APK (Gradle) - runs-on: ubuntu-latest - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: 📦 Set Up JDK + Generate Test APK - uses: ./.github/actions/setup-jdk-generate-apk - with: - APP_ENV: staging - - - name: Upload Test APK - uses: actions/upload-artifact@v3 - with: - name: test-apk - path: ./android/app/build/outputs/apk/release/app-release.apk - - test-android: - name: Run Android E2E Tests (Maestro + Github Action) - needs: generate-test-apk - runs-on: macOS-latest - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Install Maestro - 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 - with: - name: test-apk - path: ${{ github.workspace }} - - - name: Gradle cache - uses: gradle/gradle-build-action@v2 - - - name: AVD cache - uses: actions/cache@v3 - id: avd-cache - with: - path: | - ~/.android/avd/* - ~/.android/adb* - key: avd-cache - - - name: create AVD and generate snapshot for caching - if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 29 - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - cores: 2 - ram-size: 4096M - profile: Nexus 6 - script: echo "Generated AVD snapshot for caching." - - - name: Run tests with Maestro - uses: reactivecircus/android-emulator-runner@v2 - with: - api-level: 29 - force-avd-creation: false - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - disable-animations: false - cores: 2 - ram-size: 4096M - profile: Nexus 6 - script: | - adb install "${{ github.workspace }}/app-release.apk" - $HOME/.maestro/bin/maestro test .maestro/ --env=APP_ID=com.obytes.staging --format junit - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v3 - with: - name: e2e-test-logs - path: ~/.maestro/tests/**/* - - - name: Store tests result - uses: actions/upload-artifact@v3 - with: - name: e2e_android_report - path: | - report.xml diff --git a/.github/workflows/eas-build-prod.yml b/.github/workflows/eas-build-prod.yml deleted file mode 100644 index a850bf45eb827f7582e8f6523a28f9dc52198713..0000000000000000000000000000000000000000 --- a/.github/workflows/eas-build-prod.yml +++ /dev/null @@ -1,43 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/eas-build-prod.yml -# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ - -# ✍️ Description: -# This workflow is used to trigger a build on EAS for Prod environment. -# Can be triggered manually from the actions tab. -# This workflow will use ./actions/eas-build action to trigger the build on EAS with production env. - -# 🚨 GITHUB SECRETS REQUIRED: -# - EXPO_TOKEN: Expo token to authenticate with EAS -# - You can get it from https://expo.dev/settings/access-tokens - -name: EAS Production Build (Android & IOS) (EAS) - -on: - workflow_dispatch: - -jobs: - Build: - name: EAS Production Build (Android & IOS) (EAS) - runs-on: ubuntu-latest - steps: - - name: Check for EXPO_TOKEN - run: | - if [ -z "${{ secrets.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 - - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: ⏱️ EAS Build - uses: ./.github/actions/eas-build - with: - APP_ENV: production - EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} diff --git a/.github/workflows/eas-build-qa.yml b/.github/workflows/eas-build-qa.yml deleted file mode 100644 index 7cc4a853d44511854c806cdce253ce25501fc4ff..0000000000000000000000000000000000000000 --- a/.github/workflows/eas-build-qa.yml +++ /dev/null @@ -1,47 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/eas-build-qa.yml -# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ - -# ✍️ Description: -# This workflow is used to trigger a build on EAS for the QA environment. -# It will run on every GitHub release published on the repo or can be triggered manually from the actions tab. -# This workflow will use ./actions/eas-build action to trigger the build on EAS with staging env. - -# 🚨 GITHUB SECRETS REQUIRED: -# - EXPO_TOKEN: Expo token to authenticate with EAS -# - You can get it from https://expo.dev/settings/access-tokens - -name: EAS QA Build (Android & IOS) (EAS) - -on: - workflow_dispatch: - release: - types: [published] - -jobs: - Build: - name: EAS QA Build (Android & IOS) (EAS) - runs-on: ubuntu-latest - steps: - - name: Check for EXPO_TOKEN - run: | - if [ -z "${{ secrets.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 - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - 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 # TODO: set as true when IOS account is ready - diff --git a/.github/workflows/expo-doctor.yml b/.github/workflows/expo-doctor.yml deleted file mode 100644 index 6c7763ef3586d8a98b43995004b21708e8b0aea0..0000000000000000000000000000000000000000 --- a/.github/workflows/expo-doctor.yml +++ /dev/null @@ -1,61 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/expo-doctor.yml - -# ✍️ Description: -# This workflow runs the expo doctor command to check if your project dependencies are aligned with the expo sdk version you are using. -# Can be triggered manually from the Actions tab in your project. -# Runs Also on pull requests and pushes to the main/master branch, but only if the `package.json` or `pnpm-lock.yaml` files have been changed. - -# 🚨 GITHUB SECRETS REQUIRED: NONE - -name: Expo Doctor (expo) - -on: - push: - branches: - - main - - master - paths: - - 'package.json' - - 'pnpm-lock.yaml' - pull_request: - paths: - - 'package.json' - - 'pnpm-lock.yaml' - -permissions: - contents: read - pull-requests: write - -jobs: - doctor: - name: Expo Doctor (expo) - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: Run prebuild - run: pnpm run prebuild - - - name: 🚑 Run Doctor Checks - run: | - chmod +x .github/scripts/expo-doctor.sh - rm -rf ios android - .github/scripts/expo-doctor.sh - - - name: Add doctor report as comment on PR - if: github.event_name == 'pull_request' && always() - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: expo-doctor - path: .expo/expo-doctor.md diff --git a/.github/workflows/lint-ts.yml b/.github/workflows/lint-ts.yml deleted file mode 100644 index d22b3d207421a1951f53937ce0ff7c897b6e2a25..0000000000000000000000000000000000000000 --- a/.github/workflows/lint-ts.yml +++ /dev/null @@ -1,49 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/lint-ts.yml - -# ✍️ Description: -# This action is used to run eslint checks -# Runs on pull requests and pushes to the main/master branches -# Based on the event type: -# - If it's a pull request, it will run eslint, then add the check to the PR as well as annotate the code with the errors and warnings. -# - If it's a push to main/master, it will run the type checking and fail if there are any errors. - -# 🚨 GITHUB SECRETS REQUIRED: NONE - -name: Lint TS (eslint, prettier) - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - -permissions: - contents: read - pull-requests: write - -jobs: - lint: - name: Lint TS (eslint, prettier) - runs-on: ubuntu-latest - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: 🏃‍♂️ Run ESLint PR - if: github.event_name == 'pull_request' - uses: reviewdog/action-eslint@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - reporter: github-pr-review - eslint_flags: '. --ext .js,.jsx,.ts,.tsx' - - - name: 🏃‍♂️ Run ESLint PR - if: github.event_name != 'pull_request' - run: pnpm run lint diff --git a/.github/workflows/new-app-version.yml b/.github/workflows/new-app-version.yml deleted file mode 100644 index 53b42694ae2ea5a68b7e40072785afbf1190d18a..0000000000000000000000000000000000000000 --- a/.github/workflows/new-app-version.yml +++ /dev/null @@ -1,65 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/lint-ts.yml -# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ - -# ✍️ Description: -# This workflow is used to create a new version of the app and push a new tag to the repo. -# As this workflow will push code to the repo, we set up GitHub Bot as a Git user. -# This Workflow need to be triggered manually from the Actions tab in the repo. -# 1. Choose your release type (patch, minor, major) -# 2. The workflow will run the np-release script which runs the following steps: -# - Bump the version in package.json based on the release type using np -# - Run the prebuild of the app to align the package.json version with the native code -# - Create a new tag with the new version -# - Push the new tag to the repo -# - -# 🚨 GITHUB SECRETS REQUIRED: -# - GH_TOKEN: A GitHub token with write repo access. -# You can generate one from here: https://docs.github.com/en/enterprise-server@3.6/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens -# make sure to add it to the repo secrets with the name GH_TOKEN - -name: New App Version - -on: - workflow_dispatch: - inputs: - release-type: - type: choice - description: 'Release type (one of): patch, minor, major' - required: true - default: 'patch' - options: - - patch - - minor - - major - -jobs: - release: - name: Create New Version and push new tag - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: 🔍 GH_TOKEN - if: env.GH_TOKEN == '' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: echo "GH_TOKEN=${GITHUB_TOKEN}" >> $GITHUB_ENV - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GH_TOKEN }} - - - name: 📝 Git User Setup - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: 🏃‍♂️ Run App release - run: | - pnpm app-release ${{ github.event.inputs.release-type }} diff --git a/.github/workflows/new-github-release.yml b/.github/workflows/new-github-release.yml deleted file mode 100644 index a432b8515b6d71fc8a79cfc7a365248ec4742289..0000000000000000000000000000000000000000 --- a/.github/workflows/new-github-release.yml +++ /dev/null @@ -1,34 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/new-github-release.yml -# Starter releasing process: https://starter.obytes.com/ci-cd/app-releasing-process/ - -# ✍️ Description: -# This workflow will be triggered automatically after the new app version workflow has been executed successfully. -# It will create a new GitHub release with the new app version and the release notes. - -# 🚨 GITHUB SECRETS REQUIRED: None - -name: New GitHub Release - -on: - push: - tags: - - '*' - -jobs: - release: - name: New GitHub Release - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 🏃‍♂️Create A Draft Github Release - uses: ncipollo/release-action@v1 - with: - generateReleaseNotes: true - draft: false diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 3fbbdea6df5a828f4d2e69ceb279957964521bac..0000000000000000000000000000000000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: '0 0 * * *' - -permissions: - contents: read - pull-requests: write - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - 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' - days-before-stale: 60 - days-before-close: 14 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index a97de28b469434ce2aca1032cef7002035f012fe..0000000000000000000000000000000000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,50 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/test.yml - -# ✍️ Description: -# This action is used to run unit tests -# Runs on pull requests and pushes to the main/master branches -# Based on the event type: -# - If it's a pull request, it will run the tests and post a comment with coverage details. -# - If it's a push to main/master, it will run the tests and add the check to the commit. - -# 🚨 GITHUB SECRETS REQUIRED: NONE - -name: Tests (jest) - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - -jobs: - test: - name: Tests (jest) - runs-on: ubuntu-latest - - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: 🏃‍♂️ Run Tests - run: pnpm run test:ci - - - name: Jest Coverage Comment - uses: MishaKav/jest-coverage-comment@main - if: (success() || failure()) && github.event_name == 'pull_request' - with: - coverage-summary-path: ./coverage/coverage-summary.json - summary-title: '💯 Test Coverage' - badge-title: Coverage - create-new-comment: false - junitxml-title: 😎 Tests Results - junitxml-path: ./coverage/jest-junit.xml - coverage-title: 👀 Tests Details - coverage-path: ./coverage/coverage.txt - report-only-changed-files: true diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml deleted file mode 100644 index 1705bf4e3596c63d36cd44defec98087b53cd61e..0000000000000000000000000000000000000000 --- a/.github/workflows/type-check.yml +++ /dev/null @@ -1,54 +0,0 @@ -# 🔗 Links: -# Source file: https://github.com/obytes/react-native-template-obytes/blob/master/.github/workflows/type-check.yml - -# ✍️ Description: -# This action is used to run the type-check on the project. -# Runs on pull requests and pushes to the main/master branches -# Based on the event type: -# - If it's a pull request, it will run type checking, then add the check to the PR as well as annotate the code with the errors using reviewdog. -# - If it's a push to main/master, it will run the type checking and fail if there are any errors. - -# 🚨 GITHUB SECRETS REQUIRED: NONE - -name: Type Check (tsc) - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - -permissions: - contents: read - pull-requests: write - -jobs: - type-check: - name: Type Check (tsc) - runs-on: ubuntu-latest - steps: - - name: 📦 Checkout project repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: 📦 Setup Node + PNPM + install deps - uses: ./.github/actions/setup-node-pnpm-install - - - name: 📦 Install Reviewdog - if: github.event_name == 'pull_request' - uses: reviewdog/action-setup@v1 - - - name: 🏃‍♂️ Run TypeScript PR # Reviewdog tsc errorformat: %f:%l:%c - error TS%n: %m - # We only need to add the reviewdog step if it's a pull request - if: github.event_name == 'pull_request' - run: | - pnpm type-check | reviewdog -name="tsc" -efm="%f(%l,%c): error TS%n: %m" -reporter="github-pr-review" -filter-mode="nofilter" -fail-on-error -tee - env: - REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: - 🏃‍♂️ Run TypeScript Commit - # If it's not a Pull Request then we just need to run the type-check - if: github.event_name != 'pull_request' - run: pnpm type-check diff --git a/.maestro/app/create-post.yaml b/.maestro/app/create-post.yaml deleted file mode 100644 index 89772e95d1f4d0f884c8d42a675ab051d6de6814..0000000000000000000000000000000000000000 --- a/.maestro/app/create-post.yaml +++ /dev/null @@ -1,29 +0,0 @@ -appId: ${APP_ID} -env: - 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\ - \ Ipsum is that it has a more-or-less normal distribution of letters, as opposed\ - \ to using" ---- -- launchApp -- runFlow: ../utils/onboarding-and-login.yaml -- assertVisible: 'Feed' -- assertVisible: 'Create' -- tapOn: 'Create' -- assertVisible: 'Add Post' -- tapOn: - id: 'title' -- inputText: ${Title} -- tapOn: - id: 'body-input' -- inputText: 'short content' -- tapOn: - 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' diff --git a/.maestro/app/tabs.yaml b/.maestro/app/tabs.yaml deleted file mode 100644 index 741d92fed74dea8cdcd3e5687562b17729d7528f..0000000000000000000000000000000000000000 --- a/.maestro/app/tabs.yaml +++ /dev/null @@ -1,19 +0,0 @@ -appId: ${APP_ID} -env: - Name: 'User' - EMAIL: 'user@test.com' - PASSWORD: 'password' ---- -- launchApp -- runFlow: ../utils/onboarding-and-login.yaml -- assertVisible: 'Feed' -- assertVisible: - id: 'style-tab' -- tapOn: - id: 'style-tab' -- assertVisible: 'Typography' -- tapOn: - id: 'settings-tab' -- assertVisible: 'Settings' -- scroll -- assertVisible: 'Logout' diff --git a/.maestro/auth/login-with-validation.yaml b/.maestro/auth/login-with-validation.yaml deleted file mode 100644 index a669e39b7011143fbc6dc448ec6289a7eba2c09f..0000000000000000000000000000000000000000 --- a/.maestro/auth/login-with-validation.yaml +++ /dev/null @@ -1,35 +0,0 @@ -appId: ${APP_ID} -env: - Name: 'User' - EMAIL: 'user@test.com' - PASSWORD: 'password' ---- -- launchApp -- runFlow: - when: - visible: 'Obytes Starter' - file: ../utils/onboarding.yaml -- assertVisible: 'Sign In' -- assertVisible: - id: 'login-button' -- tapOn: - id: 'login-button' -- assertVisible: 'Email is required' -- assertVisible: 'Password is required' -- tapOn: - id: 'name' -- inputText: ${Name} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: 'email-input' -- inputText: 'email' -- assertVisible: 'Invalid email format' -- inputText: ${EMAIL} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: 'password-input' -- inputText: ${PASSWORD} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: 'login-button' -- assertVisible: 'Feed' diff --git a/.maestro/auth/onboarding.yaml b/.maestro/auth/onboarding.yaml deleted file mode 100644 index b52203dfd6c1b1aeea24974b4ff68f6a05cf76c2..0000000000000000000000000000000000000000 --- a/.maestro/auth/onboarding.yaml +++ /dev/null @@ -1,8 +0,0 @@ -appId: ${APP_ID} ---- -- clearState -- launchApp -- assertVisible: "Obytes Starter" -- assertVisible: "Let's Get Started " -- tapOn: "Let's Get Started " -- assertVisible: "Sign In" \ No newline at end of file diff --git a/.maestro/config.yaml b/.maestro/config.yaml deleted file mode 100644 index 6961b7e01097c0926f5047a51896203a2b37e4e5..0000000000000000000000000000000000000000 --- a/.maestro/config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -flows: - - auth/* - - app/* - -excludeTags: - - util - -executionOrder: - continueOnFailure: false # default is true - flowsOrder: - - onboarding - - login-with-validation \ No newline at end of file diff --git a/.maestro/utils/hide-keyboard-android.yaml b/.maestro/utils/hide-keyboard-android.yaml deleted file mode 100644 index 07025331e69051c5743bad02e0fd88e43c854bf7..0000000000000000000000000000000000000000 --- a/.maestro/utils/hide-keyboard-android.yaml +++ /dev/null @@ -1,5 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- hideKeyboard \ No newline at end of file diff --git a/.maestro/utils/hide-keyboard-ios.yaml b/.maestro/utils/hide-keyboard-ios.yaml deleted file mode 100644 index f22dc286f74ffec3cb1f72b5e89d78f23a14a640..0000000000000000000000000000000000000000 --- a/.maestro/utils/hide-keyboard-ios.yaml +++ /dev/null @@ -1,6 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- tapOn: - id: "Return" # Keyboard Return \ No newline at end of file diff --git a/.maestro/utils/hide-keyboard.yaml b/.maestro/utils/hide-keyboard.yaml deleted file mode 100644 index dfd1cf9a28ec0dcfd8abc4ec6d2e870b673d60ba..0000000000000000000000000000000000000000 --- a/.maestro/utils/hide-keyboard.yaml +++ /dev/null @@ -1,12 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- runFlow: - when: - platform: iOS - file: ./hide-keyboard-ios.yaml -- runFlow: - when: - platform: Android - file: ./hide-keyboard-android.yaml \ No newline at end of file diff --git a/.maestro/utils/login.yaml b/.maestro/utils/login.yaml deleted file mode 100644 index 6e2b32046241ce74a7bf06c7351cdd3f50743aff..0000000000000000000000000000000000000000 --- a/.maestro/utils/login.yaml +++ /dev/null @@ -1,22 +0,0 @@ -appId: ${APP_ID} -env: - Name: "User" - EMAIL: "user@test.com" - PASSWORD: "password" -tags: - - util ---- -- tapOn: - id: "name" -- inputText: ${Name} -- tapOn: - id: "email-input" -- inputText: ${EMAIL} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: "password-input" -- inputText: ${PASSWORD} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: "login-button" -- assertVisible: "Typography" diff --git a/.maestro/utils/onboarding-and-login.yaml b/.maestro/utils/onboarding-and-login.yaml deleted file mode 100644 index 707c945c1a9d10c801171d17845df83e01990874..0000000000000000000000000000000000000000 --- a/.maestro/utils/onboarding-and-login.yaml +++ /dev/null @@ -1,12 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- runFlow: - when: - visible: "Obytes Starter" - file: onboarding.yaml -- runFlow: - when: - visible: Sign In - file: login.yaml \ No newline at end of file diff --git a/.maestro/utils/onboarding.yaml b/.maestro/utils/onboarding.yaml deleted file mode 100644 index bb1b8937e71fa21bc6516cc71e54fb12fec66dd7..0000000000000000000000000000000000000000 --- a/.maestro/utils/onboarding.yaml +++ /dev/null @@ -1,8 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- assertVisible: 'Obytes Starter' -- assertVisible: "Let's Get Started " -- tapOn: "Let's Get Started " -- assertVisible: 'Sign In' diff --git a/LICENSE b/LICENSE index fde3b8df87dc143a4d7c3ccc8098810422cceff4..303d9db58da05512afb2aa0e112cf27877083807 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Obytes +Copyright (c) 2025 eucloud Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 56e08e96b2020b3bfb22ab3ddc1afffae662d0dc..0f33d1e29e203d565ac04ced97b09d8beda676d6 100644 --- a/README.md +++ b/README.md @@ -48,17 +48,6 @@ To run the app on Android npm run android ``` -## ✍️ Documentation - -- [Rules and Conventions](https://starter.obytes.com/getting-started/rules-and-conventions/) -- [Project structure](https://starter.obytes.com/getting-started/project-structure) -- [Environment vars and config](https://starter.obytes.com/getting-started/environment-vars-config) -- [UI and Theming](https://starter.obytes.com/ui-and-theme/ui-theming) -- [Components](https://starter.obytes.com/ui-and-theme/components) -- [Forms](https://starter.obytes.com/ui-and-theme/Forms) -- [Data fetching](https://starter.obytes.com/guides/data-fetching) -- [Contribute to starter](https://starter.obytes.com/how-to-contribute/) - ## 💎 Libraries used - [Expo](https://docs.expo.io/) @@ -89,4 +78,4 @@ This project is MIT licensed. ## 🔖 Other -[APi](https://gitee.com/xiaochanghai520/eu-admin) +[APi](https://github.com/xiaochanghai/eu.admin) diff --git a/env.js b/env.js index 8dde3be4a1de1d2838ae6a03c2a2e6a93ab40f1a..ab21d2346324158ba3dd09a20530a5ba5d71273e 100644 --- a/env.js +++ b/env.js @@ -29,7 +29,7 @@ require('dotenv').config({ * Such as: bundle id, package name, app name. * * You can add them to the .env file but we think it's better to keep them here as as we use prefix to generate this values based on the APP_ENV - * for example: if the APP_ENV is staging, the bundle id will be com.obytes.staging + * for example: if the APP_ENV is staging, the bundle id will be com.eucloud.staging */ // TODO: Replace these values with your own diff --git a/package.json b/package.json index 6a6ea5335406fa77bb8589f5419db5f90aea416d..49e484bb55bee4b8a1198de174a51a925a47fc92 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "react-native-edge-to-edge": "^1.1.2", "react-native-flash-message": "^0.4.2", "react-native-gesture-handler": "~2.20.2", - "react-native-keyboard-controller": "^1.13.2", + "react-native-keyboard-controller": "^1.14.2", "react-native-mmkv": "~3.1.0", "react-native-reanimated": "~3.16.7", "react-native-restart": "0.0.27", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79ca77c392b016e6b4f0f33f20691f72883f4855..d0f1f0b555cbc3d203ff011652428c76b17979af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,8 +120,8 @@ importers: specifier: ~2.20.2 version: 2.20.2(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) react-native-keyboard-controller: - specifier: ^1.13.2 - version: 1.16.8(react-native-reanimated@3.16.7(@babel/core@7.26.10)(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1))(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) + specifier: ^1.14.2 + version: 1.14.2(react-native-reanimated@3.16.7(@babel/core@7.26.10)(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1))(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) react-native-mmkv: specifier: ~3.1.0 version: 3.1.0(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) @@ -6543,8 +6543,8 @@ packages: react: '*' react-native: '*' - react-native-keyboard-controller@1.16.8: - resolution: {integrity: sha512-Ua6S4+ooMqNW3dFQ7/S/fhzgumAuOk0eUkYmNRyjg3ezYdOjwQNl7QiVQg6cxZkpPmeIkgHdmeOR1HZ45S2h4Q==} + react-native-keyboard-controller@1.14.2: + resolution: {integrity: sha512-1AgJo9byz9mJFnXH5WX4sGX88S9gh6lIREuurB96uoXdR7Xa17XCYd+JsrQx9pHcnK7Cz3mWcNh3IIwaHFvZKA==} peerDependencies: react: '*' react-native: '*' @@ -15875,11 +15875,10 @@ snapshots: react: 18.3.1 react-native: 0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1) - react-native-keyboard-controller@1.16.8(react-native-reanimated@3.16.7(@babel/core@7.26.10)(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1))(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1): + react-native-keyboard-controller@1.14.2(react-native-reanimated@3.16.7(@babel/core@7.26.10)(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1))(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 react-native: 0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1) - react-native-is-edge-to-edge: 1.1.7(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) react-native-reanimated: 3.16.7(@babel/core@7.26.10)(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1) react-native-mmkv@3.1.0(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.20)(react@18.3.1))(react@18.3.1): diff --git a/src/app/material/[id].tsx b/src/app/material/[id].tsx index 09ccdfb582ba4bac45177f70853ec7d82683cbc7..46d5358cdf49fa48f00b0809b701be4db22f8cc9 100644 --- a/src/app/material/[id].tsx +++ b/src/app/material/[id].tsx @@ -1,50 +1,579 @@ -import { - Stack, - // useLocalSearchParams -} from 'expo-router'; -import * as React from 'react'; - -// import { usePost } from '@/api'; -import { - // ActivityIndicator, - FocusAwareStatusBar, - Text, - View, -} from '@/components/ui'; - -export default function Post() { - // const local = useLocalSearchParams<{ id: string }>(); - - // const { data, isPending, isError } = usePost({ - // //@ts-ignore - // variables: { id: local.id }, - // }); - - // if (isPending) { - // return ( - // - // - // - // - // - // ); - // } - // if (isError) { - // return ( - // - // - // - // Error loading post - // - // ); - // } +import React, { useState } from 'react'; +import { ScrollView, Text, TouchableOpacity, View } from 'react-native'; + +import { NavHeader } from '@/components/ui'; +import { FontAwesome, GroupEnum } from '@/components/ui/icons'; +// import { LineChart } from 'react-native-chart-kit'; + +/** + * 标签类型定义 + */ +type TabType = 'info' | 'records' | 'docs'; + +/** + * 出入库记录项接口 + */ +interface RecordItem { + type: string; + orderNumber: string; + quantity: string; + date: string; + isInbound: boolean; +} + +/** + * 文档项接口 + */ +interface DocumentItem { + name: string; + type: string; + icon: string; + size: string; + uploadDate: string; +} + +/** + * 相关物料接口 + */ +interface RelatedMaterial { + name: string; + code: string; + spec: string; + stock: string; +} + +/** + * 物料数据接口 + */ +interface MaterialData { + id: string; + name: string; + category: string; + tag: string; + currentStock: number; + unit: string; + safetyStock: number; + status: string; + spec: string; + material: string; + price: number; + supplier: string; + location: string; + createDate: string; + remark: string; +} + +/** + * 详情行属性接口 + */ +interface DetailRowProps { + label: string; + value: string; + isLast?: boolean; +} + +/** + * 物料详情组件 + */ +const MaterialDetail = () => { + // 当前激活的标签页 + const [activeTab, setActiveTab] = useState('info'); + + // 模拟数据 - 物料基本信息 + const materialData: MaterialData = { + id: 'M10023', + name: '铝合金型材 AL6061', + category: '原材料', + tag: '常用', + currentStock: 120, + unit: '根', + safetyStock: 50, + status: '充足', + spec: '20mm×40mm×6000mm', + material: '铝合金 6061-T6', + price: 185.0, + supplier: '广州市恒鑫金属材料有限公司', + location: 'A区-03-B12', + createDate: '2023-05-18', + remark: '用于机器框架结构,需按图纸要求切割', + }; + + // 模拟数据 - 出入库记录 + const records: RecordItem[] = [ + { + type: '入库', + orderNumber: 'RK20230612-001', + quantity: '+30根', + date: '2023-06-12 14:30', + isInbound: true, + }, + { + type: '出库', + orderNumber: 'CK20230605-008', + quantity: '-15根', + date: '2023-06-05 09:15', + isInbound: false, + }, + { + type: '入库', + orderNumber: 'RK20230528-003', + quantity: '+50根', + date: '2023-05-28 16:45', + isInbound: true, + }, + { + type: '出库', + orderNumber: 'CK20230520-012', + quantity: '-25根', + date: '2023-05-20 11:30', + isInbound: false, + }, + ]; + + // 模拟数据 - 相关文档 + const documents: DocumentItem[] = [ + { + name: '产品规格书', + type: 'PDF文档', + icon: 'file-pdf', + size: '2.5MB', + uploadDate: '2023-05-18上传', + }, + { + name: '材质检测报告', + type: 'Excel文档', + icon: 'file-excel', + size: '1.2MB', + uploadDate: '2023-05-18上传', + }, + { + name: '材料图片', + type: 'JPG图片', + icon: 'file-image', + size: '3.8MB', + uploadDate: '2023-05-18上传', + }, + { + name: '供应商信息', + type: 'TXT文档', + icon: 'file-alt', + size: '0.5MB', + uploadDate: '2023-05-18上传', + }, + ]; + + // 模拟数据 - 相关物料 + const relatedMaterials: RelatedMaterial[] = [ + { + name: '铝合金型材 AL6063', + code: 'M10024', + spec: '30mm×60mm×6000mm', + stock: '85根', + }, + { + name: '铝合金型材 AL6082', + code: 'M10025', + spec: '20mm×40mm×6000mm', + stock: '65根', + }, + ]; + + // 样式常量 + const styles = { + tab: 'text-sm font-medium text-gray-600', + tabActive: 'text-sm font-medium text-blue-600', + tabTouchable: 'flex-1 items-center px-4 py-2', + tabTouchableActive: + 'flex-1 items-center border-b-2 border-blue-600 px-4 py-2', + fastOption: 'items-center justify-center rounded-lg py-2', + fastOptionWithMargin: 'mr-2 items-center justify-center rounded-lg py-2', + listItemBorder: 'border-b border-gray-100 py-3', + listItemNoBorder: 'py-3', + }; + + /** + * 渲染标签页内容 + */ + const renderTabContent = () => { + switch (activeTab) { + case 'info': + return ( + + + + + + + + + + + ); + case 'records': + return ( + + {records.map((record, index) => ( + + ))} + + ); + case 'docs': + return ( + + {documents.map((doc, index) => ( + + ))} + + ); + default: + return null; + } + }; return ( - - - - 11111 - 1111 + + + + + + + + + + } + /> + + {/* 物料基本信息卡片 */} + + + + + + + {materialData.name} + + 编号: {materialData.id} + + + + + {materialData.category} + + + + + {materialData.tag} + + + + + + + {/* 库存状态 */} + + + 当前库存 + + + {materialData.currentStock} + + + {materialData.unit} + + + + + 安全库存 + + + {materialData.safetyStock} + + + {materialData.unit} + + + + + 状态 + + + + {materialData.status} + + + + + + {/* 快捷操作按钮 */} + + + + + + + + + {/* 详细信息选项卡 */} + + + setActiveTab('info')} + styles={styles} + /> + setActiveTab('records')} + styles={styles} + /> + setActiveTab('docs')} + styles={styles} + /> + + + {renderTabContent()} + + + {/* 相关物料 */} + + 相关物料 + + {relatedMaterials.map((material, index) => ( + + ))} + + ); +}; + +/** + * 详情行组件 + */ +const DetailRow = ({ + label = '', + value = '', + isLast = false, +}: DetailRowProps) => ( + + {label} + {value} + +); + +/** + * 出入库记录项组件 + */ +interface RecordListItemProps { + record: RecordItem; + isLast: boolean; +} + +const RecordListItem = ({ record, isLast }: RecordListItemProps) => ( + + + + {record.type} + + 单号: {record.orderNumber} + + + + + {record.quantity} + + {record.date} + + + +); + +/** + * 文档列表项组件 + */ +interface DocumentListItemProps { + document: DocumentItem; + isLast: boolean; } + +const DocumentListItem = ({ document, isLast }: DocumentListItemProps) => { + /** + * 获取文档图标颜色 + * @param iconName 图标名称 + * @returns 对应的颜色代码 + */ + const getDocIconColor = (iconName: string): string => { + switch (iconName) { + case 'file-pdf': + return '#ef4444'; // 红色 + case 'file-excel': + return '#22c55e'; // 绿色 + case 'file-image': + return '#3b82f6'; // 蓝色 + default: + return '#6b7280'; // 灰色 + } + }; + // 获取图标颜色 + const iconColor = getDocIconColor(document.icon); + + return ( + + + + + {document.name} + + {document.type} · {document.size} · {document.uploadDate} + + + + + ); +}; + +/** + * 相关物料项组件 + */ +interface RelatedMaterialItemProps { + material: RelatedMaterial; + isLast: boolean; +} + +const RelatedMaterialItem = ({ + material, + isLast, +}: RelatedMaterialItemProps) => ( + + + + {material.name} + + 编号: {material.code} | 规格: {material.spec} + + + + 库存: {material.stock} + + + +); + +/** + * 操作按钮组件 + */ +interface ActionButtonProps { + icon: string; + label: string; + color: string; + className: string; +} + +const ActionButton = ({ icon, label, color, className }: ActionButtonProps) => ( + + + {label} + +); + +/** + * 标签按钮组件 + */ +interface TabButtonProps { + label: string; + isActive: boolean; + onPress: () => void; + styles: Record; +} + +const TabButton = ({ label, isActive, onPress, styles }: TabButtonProps) => ( + + {label} + +); + +export default MaterialDetail; diff --git a/src/components/ui/icons/font-awesome.tsx b/src/components/ui/icons/font-awesome.tsx index 281d7be805911db36a9496487f6458caf7aa33f6..2b6bc22ffbb9fd25548cedecc1ce89e4a41ae6ac 100644 --- a/src/components/ui/icons/font-awesome.tsx +++ b/src/components/ui/icons/font-awesome.tsx @@ -33,13 +33,15 @@ type Group = * @property {number} [size=24] - 图标大小 * @property {string} [color] - 图标颜色 * @property {React.CSSProperties} [style] - 自定义样式 + * @property {string} [className] - 自定义CSS类名 * @property {Group} [group] - 指定图标组,不指定时会自动判断 */ type FontAwesomeIconProps = { name: string; size?: number; color?: string; - style?: React.CSSProperties; // 使用更精确的类型替代 any + style?: React.CSSProperties; + className?: string; // 添加className属性 group?: Group; }; @@ -96,6 +98,9 @@ const isFA5Icon = (iconName: string): boolean => { * // 基本用法 * * + * // 使用className设置样式 + * + * * // 指定图标组 * * @@ -107,11 +112,20 @@ export const FontAwesome: React.FC = ({ size = 24, color, style, + className, group, }) => { // 优先根据图标名称自动判断图标库 if (isFA5Icon(name)) { - return ; + return ( + + ); } // 其次根据指定的组类型选择图标库 @@ -122,6 +136,7 @@ export const FontAwesome: React.FC = ({ size={size} color={color} style={style as any} + className={className} /> ); } else if (group === GroupEnum.FontAwesome5) { @@ -130,7 +145,8 @@ export const FontAwesome: React.FC = ({ name={name} size={size} color={color} - style={style as any} + style={style} + className={className} /> ); } else if (group === GroupEnum.EvilIcons) { @@ -140,6 +156,7 @@ export const FontAwesome: React.FC = ({ size={size} color={color} style={style as any} + className={className} /> ); } @@ -151,6 +168,7 @@ export const FontAwesome: React.FC = ({ size={size} color={color} style={style as any} + className={className} /> ); };