Skip to content

Commit

Permalink
Merge pull request #456 from icssc/frontend-changes-branched
Browse files Browse the repository at this point in the history
Frontend changes branched
  • Loading branch information
bjsilva1 authored Jun 4, 2024
2 parents 13f5f54 + d68b875 commit 6c5916a
Show file tree
Hide file tree
Showing 52 changed files with 6,142 additions and 4,898 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.12.1
lts/*
9 changes: 9 additions & 0 deletions apps/expo/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Config } from "jest";

export default {
verbose: true,
preset: "jest-expo",
transformIgnorePatterns: [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)",
],
} satisfies Config;
11 changes: 10 additions & 1 deletion apps/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"ios": "expo run:ios",
"format": "prettier --check . --ignore-path ../../.gitignore",
"lint": "eslint .",
"_test": "jest",
"typecheck": "tsc --noEmit"
},
"dependencies": {
Expand Down Expand Up @@ -46,6 +47,7 @@
"expo-splash-screen": "~0.26.4",
"expo-status-bar": "~1.11.1",
"react": "18.2.0",
"react-datepicker": "^6.9.0",
"react-dom": "18.2.0",
"react-native": "~0.73.6",
"react-native-css-interop": "~0.0.34",
Expand All @@ -62,15 +64,22 @@
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"@babel/preset-typescript": "^7.24.6",
"@babel/runtime": "^7.24.0",
"@jest/globals": "^29.7.0",
"@testing-library/react-native": "^12.5.1",
"@types/react-datepicker": "^6.2.0",
"@zotmeal/eslint-config": "workspace:^0.2.0",
"@zotmeal/prettier-config": "workspace:^0.1.0",
"@zotmeal/tailwind-config": "workspace:^0.1.0",
"@zotmeal/tsconfig": "workspace:^0.1.0",
"@zotmeal/ui": "workspace:^",
"eslint": "^8.57.0",
"jest": "^29.7.0",
"jest-expo": "^50.0.4",
"prettier": "^3.2.5",
"react-test-renderer": "^18.2.0",
"tailwindcss": "^3.4.3",
"ts-jest": "^29.1.4",
"typescript": "^5.4.3"
},
"eslintConfig": {
Expand Down
10 changes: 10 additions & 0 deletions apps/expo/src/__tests__/app.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
import renderer from "react-test-renderer";
import { Logo } from "~/components";

describe("<App />", () => {
it("has 1 child", () => {
const tree = renderer.create(<Logo />).toJSON();
expect(tree.children.length).toBe(1);
});
});
35 changes: 6 additions & 29 deletions apps/expo/src/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,36 @@ import { config } from "@tamagui/config/v3";

import "@tamagui/core/reset.css";

import type { TokenCache } from "@clerk/clerk-expo/dist/cache";
import type { FontSource } from "expo-font";
import { useColorScheme } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useFonts } from "expo-font";
import { Stack } from "expo-router";
import * as SecureStore from "expo-secure-store";
import { StatusBar } from "expo-status-bar";
import { ClerkProvider } from "@clerk/clerk-expo";
import InterBold from "@tamagui/font-inter/otf/Inter-Bold.otf";
import Inter from "@tamagui/font-inter/otf/Inter-Medium.otf";
import { ToastProvider, ToastViewport } from "@tamagui/toast";
import { createTamagui, TamaguiProvider, Theme } from "tamagui";

import Logo from "~/components/Logo";
import { Logo } from "~/components";
import { HamburgerMenu } from "~/components/navigation/HamburgerMenu";
import { TRPCProvider } from "~/utils";
import { TRPCProvider, useZotmealColorScheme } from "~/utils";
import { tokenCache } from "~/utils/tokenCache";
import { env } from "../utils/env";

// Main layout of the app
// It wraps your pages with the providers they need

const tamaguiConfig = createTamagui(config);

const tokenCache: TokenCache = {
async getToken(key: string) {
try {
return SecureStore.getItemAsync(key);
} catch (err) {
return null;
}
},
async saveToken(key: string, value: string) {
try {
await SecureStore.setItemAsync(key, value);
} catch (err) {
console.error(err);
}
},
};

export default function RootLayout() {
const [loaded] = useFonts({
Inter: Inter as FontSource,
InterBold: InterBold as FontSource,
});

const colorScheme = useColorScheme();
const colorScheme = useZotmealColorScheme();

const { bottom, left, right } = useSafeAreaInsets();

if (!loaded) {
return null;
}
if (!loaded) return null;

return (
<TRPCProvider>
Expand Down
7 changes: 3 additions & 4 deletions apps/expo/src/app/events/event/[title].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import {
Separator,
Square,
Text,
View,
XStack,
YStack,
} from "tamagui";

import type { Event } from "@zotmeal/db";

import useZotmealStore from "~/utils/useZotmealStore";
import { useZotmealStore } from "~/utils";

export default function Event() {
const { title } = useGlobalSearchParams();
Expand Down Expand Up @@ -57,9 +58,6 @@ export default function Event() {
justifyContent: "center",
alignItems: "center",
}}
contentInset={{
bottom: 100,
}}
>
<YStack
justifyContent="center"
Expand Down Expand Up @@ -130,6 +128,7 @@ export default function Event() {
</Accordion.Content>
</Accordion.Item>
</Accordion>
<View height={100} />
</ScrollView>
</>
);
Expand Down
54 changes: 30 additions & 24 deletions apps/expo/src/app/events/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useEffect } from "react";
import { Link } from "expo-router";
import { CalendarX2 } from "@tamagui/lucide-icons";
import { format } from "date-fns";
import { H3, Image, Tabs, Text, YStack } from "tamagui";
import { H3, Image, Spinner, Tabs, Text, View, YStack } from "tamagui";

import type { Event } from "@zotmeal/db";
import { getRestaurantNameById } from "@zotmeal/utils";

import { RestaurantTabs } from "~/components";
import { useZotmealStore } from "~/utils";
import { api } from "~/utils/api";
import useZotmealStore from "~/utils/useZotmealStore";

// Create a context for events, default value is a test event
const _testData = {
Expand Down Expand Up @@ -95,32 +96,37 @@ export default function Events() {
setBrandywineEvents(brandywineEvents);
}, [eventsQuery.data, setAnteateryEvents, setBrandywineEvents]);

if (eventsQuery?.isLoading) {
return <Text>Loading...</Text>;
}
// TODO: show a toast if there is an error
if (eventsQuery?.isError) console.error(eventsQuery.error);

if (eventsQuery?.isError) {
return <Text>Error: {eventsQuery.error.message}</Text>;
}

if (!anteateryEvents || !brandywineEvents) {
return <Text>No events found</Text>;
}
const EventsContent = () =>
eventsQuery.isLoading ? (
<Spinner size="large" marginTop="$10" />
) : brandywineEvents && anteateryEvents ? (
<>
{[brandywineEvents, anteateryEvents].map((events, index) => (
<Tabs.Content
key={index}
value={getRestaurantNameById(index === 0 ? "3314" : "3056")}
>
<YStack>
{events.map((event, index) => (
<EventCard key={index} event={event} />
))}
</YStack>
</Tabs.Content>
))}
</>
) : (
<View alignItems="center">
<CalendarX2 size="$10" />
<Text>Events not found</Text>
</View>
);

return (
<RestaurantTabs>
{[brandywineEvents, anteateryEvents].map((events, index) => (
<Tabs.Content
key={index}
value={getRestaurantNameById(index === 0 ? "3314" : "3056")}
>
<YStack>
{events.map((event, index) => (
<EventCard key={index} event={event} />
))}
</YStack>
</Tabs.Content>
))}
<EventsContent />
</RestaurantTabs>
);
}
52 changes: 52 additions & 0 deletions apps/expo/src/app/home/_components/date-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useState } from "react";
import { Platform } from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
import { CalendarDays } from "@tamagui/lucide-icons";
import { endOfWeek, startOfWeek } from "date-fns";
import { Button } from "tamagui";

/**
* Native date picker for iOS and Android.
*
* Platform handling from an issue thread:
*
* @see https://github.com/react-native-datetimepicker/datetimepicker/issues/54
*/
export const UniversalDatePicker = ({
date,
setDate,
}: Readonly<{ date: Date; setDate: (date: Date) => void }>) => {
const [showDatePicker, setShowDatePicker] = useState<boolean>(true);

return (
<>
{Platform.OS === "android" && (
<Button
onPress={() => setShowDatePicker(true)}
icon={CalendarDays}
scaleIcon={1.5}
size="$5"
borderRadius="$10"
pressTheme
>
{date.toLocaleDateString("en-US")}
</Button>
)}
{showDatePicker && (
<DateTimePicker
value={date}
mode="date"
minimumDate={startOfWeek(new Date())}
maximumDate={endOfWeek(new Date())}
onChange={(_, selectedDate) => {
// hide date picker on android
setShowDatePicker(Platform.OS === "ios");
if (selectedDate) {
setDate(selectedDate);
}
}}
/>
)}
</>
);
};
49 changes: 49 additions & 0 deletions apps/expo/src/app/home/_components/date-picker.web.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react";
import { endOfWeek, startOfWeek } from "date-fns";
import DatePicker from "react-datepicker";

import "react-datepicker/dist/react-datepicker.css";

import { CalendarDays } from "@tamagui/lucide-icons";
import { Button, ButtonProps, TamaguiElement } from "tamagui";

interface UniversalDatePickerProps {
date: Date;
setDate: (date: Date) => void;
}

interface CustomInputProps {
value: HTMLInputElement["value"];
onClick: ButtonProps["onPress"];
}

/**
* Universal date picker for web.
*/
export const UniversalDatePicker = ({
date,
setDate,
}: Readonly<UniversalDatePickerProps>) => {
/**
* Courtesy of issue thread:
* @see https://github.com/Hacker0x01/react-datepicker/issues/2165#issuecomment-711032947
*/
const CustomInput = (
{ value, onClick }: CustomInputProps,
ref: React.Ref<TamaguiElement>,
) => (
<Button icon={CalendarDays} onPress={onClick} ref={ref}>
{value}
</Button>
);

return (
<DatePicker
customInput={React.createElement(React.forwardRef(CustomInput))}
selected={date}
minDate={startOfWeek(new Date())}
maxDate={endOfWeek(new Date())}
onChange={(prev) => setDate(prev ?? new Date())}
/>
);
};
Loading

0 comments on commit 6c5916a

Please sign in to comment.