diff --git a/.github/actions/install-deps/action.yml b/.github/actions/install-deps/action.yml
index e56e3ae9e4..94d416d627 100644
--- a/.github/actions/install-deps/action.yml
+++ b/.github/actions/install-deps/action.yml
@@ -1,13 +1,11 @@
name: 'Install Dependencies'
description: 'Install Node.js dependencies'
-
runs:
using: 'composite'
steps:
- name: Checkout code
uses: actions/checkout@v2
- # Cache yarn packages to speed up installation
- name: Cache Yarn packages
uses: actions/cache@v2
with:
@@ -16,7 +14,6 @@ runs:
restore-keys: |
${{ runner.os }}-yarn-
- # Install dependencies
- name: Install dependencies
run: yarn install --immutable
- shell: bash
+ shell: bash
\ No newline at end of file
diff --git a/.github/actions/setup-js-runtime/action.yml b/.github/actions/setup-js-runtime/action.yml
new file mode 100644
index 0000000000..112383ba1b
--- /dev/null
+++ b/.github/actions/setup-js-runtime/action.yml
@@ -0,0 +1,22 @@
+name: 'Setup JS Runtime Environment'
+description: 'Sets up Node.js and caches Node modules'
+runs:
+ using: 'composite'
+ steps:
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: '20.x'
+ cache: 'yarn'
+
+ - name: Cache Yarn packages
+ uses: actions/cache@v2
+ with:
+ path: ~/.yarn/cache
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - name: Install dependencies
+ run: yarn install --immutable
+ shell: bash
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 18635eeb6f..f74326c8ad 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -1,77 +1,61 @@
-# Add 'root' label to any root file changes
-# Quotation marks are required for the leading asterisk
root:
-- changed-files:
- - any-glob-to-any-file: '*'
+ - changed-files:
+ - any-glob-to-any-file: '*'
-## Equivalent of the above mentioned configuration using another syntax
docs:
-- changed-files:
- - any-glob-to-any-file: ['docs/*', 'guides/*', '**/*.md']
+ - changed-files:
+ - any-glob-to-any-file: '{docs/**/*,guides/**/*,**/*.md}'
-# Add 'feature' label to any PR where the head branch name starts with `feature` or has a `feature` section in the name
feature:
- - head-branch: ['^feature', 'feature']
+ - head-branch: ['^feature', 'feature']
-# Add 'release' label to any PR that is opened against the `main` branch
release:
- - base-branch: 'main'
+ - base-branch: 'main'
-# Add 'test' label to any change to *.spec.ts, *.spec.js, *.test.ts, *.test.js files within the entire repository
test:
-- changed-files:
- - any-glob-to-any-file:
- - '**/*.spec.ts'
- - '**/*.spec.js'
- - '**/*.test.ts'
- - '**/*.test.js'
- - '**/tests/**/*.ts'
- - '**/tests/**/*.js'
+ - changed-files:
+ - any-glob-to-any-file:
+ - '**/*.spec.ts'
+ - '**/*.spec.js'
+ - '**/*.test.ts'
+ - '**/*.test.js'
+ - '**/tests/**/*.ts'
+ - '**/tests/**/*.js'
-# Add 'frontend' label to any change in the 'client' directory
frontend:
-- changed-files:
- - any-glob-to-any-file:
- - 'apps/**/*.{ts,js}'
- - any: 'apps/**/*.ts'
- - any: 'apps/**/*.js'
- - all-globs-to-all-files:
- - '!apps/src/main.ts'
- - '!apps/src/main.js'
+ - changed-files:
+ - any-glob-to-any-file: 'apps/**/*.{ts,js, jsx, tsx}'
-# Add 'backend' label to any change in the 'server' directory
backend:
-- changed-files:
- - any-glob-to-any-file: 'server/**/*.{ts,js}'
+ - changed-files:
+ - any-glob-to-any-file: 'server/**/*.{ts,js}'
-# Add the 'AnyChange' label to any changes within the entire repository
AnyChange:
-- changed-files:
- - any-glob-to-any-file: '**'
+ - changed-files:
+ - any-glob-to-any-file: '*'
-# Add 'client' label to any change in the 'apps' directory
client:
-- changed-files:
- - any-glob-to-any-file: 'apps/**/*'
+ - changed-files:
+ - any-glob-to-any-file: 'apps/**/*'
-# Add 'expo' label to any changes in the 'apps/expo' directory
expo:
-- changed-files:
- - any-glob-to-any-file: 'apps/expo/**/*'
+ - changed-files:
+ - any-glob-to-any-file: 'apps/expo/**/*'
-# Add 'next' label to any changes in the 'apps/next' directory
next:
-- changed-files:
- - any-glob-to-any-file: 'apps/next/**/*'
+ - changed-files:
+ - any-glob-to-any-file: 'apps/next/**/*'
-# Add 'vite' label to any changes in the 'apps/vite' directory
vite:
-- changed-files:
- - any-glob-to-any-file: 'apps/vite/**/*'
+ - changed-files:
+ - any-glob-to-any-file: 'apps/vite/**/*'
-# Add 'api' label to any changes in the 'api' or 'server' directories
api:
-- changed-files:
- - any-glob-to-any-file:
- - 'api/**/*'
- - 'server/**/*'
+ - changed-files:
+ - any-glob-to-any-file:
+ - 'api/**/*'
+ - 'server/**/*'
+
+github:
+ - changed-files:
+ - any-glob-to-any-file: '.github/**/*'
\ No newline at end of file
diff --git a/.github/scripts/env.ts b/.github/scripts/env.ts
index ce02a6c1af..b168d2b054 100644
--- a/.github/scripts/env.ts
+++ b/.github/scripts/env.ts
@@ -88,4 +88,23 @@ const viteFileContent = envFileContent
.join('\n');
fs.writeFileSync(viteOutputPath, `${autogeneratedComment}\n${viteFileContent}`);
-// TODO: Add wrangler env generation
\ No newline at end of file
+// TODO: Add wrangler env generation
+/**
+ * Generate Cloudflare Wrangler .dev.vars file content
+ */
+// const wranglerOutputPath = path.join(__dirname, '..', '..', 'packages', 'api', '.dev.vars')
+// // Remove public variables from output
+// const wranglerFileContent = envFileContent
+// .split('\n')
+// .map((line) => {
+// if (line.startsWith('PUBLIC_APP_URL')) return line.replace(/^PUBLIC_APP_URL/, 'APP_URL')
+// if (!line.startsWith('PUBLIC_')) {
+// return line
+// }
+// })
+// .join('\n')
+// const noD1Warning = 'NO_D1_WARNING=true'
+// fs.writeFileSync(
+// wranglerOutputPath,
+// `${autogeneratedComment}\n${wranglerFileContent}\n${noD1Warning}`
+// )
\ No newline at end of file
diff --git a/.github/workflows/android-preview-build-local.yml b/.github/workflows/android-preview-build-local.yml
index 56e8b3699f..5f97a9cfe3 100644
--- a/.github/workflows/android-preview-build-local.yml
+++ b/.github/workflows/android-preview-build-local.yml
@@ -1,9 +1,9 @@
name: android-preview-build-local
on:
push:
- branches: [ "**" ]
+ branches: ['**']
pull_request:
- branches: [ "**" ]
+ branches: ['**']
jobs:
update:
@@ -65,7 +65,7 @@ jobs:
echo "apk_path=${apk_path}" >> $GITHUB_ENV
working-directory: apps/expo
env:
- DEBUG: "true"
+ DEBUG: 'true'
continue-on-error: true
- name: Upload APK
@@ -74,10 +74,58 @@ jobs:
name: android-apk
path: /home/runner/work/PackRat/PackRat/apps/expo/build-*.apk
- - name: Create Commit Comment
- if: github.event_name == 'push'
- uses: peter-evans/commit-comment@v2
+ - name: Find or create comment
+ if: github.event_name == 'pull_request'
+ uses: actions/github-script@v6
+ id: find_or_create_comment
with:
- body: |
- Android APK build ${{ steps.build.outcome == 'success' && 'completed' || 'failed' }}!
- ${{ steps.build.outcome == 'success' && format('You can download the APK file from the following link:\nhttps://github.com/{0}/actions/runs/{1}#artifacts', github.repository, github.run_id) || 'Please check the workflow logs for more details on the build failure.' }}
\ No newline at end of file
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const commentIdentifier = '';
+ const comments = await github.rest.issues.listComments({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ });
+
+ const existingComment = comments.data.find(comment => comment.body.startsWith(commentIdentifier));
+
+ if (existingComment) {
+ core.setOutput('comment_id', existingComment.id);
+ } else {
+ const commentBody = `${commentIdentifier}\nš Android APK build started... Please wait for the results! š`;
+ const { data: { id: commentId } } = await github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: commentBody
+ });
+ core.setOutput('comment_id', commentId);
+ }
+
+ - name: Update PR comment
+ if: always() && github.event_name == 'pull_request'
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const commentIdentifier = '';
+ const commentId = '${{ steps.find_or_create_comment.outputs.comment_id }}';
+ const buildOutcome = '${{ steps.build.outcome }}';
+ const buildStatus = buildOutcome == 'success' ? 'completed' : 'failed';
+ const workflowUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
+
+ let commentBody = `${commentIdentifier}\nAndroid APK build ${buildStatus}!`;
+
+ if (buildOutcome == 'success') {
+ commentBody += `\nYou can download the APK file from the following link:\n${workflowUrl}#artifacts`;
+ } else {
+ commentBody += '\nPlease check the workflow logs for more details on the build failure.';
+ }
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: commentBody
+ });
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5634a5e352..8b2a6d48aa 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,31 +1,51 @@
name: android-build-apk
on:
push:
- branches: [ "**" ]
+ branches: ['**']
pull_request:
- branches: [ "**" ]
+ branches: ['**']
jobs:
install-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- - name: Install yarn dependencies
- run: |
- yarn install
+
+ - name: Install dependencies
+ uses: ./.github/actions/install-deps
build-android:
needs: install-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- - name: Install yarn dependencies
+
+ - name: Setup Java
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 20.x
+ cache: yarn
+
+ - name: Install dependencies
+ uses: ./.github/actions/install-deps
+
+ - name: Prebuild
run: |
- yarn install
+ echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN"
+ export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }}
+ yarn run prebuild:expo
+
- name: Build Android Release
run: |
cd apps/expo/android && ./gradlew assembleRelease
+
- name: Upload Artifact
uses: actions/upload-artifact@v1
with:
name: app-release.apk
- path: android/app/build/outputs/apk/release/
\ No newline at end of file
+ path: android/app/build/outputs/apk/release/
diff --git a/.github/workflows/deployments/backend.yml b/.github/workflows/deployments/backend.yml
new file mode 100644
index 0000000000..5b970dd886
--- /dev/null
+++ b/.github/workflows/deployments/backend.yml
@@ -0,0 +1,54 @@
+name: 'Backend Deployment'
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ paths:
+ - 'packages/api/**'
+ - 'server/**'
+
+jobs:
+ deploy:
+ name: Deploy to Cloudflare Workers
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 1
+
+ - name: Setup JS Runtime environment
+ uses: ./.github/actions/setup-js-runtime
+
+ - name: Install dependencies
+ uses: ./.github/actions/install-deps
+
+ - name: Migrate database
+ # run: cd packages/api && bun run migrate
+ run: cd server && yarn run migrate:prod
+ env:
+ NO_D1_WARNING: true
+ CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
+
+ - name: Deploy
+ uses: cloudflare/wrangler-action@v3.3.2
+ with:
+ wranglerVersion: '3.15.0'
+ apiToken: ${{ secrets.CF_API_TOKEN }}
+ # workingDirectory: packages/api
+ workingDirectory: server
+ command: yarn run deploy:prod
+ packageManager: bun
+ secrets: |
+ APP_URL
+ JWT_VERIFICATION_KEY
+ CI
+ env:
+ APP_URL: ${{ secrets.NEXT_PUBLIC_APP_URL }}
+ JWT_VERIFICATION_KEY: ${{ secrets.JWT_VERIFICATION_KEY }}
+ CI: true
+ NO_D1_WARNING: true
\ No newline at end of file
diff --git a/.github/workflows/ios-build-local.yml b/.github/workflows/ios-build-local.yml
index c3425d8752..a696a89d70 100644
--- a/.github/workflows/ios-build-local.yml
+++ b/.github/workflows/ios-build-local.yml
@@ -40,6 +40,7 @@ jobs:
yarn run prebuild:expo
- name: Build iOS app
+ id: build
run: |
echo "Using Mapbox Token: $MAPBOX_DOWNLOADS_TOKEN"
export MAPBOX_DOWNLOADS_TOKEN=${{ secrets.MAPBOX_DOWNLOADS_TOKEN }}
@@ -54,10 +55,57 @@ jobs:
name: app-release
path: ${{ github.workspace }}/app-release.ipa
- - name: Create Commit Comment
- if: github.event_name == 'push'
- uses: peter-evans/commit-comment@v2
+ - name: Find or create comment
+ if: github.event_name == 'pull_request'
+ uses: actions/github-script@v6
+ id: find_or_create_comment
with:
- body: |
- iOS app build ${{ steps.build.outcome == 'success' && 'completed' || 'failed' }}!
- ${{ steps.build.outcome == 'success' && format('You can download the IPA file from the following link:\nhttps://github.com/{0}/actions/runs/{1}#artifacts', github.repository, github.run_id) || 'Please check the workflow logs for more details on the build failure.' }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const commentIdentifier = '';
+ const comments = await github.rest.issues.listComments({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ });
+
+ const existingComment = comments.data.find(comment => comment.body.startsWith(commentIdentifier));
+
+ if (existingComment) {
+ core.setOutput('comment_id', existingComment.id);
+ } else {
+ const commentBody = `${commentIdentifier}\nš iOS app build started... Please wait for the results! š`;
+ const { data: { id: commentId } } = await github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: commentBody
+ });
+ core.setOutput('comment_id', commentId);
+ }
+ - name: Update PR comment
+ if: always() && github.event_name == 'pull_request'
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const commentIdentifier = '';
+ const commentId = '${{ steps.find_or_create_comment.outputs.comment_id }}';
+ const buildOutcome = '${{ steps.build.outcome }}';
+ const buildStatus = buildOutcome == 'success' ? 'completed' : 'failed';
+ const workflowUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
+
+ let commentBody = `${commentIdentifier}\niOS app build ${buildStatus}!`;
+
+ if (buildOutcome == 'success') {
+ commentBody += `\nYou can download the IPA file from the following link:\n${workflowUrl}#artifacts`;
+ } else {
+ commentBody += '\nPlease check the workflow logs for more details on the build failure.';
+ }
+
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: commentId,
+ body: commentBody
+ });
diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml
index 80d7979334..fe26a89eff 100644
--- a/.github/workflows/label.yml
+++ b/.github/workflows/label.yml
@@ -6,7 +6,8 @@
# https://github.com/actions/labeler
name: Pull request labeler
-on: [ pull_request_target ]
+on:
+ - pull_request
jobs:
label:
@@ -22,5 +23,6 @@ jobs:
- name: Labeler
uses: actions/labeler@v5
+ continue-on-error: true
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.github/workflows/node.js.dev.yml b/.github/workflows/node.js.dev.yml
index 04b0e3b47b..58da816fae 100644
--- a/.github/workflows/node.js.dev.yml
+++ b/.github/workflows/node.js.dev.yml
@@ -13,7 +13,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest] # Operating systems
- node-version: [18.x, 20.x, 21.x] # Node.js versions
+ node-version: [20.x, 22.x] # Node.js versions
steps:
- name: Checkout Repository
diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml
index 93b54380ef..6a54330363 100644
--- a/.github/workflows/node.js.yml
+++ b/.github/workflows/node.js.yml
@@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest] # Operating systems
- node-version: [18.x, 20.x, 21.x] # Node.js versions
+ node-version: [20.x, 22.x] # Node.js versions
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 52165f25b2..480e938a25 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -63,13 +63,16 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
+ const commentIdentifier = '';
const commentId = process.env.COMMENT_ID;
const testLogs = `${{ steps.run_tests.outputs.stdout }}\n${{ steps.run_tests.outputs.stderr }}`;
const testStatus = `${{ steps.run_tests.outcome }}`;
+ const workflowUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
- let commentBody = '\n';
- let emoji = '';
+ const includeTestLogs = false; // Set this to true when you want to include the test logs
+ let commentBody = `${commentIdentifier}\n`;
+ let emoji = '';
if (testStatus === 'success') {
commentBody += 'ā
Tests passed successfully! š\n\n';
emoji = 'š';
@@ -78,7 +81,11 @@ jobs:
emoji = 'ā¤ļø';
}
- commentBody += `Test Logs
\n\n\`\`\`\n${testLogs}\n\`\`\`\n `;
+ commentBody += `[View Test Workflow](${workflowUrl})\n\n`;
+
+ if (includeTestLogs) {
+ commentBody += `Test Logs
\n\n\`\`\`\n${testLogs}\n\`\`\`\n `;
+ }
await github.rest.issues.updateComment({
owner: context.repo.owner,
diff --git a/apps/next/package.json b/apps/next/package.json
index b2bb2d0664..90f62dfe52 100644
--- a/apps/next/package.json
+++ b/apps/next/package.json
@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
- "dev": "next dev -p 4000",
+ "dev": "next dev -p 4200",
"build": "next build",
"start": "next start",
"lint": "next lint",
diff --git a/package.json b/package.json
index 5a4b600548..f010d85995 100644
--- a/package.json
+++ b/package.json
@@ -73,6 +73,7 @@
"upgrade:hono": "yarn up '@hono/*'@latest 'hono'@latest",
"upgrade:tamagui:canary": "yarn up '*tamagui*'@canary '@tamagui/*'@canary",
"upgrade:tamagui": "yarn up '*tamagui*'@latest '@tamagui/*'@latest",
+ "upgrade:drizzle": "yarn up 'drizzle-*'@latest",
"web": "cd apps/next && yarn dev"
},
"engines": {
diff --git a/packages/app/components/PlacesAutocomplete/PlacesAutocomplete.tsx b/packages/app/components/PlacesAutocomplete/PlacesAutocomplete.tsx
index 7e3b8a01d2..82715aaae4 100644
--- a/packages/app/components/PlacesAutocomplete/PlacesAutocomplete.tsx
+++ b/packages/app/components/PlacesAutocomplete/PlacesAutocomplete.tsx
@@ -1,39 +1,40 @@
-import { forwardRef, useImperativeHandle, useRef } from 'react';
-import { TextInput } from 'react-native';
+import React, { forwardRef, useImperativeHandle, useRef } from 'react';
+import { type TextInput } from 'react-native';
import { SearchInput } from '../SearchInput';
import { RStack, RText } from '@packrat/ui';
import useTheme from 'app/hooks/useTheme';
import { usePlacesAutoComplete } from './usePlacesAutoComplete';
-export const PlacesAutocomplete = forwardRef(
- ({ onSelect, placeholder }, ref) => {
- const { data, handleSelect, search, setSearch } =
- usePlacesAutoComplete(onSelect);
- const inputRef = useRef();
+export const PlacesAutocomplete = forwardRef(function PlacesAutoComplete(
+ { onSelect, placeholder },
+ ref,
+) {
+ const { data, handleSelect, search, setSearch } =
+ usePlacesAutoComplete(onSelect);
+ const inputRef = useRef();
- useImperativeHandle(
- ref,
- () => ({
- searchText: search,
- focus: () => inputRef.current?.focus(),
- }),
- [search],
- );
+ useImperativeHandle(
+ ref,
+ () => ({
+ searchText: search,
+ focus: () => inputRef.current?.focus(),
+ }),
+ [search],
+ );
- return (
- }
- onChange={setSearch}
- searchString={search}
- ref={inputRef}
- />
- );
- },
-);
+ return (
+ }
+ onChange={setSearch}
+ searchString={search}
+ ref={inputRef}
+ />
+ );
+});
const PlaceItem = ({ item }) => {
const { currentTheme } = useTheme();
diff --git a/packages/app/components/PlacesAutocomplete/usePlacesAutoComplete.ts b/packages/app/components/PlacesAutocomplete/usePlacesAutoComplete.ts
index b4b7f677fa..7707bf7e40 100644
--- a/packages/app/components/PlacesAutocomplete/usePlacesAutoComplete.ts
+++ b/packages/app/components/PlacesAutocomplete/usePlacesAutoComplete.ts
@@ -9,7 +9,7 @@ export const usePlacesAutoComplete = (onSelect) => {
const handleSelect = (result) => {
onSelect(result);
-
+ setSearch('');
// return new value of the input
return result.properties.name;
};
diff --git a/packages/app/components/SearchInput/SearchInput.tsx b/packages/app/components/SearchInput/SearchInput.tsx
index f6d9ad4320..04a50b9e03 100644
--- a/packages/app/components/SearchInput/SearchInput.tsx
+++ b/packages/app/components/SearchInput/SearchInput.tsx
@@ -1,5 +1,5 @@
-import React, { cloneElement, ReactNode, forwardRef } from 'react';
-import { Platform, TextInput } from 'react-native';
+import React, { cloneElement, type ReactNode, forwardRef } from 'react';
+import { Platform, type TextInput } from 'react-native';
import { MaterialIcons, MaterialCommunityIcons } from '@expo/vector-icons';
import useSearchInput from './useSearchInput';
import useTheme from 'app/hooks/useTheme';
@@ -25,7 +25,7 @@ interface SearchInputProps {
}
export const SearchInput = forwardRef(
- (
+ function SearchInput(
{
onSelect,
placeholder,
@@ -35,7 +35,7 @@ export const SearchInput = forwardRef(
searchString,
},
inputRef,
- ) => {
+ ) {
const {
handleClearSearch,
handleSearchResultClick,
@@ -243,5 +243,8 @@ const loadStyles = () => ({
marginBottom: 15,
maxWidth: 400,
width: '100%',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
},
});
diff --git a/packages/app/components/carousel/ScrollButton.tsx b/packages/app/components/carousel/ScrollButton.tsx
index 0e8a58aa4a..f8a576ce30 100644
--- a/packages/app/components/carousel/ScrollButton.tsx
+++ b/packages/app/components/carousel/ScrollButton.tsx
@@ -10,6 +10,7 @@ import {
ViewStyle,
} from 'react-native';
import useCustomStyles from 'app/hooks/useCustomStyles';
+import useTheme from 'app/hooks/useTheme';
interface ScrollButtonProps {
direction: 'left' | 'right';
@@ -19,6 +20,7 @@ interface ScrollButtonProps {
const ScrollButton = ({ direction, onPress, disabled }: ScrollButtonProps) => {
const styles = useCustomStyles(loadStyles);
+ const { isDark } = useTheme();
return (
{
style={styles.scrollButton}
disabled={disabled}
>
- {direction === 'left' && 〈}
- {direction != 'left' && 〉}
+ {direction === 'left' && 〈}
+ {direction != 'left' && 〉}
);
};
diff --git a/packages/app/components/itemtable/itemTable.tsx b/packages/app/components/itemtable/itemTable.tsx
index 18da5ab77e..ceb30136b6 100644
--- a/packages/app/components/itemtable/itemTable.tsx
+++ b/packages/app/components/itemtable/itemTable.tsx
@@ -147,7 +147,9 @@ export const ItemsTable = ({
*
* @return {undefined} This function doesn't return anything.
*/
- const handleNextPage = () => {};
+ const handleNextPage = () => {
+ setPage(page + 1)
+ };
/**
* Handles the action of going to the previous page.
*
diff --git a/packages/app/components/pack/AddPack.tsx b/packages/app/components/pack/AddPack.tsx
index d4f5a3f47f..6fee06511f 100644
--- a/packages/app/components/pack/AddPack.tsx
+++ b/packages/app/components/pack/AddPack.tsx
@@ -8,45 +8,50 @@ import {
FormSelect,
FormInput,
SubmitButton,
+ useModal,
} from '@packrat/ui';
import { BaseModal } from '@packrat/ui';
import useTheme from '../../hooks/useTheme';
import useCustomStyles from 'app/hooks/useCustomStyles';
-import { useAddNewPack } from 'app/hooks/packs';
+import { useAddNewPack, usePackId } from 'app/hooks/packs';
import { useRouter } from 'app/hooks/router';
import { addPackSchema } from '@packrat/validations';
-export const AddPack = ({ isCreatingTrip = false }) => {
+export const AddPack = ({ isCreatingTrip = false, onSuccess }) => {
// Hooks
const { enableDarkMode, enableLightMode, isDark, isLight, currentTheme } =
useTheme();
const styles = useCustomStyles(loadStyles);
const router = useRouter();
+ const [_, setPackIdParam] = usePackId();
const {
- addNewPack,
- isSuccess,
- isError,
+ addNewPackAsync,
response,
- error,
+ isError,
isLoading,
- name,
setIsPublic,
- isPublic,
- setName,
packSelectOptions,
} = useAddNewPack();
- // routing
- if (isSuccess && !isCreatingTrip && response) {
- router.push(`/pack/${response.id}`);
- }
/**
* Handles the addition of a pack.
* @return {void}
*/
- const handleAddPack = (data) => {
- addNewPack(data);
+ const handleAddPack = async (data) => {
+ try {
+ await addNewPackAsync(data);
+ onSuccess?.();
+ if (!response?.id) {
+ return;
+ }
+ if (!isCreatingTrip) {
+ router.push(`/pack/${response.id}`);
+ return;
+ }
+
+ setPackIdParam(response.id);
+ } catch {}
};
const handleonValueChange = (itemValue) => {
@@ -77,7 +82,7 @@ export const AddPack = ({ isCreatingTrip = false }) => {
placeholder={'Is Public'}
/>
@@ -95,11 +100,21 @@ export const AddPack = ({ isCreatingTrip = false }) => {
export const AddPackContainer = ({ isCreatingTrip }) => {
return (
-
+
);
};
+const PackModalContent = ({ isCreatingTrip }: { isCreatingTrip?: boolean }) => {
+ const { setIsModalOpen } = useModal();
+ return (
+ setIsModalOpen(false)}
+ />
+ );
+};
+
const loadStyles = (theme, appTheme) => {
const { isDark, currentTheme } = theme;
return {
diff --git a/packages/app/components/pack/PackDetails.tsx b/packages/app/components/pack/PackDetails.tsx
index 4f29e9f5f3..ba31f36556 100644
--- a/packages/app/components/pack/PackDetails.tsx
+++ b/packages/app/components/pack/PackDetails.tsx
@@ -75,10 +75,10 @@ export function PackDetails() {
error={error}
additionalComps={
<>
-
+
val}
renderItem={({ item }) => {
{
@@ -93,16 +93,14 @@ export function PackDetails() {
);
case SECTION.CTA:
return isAuthUserPack ? (
-
- setRefetch((prev) => !prev)}
- />
-
+ setRefetch((prev) => !prev)}
+ />
) : null;
case SECTION.SCORECARD:
return (
@@ -152,7 +150,6 @@ const loadStyles = (theme) => {
packsContainer: {
flexDirection: 'column',
minHeight: '100vh',
-
padding: 25,
fontSize: 26,
},
@@ -160,10 +157,10 @@ const loadStyles = (theme) => {
backgroundColor: currentTheme.colors.white,
},
boxStyle: {
- padding: 10,
+ padding: 5,
borderRadius: 10,
width: '100%',
- minHeight: 100,
+ minHeight: 400,
},
};
};
diff --git a/packages/app/hooks/geojson/useGEOLocationSearch.ts b/packages/app/hooks/geojson/useGEOLocationSearch.ts
index f9e5f8a95b..fe85057999 100644
--- a/packages/app/hooks/geojson/useGEOLocationSearch.ts
+++ b/packages/app/hooks/geojson/useGEOLocationSearch.ts
@@ -2,7 +2,7 @@ import { useMemo } from 'react';
import { createParam } from '@packrat/crosspath';
interface GeoSearchParams {
- osmId?: string;
+ osmId?: number;
osmType?: string;
name?: string;
}
@@ -31,5 +31,13 @@ export const useGEOLocationSearch = (): [
setParams(newSearchParams);
};
- return [osm, setGEOLocation];
+ const formattedOSM = useMemo(
+ () => ({
+ ...osm,
+ osmId: Number(osm.osmId),
+ }),
+ [osm],
+ );
+
+ return [formattedOSM, setGEOLocation];
};
diff --git a/packages/app/hooks/packs/useAddNewPack.ts b/packages/app/hooks/packs/useAddNewPack.ts
index 05300ff414..3ec3f737ba 100644
--- a/packages/app/hooks/packs/useAddNewPack.ts
+++ b/packages/app/hooks/packs/useAddNewPack.ts
@@ -22,6 +22,15 @@ export const useAddNewPack = () => {
});
};
+ // TODO Refactor pack creation
+ const addNewPackAsync = (data) => {
+ return mutation.mutateAsync({
+ name: data.name,
+ is_public: data.isPublic === packSelectOptions[0].value,
+ owner_id: user?.id,
+ });
+ };
+
const mutation = queryTrpc.addPack.useMutation({
onMutate: async (packData) => {
utils.getPacks.cancel({
@@ -76,6 +85,7 @@ export const useAddNewPack = () => {
return {
mutation,
addNewPack,
+ addNewPackAsync,
isLoading: mutation.isLoading,
isError: mutation.isError,
isSuccess: mutation.isSuccess,
diff --git a/packages/app/hooks/trips/useCreateTripForm.ts b/packages/app/hooks/trips/useCreateTripForm.ts
index ab45511d65..4034d5e1e0 100644
--- a/packages/app/hooks/trips/useCreateTripForm.ts
+++ b/packages/app/hooks/trips/useCreateTripForm.ts
@@ -21,8 +21,8 @@ export const useCreateTripForm = (
formatCreateTripValuesForAPI,
);
- const togglePlace = (value: any) => {
- setTripValue('destination', value);
+ const togglePlace = (name: 'trail' | 'park', value: any) => {
+ setTripValue(name, store[name] !== value ? value : '');
};
const createTripFormValues = useMemo>>(
diff --git a/packages/app/hooks/weather/useFetchWeather.ts b/packages/app/hooks/weather/useFetchWeather.ts
index d36c9be6ea..fb31640db2 100644
--- a/packages/app/hooks/weather/useFetchWeather.ts
+++ b/packages/app/hooks/weather/useFetchWeather.ts
@@ -1,6 +1,4 @@
import { queryTrpc } from '../../trpc';
-import { store } from '../../store/store';
-import { useState, useEffect } from 'react';
export const useFetchWeather = (latLng, isDisabled = false) => {
const { lat, lon } = latLng || {};
diff --git a/packages/app/hooks/weather/useFetchWeatherWeek.ts b/packages/app/hooks/weather/useFetchWeatherWeek.ts
index 65c6bc7bbf..379df11f5d 100644
--- a/packages/app/hooks/weather/useFetchWeatherWeek.ts
+++ b/packages/app/hooks/weather/useFetchWeatherWeek.ts
@@ -3,6 +3,7 @@ import { queryTrpc } from '../../trpc';
export const useFetchWeatherWeak = (latLng, isDisabled = false) => {
const { lat, lon } = latLng || {};
const isEnabled = !isDisabled && Boolean(lat && lon);
+
const { refetch, data, error, isLoading, isError } =
queryTrpc.getWeatherWeek.useQuery(
{ lat, lon },
diff --git a/packages/app/screens/about/AboutContent.tsx b/packages/app/screens/about/AboutContent.tsx
index d0c1cf678b..6fe73a80d4 100644
--- a/packages/app/screens/about/AboutContent.tsx
+++ b/packages/app/screens/about/AboutContent.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { View, Text } from 'react-native';
+import { View, Text , ScrollView} from 'react-native';
import { FontAwesome, MaterialCommunityIcons } from '@expo/vector-icons';
import { RButton, RStack } from '@packrat/ui';
import useTheme from '../../hooks/useTheme';
@@ -22,7 +22,7 @@ const AboutContent = ({ desktopContainer, isMobile }: AboutContentProps) => {
const { handleGithubLink, handleDiscordLink, aboutSections } = useAbout();
return (
-
+
@@ -67,7 +67,7 @@ const AboutContent = ({ desktopContainer, isMobile }: AboutContentProps) => {
-
+
);
};
diff --git a/packages/app/screens/trip/createTrip.tsx b/packages/app/screens/trip/createTrip.tsx
index 2b411b7336..e94c7cce53 100644
--- a/packages/app/screens/trip/createTrip.tsx
+++ b/packages/app/screens/trip/createTrip.tsx
@@ -65,13 +65,13 @@ export default function Trips() {
)}
togglePlace('trail', trail)}
+ selectedValue={tripStore.trail}
/>
togglePlace('park', park)}
+ selectedValue={tripStore.park}
/>
diff --git a/packages/validations/src/validations/tripRoutesValidator.ts b/packages/validations/src/validations/tripRoutesValidator.ts
index a53732dfc1..180be8c363 100644
--- a/packages/validations/src/validations/tripRoutesValidator.ts
+++ b/packages/validations/src/validations/tripRoutesValidator.ts
@@ -48,6 +48,8 @@ export const addTripDetails = z.object({
start_date: z.string(),
end_date: z.string(),
destination: z.string(),
+ park: z.string().optional(),
+ trail: z.string().optional(),
geoJSON: z.object({
type: z.literal('FeatureCollection'),
features: z.array(featureSchema),
diff --git a/server/migrations/0001_same_iron_patriot.sql b/server/migrations/0001_same_iron_patriot.sql
new file mode 100644
index 0000000000..ab10bdc3cb
--- /dev/null
+++ b/server/migrations/0001_same_iron_patriot.sql
@@ -0,0 +1,10 @@
+-- This is a dummy migration
+-- It does nothing
+SELECT 1;--> statement-breakpoint
+/*
+ SQLite does not support "Creating foreign key on existing column" out of the box, we do not generate automatic migration for that, so it has to be done manually
+ Please refer to: https://www.techonthenet.com/sqlite/tables/alter_table.php
+ https://www.sqlite.org/lang_altertable.html
+
+ Due to that we don't generate migration automatically and it has to be done manually
+*/
\ No newline at end of file
diff --git a/server/migrations/0003_conversation_schema_update.sql b/server/migrations/0003_conversation_schema_update.sql
index d6647c4ab8..9e13a3eff4 100644
--- a/server/migrations/0003_conversation_schema_update.sql
+++ b/server/migrations/0003_conversation_schema_update.sql
@@ -1,24 +1 @@
-BEGIN TRANSACTION;
--- Create a new table with the desired schema
-CREATE TABLE conversation_new (
- id TEXT PRIMARY KEY NOT NULL,
- user_id TEXT NOT NULL,
- history TEXT,
- itemTypeId TEXT NOT NULL,
- created_at TEXT DEFAULT CURRENT_TIMESTAMP,
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
-);
--- Copy all data from the old table to the new table
-INSERT INTO conversation_new (id, user_id, history, created_at, updated_at)
-SELECT id,
- user_id,
- history,
- created_at,
- updated_at
-FROM conversation;
--- Drop the old table
-DROP TABLE conversation;
--- Rename the new table to the old table's name
-ALTER TABLE conversation_new
- RENAME TO conversation;
-COMMIT;
\ No newline at end of file
+select 1;
\ No newline at end of file
diff --git a/server/package.json b/server/package.json
index 703a16018a..ac5ffeff20 100644
--- a/server/package.json
+++ b/server/package.json
@@ -17,15 +17,14 @@
"test:expect": "mocha 'generated/test/**/*.spec.js'",
"test:generate": "npx openapi-generator url http://localhost:3000/swagger.json -d ./generated -t javascript",
"test": "vitest",
- "prisma:format": "npx prisma format --schema=src/prisma/schema.prisma",
- "prisma:generate": "npx prisma generate --schema=src/prisma/schema.prisma --data-proxy",
- "prisma:validate": "npx prisma validate --schema=src/prisma/schema.prisma",
- "prisma:pull": "npx prisma db pull --schema=src/prisma/schema.prisma",
"wrangler:dev": "npx wrangler dev --port 8787 --local",
"wrangler:dev2": "npx wrangler pages dev --proxy 3001 --local --persist-to=./db.sqlite --d1=DB -- npm run dev",
"generate": "drizzle-kit generate:sqlite --schema=./src/db/schema.ts --out=./migrations",
- "migrate": "wrangler d1 migrations apply production",
+ "migrate": "yarn run migrate:local",
+ "migrate:prod": "wrangler d1 migrations apply production --remote",
"migrate:local": "wrangler d1 migrations apply production --local",
+ "migrate:down": "yarn run migrate:down:local",
+ "migrate:down:local": "drizzle-kit drop",
"seed": "wrangler d1 execute production --file=./seed/seed.sql",
"seed:local": "wrangler d1 execute production --local --file=./seed/seed.sql",
"studio": "drizzle-kit studio",
@@ -67,17 +66,17 @@
"cors": "^2.8.5",
"csurf": "^1.11.0",
"dotenv": "^16.0.3",
- "drizzle-orm": "^0.30.7",
+ "drizzle-orm": "^0.30.10",
"drizzle-zod": "^0.5.1",
"eslint-plugin-drizzle": "^0.2.3",
- "express": "^4.18.2",
+ "express": "^4.19.2",
"express-rate-limit": "^6.9.0",
"firebase": "^9.19.1",
"firebase-admin": "^11.5.0",
"google-auth-library": "^8.8.0",
"googleapis": "^118.0.0",
"helmet": "^7.0.0",
- "hono": "^4.2.6",
+ "hono": "^4.2.7",
"http2": "^3.3.7",
"i": "^0.3.7",
"joi": "^17.9.2",
@@ -118,7 +117,7 @@
"@types/jest": "^29.5.11",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"cross-env": "^7.0.3",
- "drizzle-kit": "^0.20.14",
+ "drizzle-kit": "^0.20.17",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-standard-with-typescript": "^38.0.0",
diff --git a/yarn.lock b/yarn.lock
index 44b460211f..320aa21730 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -16571,7 +16571,7 @@ __metadata:
languageName: node
linkType: hard
-"drizzle-kit@npm:^0.20.14":
+"drizzle-kit@npm:^0.20.17":
version: 0.20.17
resolution: "drizzle-kit@npm:0.20.17"
dependencies:
@@ -16598,7 +16598,7 @@ __metadata:
languageName: node
linkType: hard
-"drizzle-orm@npm:^0.30.7":
+"drizzle-orm@npm:^0.30.10":
version: 0.30.10
resolution: "drizzle-orm@npm:0.30.10"
peerDependencies:
@@ -19513,7 +19513,7 @@ __metadata:
languageName: node
linkType: hard
-"express@npm:^4.17.3, express@npm:^4.18.2, express@npm:^4.19.2":
+"express@npm:^4.17.3, express@npm:^4.19.2":
version: 4.19.2
resolution: "express@npm:4.19.2"
dependencies:
@@ -21342,14 +21342,7 @@ __metadata:
languageName: node
linkType: hard
-"hono@npm:^4.1.4, hono@npm:^4.2.6":
- version: 4.2.9
- resolution: "hono@npm:4.2.9"
- checksum: 10/b35ab755b84dbb649138b16889b5e7b752391cadb4a73f658af9e2c0133a6db28f472125f6ba996d3353e25b4d85d15ed724c3fe0f178b969e65d7324c108731
- languageName: node
- linkType: hard
-
-"hono@npm:^4.2.7":
+"hono@npm:^4.1.4, hono@npm:^4.2.7":
version: 4.2.9
resolution: "hono@npm:4.2.9"
checksum: 10/b35ab755b84dbb649138b16889b5e7b752391cadb4a73f658af9e2c0133a6db28f472125f6ba996d3353e25b4d85d15ed724c3fe0f178b969e65d7324c108731
@@ -31395,8 +31388,8 @@ __metadata:
cross-env: "npm:^7.0.3"
csurf: "npm:^1.11.0"
dotenv: "npm:^16.0.3"
- drizzle-kit: "npm:^0.20.14"
- drizzle-orm: "npm:^0.30.7"
+ drizzle-kit: "npm:^0.20.17"
+ drizzle-orm: "npm:^0.30.10"
drizzle-zod: "npm:^0.5.1"
eslint: "npm:^8.56.0"
eslint-config-prettier: "npm:^9.0.0"
@@ -31408,14 +31401,14 @@ __metadata:
eslint-plugin-prettier: "npm:^5.0.0"
eslint-plugin-promise: "npm:^6.1.1"
expect.js: "npm:^0.3.1"
- express: "npm:^4.18.2"
+ express: "npm:^4.19.2"
express-rate-limit: "npm:^6.9.0"
firebase: "npm:^9.19.1"
firebase-admin: "npm:^11.5.0"
google-auth-library: "npm:^8.8.0"
googleapis: "npm:^118.0.0"
helmet: "npm:^7.0.0"
- hono: "npm:^4.2.6"
+ hono: "npm:^4.2.7"
http2: "npm:^3.3.7"
i: "npm:^0.3.7"
jest: "npm:^29.7.0"