Skip to content

Commit

Permalink
Add POS main page to router
Browse files Browse the repository at this point in the history
  • Loading branch information
kilbot committed Feb 18, 2025
1 parent 646f4f6 commit e0f5ec3
Show file tree
Hide file tree
Showing 23 changed files with 295 additions and 177 deletions.
2 changes: 1 addition & 1 deletion apps/electron
Submodule electron updated 1 files
+0 −1 package.json
60 changes: 58 additions & 2 deletions apps/main/app/(app)/(drawer)/(pos)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,62 @@
import React from 'react';

import { Slot } from 'expo-router';
import { useObservableEagerState, ObservableResource } from 'observable-hooks';
import { map, distinctUntilChanged } from 'rxjs/operators';

import { Suspense } from '@wcpos/components/suspense';
import { useAppState } from '@wcpos/core/contexts/app-state';
import { useCollection } from '@wcpos/core/screens/main/hooks/use-collection';
import { CurrentOrderProvider } from '@wcpos/core/screens/main/pos/contexts/current-order';
import type { OrderDocument } from '@wcpos/database';

export default function POSLayout() {
// Set up the auth context and render our layout inside of it.
return <Slot />;
const { wpCredentials, store } = useAppState();
const cashierID = useObservableEagerState(wpCredentials.id$);
const storeID = useObservableEagerState(store.id$);
const { collection: ordersCollection } = useCollection('orders');

/**
* We then need to filter the open orders to limit by cashier and store
*
* @TODO - it would be nice to be able to query ($elemMatch) by cashier and store, but
* there are too many edge cases, ie: cashier is not set, store is not set, etc.
* For now, we'll just filter the results.
*/
const resource = React.useMemo(
() =>
new ObservableResource(
ordersCollection.find({ selector: { status: 'pos-open' } }).$.pipe(
map((docs: OrderDocument[]) => {
const filteredDocs = docs.filter((doc) => {
const metaData = doc.meta_data;
const _pos_user = metaData.find((item) => item.key === '_pos_user')?.value;
const _pos_store = metaData.find((item) => item.key === '_pos_store')?.value;
if (storeID === 0) {
return _pos_user === String(cashierID);
}
return _pos_user === String(cashierID) && _pos_store === String(storeID);
});
const filteredAndSortedDocs = filteredDocs.sort((a, b) =>
a.date_created_gmt.localeCompare(b.date_created_gmt)
);
return filteredAndSortedDocs.map((doc) => ({ id: doc.uuid, document: doc }));
}),
distinctUntilChanged((prev, next) => prev.length === next.length)
)
),
[cashierID, ordersCollection, storeID]
);

return (
<Suspense>
<CurrentOrderProvider
resource={resource} //</Suspense>currentOrderUUID={route.params?.orderID}
>
<Suspense>
<Slot />
</Suspense>
</CurrentOrderProvider>
</Suspense>
);
}
26 changes: 1 addition & 25 deletions apps/main/app/(app)/(drawer)/(pos)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
import { Text, View } from 'react-native';

import { Link } from 'expo-router';

import { useAppState } from '@wcpos/core/contexts/app-state';

export default function Index() {
const { logout } = useAppState();

return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home Screen</Text>
<Link href="/(app)/(modal)/settings">Present modal</Link>

<Text
onPress={() => {
// The `app/(app)/_layout.tsx` will redirect to the sign-in screen.
logout();
}}
>
Sign Out
</Text>
</View>
);
}
export { POS as default } from '@wcpos/core/screens/main/pos/pos';
53 changes: 39 additions & 14 deletions apps/main/app/(app)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { Redirect, Stack } from 'expo-router';
import { useObservableEagerState } from 'observable-hooks';

import { useAppState } from '@wcpos/core/contexts/app-state';
import { useLocale } from '@wcpos/core/hooks/use-locale';
import { ExtraDataProvider } from '@wcpos/core/screens/main/contexts/extra-data';
import { UISettingsProvider } from '@wcpos/core/screens/main/contexts/ui-settings';
import { Errors } from '@wcpos/core/screens/main/errors';
import { useRestHttpClient } from '@wcpos/core/screens/main/hooks/use-rest-http-client';
import { OnlineStatusProvider } from '@wcpos/hooks/use-online-status';
import { QueryProvider } from '@wcpos/query';

export const unstable_settings = {
// Ensure that reloading on `/modal` keeps a back button present.
Expand All @@ -9,25 +17,42 @@ export const unstable_settings = {

export default function AppLayout() {
const { site, storeDB, fastStoreDB } = useAppState();
const wpAPIURL = useObservableEagerState(site.wp_api_url$);
const { locale } = useLocale();

/**
* The http client should be smarter, ie: if offline or no auth, it should pause the replications
* or put this as part of the OnlineStatusProvider
*/
const http = useRestHttpClient();

if (!storeDB) {
return <Redirect href="/(auth)/connect" />;
}

return (
<Stack>
<Stack.Screen
name="(drawer)"
options={{
headerShown: false,
}}
/>
<Stack.Screen
name="(modal)/settings"
options={{
presentation: 'modal',
}}
/>
</Stack>
<ExtraDataProvider>
<QueryProvider localDB={storeDB} fastLocalDB={fastStoreDB} http={http} locale={locale}>
<UISettingsProvider>
<OnlineStatusProvider wpAPIURL={wpAPIURL}>
<Stack>
<Stack.Screen
name="(drawer)"
options={{
headerShown: false,
}}
/>
<Stack.Screen
name="(modal)/settings"
options={{
presentation: 'modal',
}}
/>
</Stack>
</OnlineStatusProvider>
</UISettingsProvider>
<Errors /> {/* TODO - we need a app-wide event bus to channel errors to the snackbar */}
</QueryProvider>
</ExtraDataProvider>
);
}
18 changes: 16 additions & 2 deletions apps/main/app/(auth)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import { Stack } from 'expo-router';
import { Stack, Redirect } from 'expo-router';

import { useAppState } from '@wcpos/core/contexts/app-state';

export const unstable_settings = {
// Ensure that reloading on `/modal` keeps a back button present.
initialRouteName: 'connect',
};

export default function AuthLayout() {
const { storeDB } = useAppState();

if (storeDB) {
return <Redirect href="/" />;
}

return (
<Stack screenOptions={{ headerShown: false }}>
<Stack.Screen name="connect" />
<Stack.Screen
name="login"
options={{
presentation: 'modal',
presentation: 'transparentModal',
animation: 'fade',
headerShown: false,
}}
/>
Expand Down
12 changes: 1 addition & 11 deletions apps/main/app/(auth)/login.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1 @@
import { View } from 'react-native';

import { Text } from '@wcpos/components/text';

export default function Login() {
return (
<View>
<Text>Login</Text>
</View>
);
}
export { Login as default } from '@wcpos/core/screens/auth/login';
1 change: 1 addition & 0 deletions apps/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"preset": "jest-expo"
},
"dependencies": {
"@react-native-community/netinfo": "11.4.1",
"@react-navigation/drawer": "^7.1.1",
"@react-navigation/native": "7.0.14",
"@shopify/flash-list": "1.7.3",
Expand Down
Loading

0 comments on commit e0f5ec3

Please sign in to comment.