Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup SearchFilters framing #26

Merged
merged 11 commits into from
Oct 20, 2024
164 changes: 164 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Upcoming TODOs

## Development ease

- [X] Create some [common snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_create-your-own-snippets)
- Start with below
```javascript
// Snippet #1
<View style={ruffwind``}></View>
// Snippet #2
style={ruffwind``}
```
- Note: This updated in `~/Library/Application Support/Code/User/snippets/typescriptreact.json`
- [ ] Personal side quest: what happened with script generation of Week 43?
- [ ] Personal side quest: when should it generate?
- [ ] Personal side quest: when should it generate
- [ ] Personal side quest: fix tasks from duplicating
- [ ] Personal side quest: fix typography

## Finish framing and styles on SearchFilters page

- [x] Put in mock time of day (either radio placeholder or input)
- [x] Radio group - handle flex direction
- [x] Add styles for search button and clear filters link
- [ ] Test bottomsheet for date (create a simple button to open bottomsheet just ot make sure things are copasetic)
- [ ] Test input opens keyboard on dashboard and filters page

## Setup on other computer

- [ ] Merge "Finish framing and styles on SearchFilters page" work
- [ ] Download onto other laptop
- [ ] Document any setup discrepencies
- [ ] Push updates to README

## Add framing and styles on SearchResults page

- [ ] Add base styles and framing
- [ ] Add filters modal styles and framing
- [ ] Add mock map (image is fine)
- [ ] Add mock search results

## Can I send a base build to Sara?

- [ ] Ensure navigation goes to _coming soon_ pages
- [ ] Final "walk though of pet profiles and dashboard/search pages to confirm workflows"
- [ ] Add app icon to build
- [ ] Expo build and export

## Add new form components

- [ ] Add checkbox group component
- [ ] Implement checkbox group in search filters page
- [ ] Add date picker component
- [ ] Handle single date selection
- [ ] Handle range selection
- [ ] Add date picker modal
- [ ] Add date picker dropdown
- [ ] Implement date picker in search filters page
- [ ] Update Button with count notification
- [ ] Add Dropdown with count notification
- [ ] Add price range selector component

## Handle map

- [ ] Test different maps
- [ ] Build protoype with behaviors
- [ ] Zoom in
- [ ] See visible circle range
- [ ] Handle grouping caretakers by section to protect privacy
- [ ] What is the physical radius we need to adhere to?
- [ ] Handle selecting a price on map, opens caretaker profile in modal
- [ ] Modal can slide up for more information
- [ ] Modal is scrollable
- [ ] Handle how multiple prices stacked in a map are still visible
- [ ] How can we prevent them from fully stacking? Or... if we stack.. can we open some sort of secondary screen? Or if we stack and click on a stack - can all results in a stack appear in the results bottomsheet? (last option seems smallest level of lift and easiest accessibility)
- [ ] Ideation:
- [ ] if a stack has <= 3, display all three prices next to each other
- [ ] if a stack has > 3, display "from $XX (3+)"
- [ ] if they click on that, it opens all results in that stack in the results modal as list instead of a single profile with a header that lets you know your in the stack and can take you back to your previous view/search/etc

## Form and API work

- [ ] Dashboard
- [ ] Add location search input using mock location API
- [ ] Implement location serach input in search filters page and search dashboard page
- [ ] Implement favoriting with mock API call
- [ ] Ensure navigation goes to _coming soon_ pages
- [ ] Filters
- [ ] Convert to form
- [ ] Manage clear all button
- [ ] Manage submit to search API
- [ ] Results
- [ ] Add styles and framing
- [ ] Add filters modal styles and framing
- [ ] Add map handling and styles
- [ ] Add search results displaying
- [ ] Handle filters form
- [ ] Handle filters submission to caretakers search API and refresh on page
- [ ] Handle dropdown count notification on filters and pets
- [ ] Handle date dropdown
- [ ] Handle date submission to caretakers search API and refresh on page
- [ ] Handle my pets dropdown
- [ ] Handle my pets submission to caretakers search API and refresh on page
- [ ] Handle no pets and going to access or pet profile splash pages
- [ ] Update filters based on selected pet(s)

## Backend work

- [ ] Add caretakers API using mock db data
- [ ] Source and add location API wrapper
- [ ] Add caretaker search service
- [ ] Add petowner api
- [ ] Add access workflows
- [ ] account api
- [ ] passwordless login via email
- [ ] social via google
- [ ] social via apple
- [ ] Add pet profile api
- [ ] Research a cloud option for things like images and other pieces - probably start with AWS b/c easy enough to get started
- [ ] Add image saving pathway - firebase? s3? etc?

## Cleanup

- [ ] Jest tests for every UI component
- [ ] Rspec tests for every unit and integration
- [ ] Implement basic testing CI
- [ ] Can I afford to spend time on e2e?
- [ ] Cypress?
- [ ] Capybara?
- [ ] Option 3?

## Access workflows

- [ ] Add onboarding pages
- [ ] Add email workflow pages
- [ ] Add guest workflow pages
- [ ] Add profile setup pages
- [ ] Add apple login workflow pages
- [ ] Add google login workflow pages
- [ ] Add app icon to build
- [ ] Research and add splash animation

## Next work

- [ ] Access needed profile splash updates
- [ ] Caretaker profile
- [ ] Booking prototype
- [ ] Account prototype

## Next next steps

- [ ] Messaging prototype
- [ ] Petowner view prototype
- [ ] Pet profile view prototype
- [ ] Caretaker account creation prototype

## Future work [if Sara designs]

- [ ] Petowner profile view
- [ ] Pet profile view
- [ ] Bookings
- [ ] Account
- [ ] Messaging
- [ ] Caretaker account creation
11 changes: 8 additions & 3 deletions apps/rufferal/src/app/screens/Screens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export const Screens = observer(() => {
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
{/* ⬇️⬇️⬇️ CURRENT DEVELOPMENT PAGE ⬇️⬇️⬇️ */}
<Stack.Screen name="Search Filters" component={SearchFiltersScreen} />
<Stack.Screen
name="Search Dashboard"
component={SearchDashboardScreen}
/>
{/* ⬆️⬆️⬆️ CURRENT DEVELOPMENT PAGE ⬆️⬆️⬆️ */}

<Stack.Screen name="Pet Splash" component={PetSplashScreen} />
Expand All @@ -38,11 +43,11 @@ export const Screens = observer(() => {
<Stack.Screen name="Dog Avatar" component={DogAvatarScreen} />
<Stack.Screen name="Dog Personality" component={DogPersonalityScreen} />
<Stack.Screen name="Dog Careplan" component={DogCareplanScreen} />
<Stack.Screen
{/* <Stack.Screen
name="Search Dashboard"
component={SearchDashboardScreen}
/>
<Stack.Screen name="Search Filters" component={SearchFiltersScreen} />
/> */}
{/* <Stack.Screen name="Search Filters" component={SearchFiltersScreen} /> */}
<Stack.Screen name="Search Results" component={SearchResultsScreen} />
<Stack.Screen name="Profile Splash" component={ProfileSplashScreen} />
</Stack.Navigator>
Expand Down
Binary file added assets/src/icons/rotate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions types/src/ui/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export interface FieldInputProps

export interface LabelProps {
text: string;
size?: Extract<FieldSize, 'default' | 'large' | 'xlarge' | '2xlarge'>;
state?: FieldState;
}

Expand All @@ -154,6 +155,16 @@ export interface ItemProps extends PressableProps {
height?: string;
}

export interface LinkButtonProps extends PressableProps {
containerStyles?: string;
iconLeft?: React.JSX.Element;
iconRight?: React.JSX.Element;
state?: FieldState;
text?: string;
textStyles?: string;
underlineStyles?: string;
}

export interface ProgressBarProps {
step: number;
total: number;
Expand Down
11 changes: 10 additions & 1 deletion types/src/ui/fields.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
export type FieldSize = 'standard' | 'standard-short' | 'small' | 'small-short';
export type FieldSize =
| 'xxsmall'
| 'xsmall'
| 'small'
| 'medium'
| 'default'
| 'large'
| 'xlarge'
| '2xlarge'
| '3xlarge';

export type FieldState = 'default' | 'errored' | 'disabled';

Expand Down
29 changes: 29 additions & 0 deletions types/src/ui/molecules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,34 @@ import {
FieldInputProps,
FieldOption,
FieldSelectProps,
FieldSize,
SingleSliderProps,
ToggleProps,
} from '..';

export interface CheckboxCardProps {
containerDirection?: string;
containerGap?: string;
defaultColumnCount?: number;
optionDirection?: string;
optionGap?: string;
optionHeight?: string;
optionSelectedBackground?: string;
optionSelectedBorder?: string;
optionText?: string;
optionUnselectedBackground?: string;
optionUnselectedBorder?: string;
}

export interface CheckboxCardOptionProps
extends Omit<CheckboxCardProps, 'containerDirection' | 'containerGap'> {
heightStyle?: string;
icon?: JSX.Element;
label: string;
onPress: (option: FieldOption) => void;
selected?: boolean;
}

export interface CheckToggleProps extends ToggleProps {
disabled?: boolean;
errorMessage?: string;
Expand Down Expand Up @@ -53,12 +77,17 @@ export interface PhotoModalProps {
}

export interface RadioGroupProps {
containerGap?: string;
data: FieldOption[];
disabled?: boolean;
errorMessage?: string;
label?: string;
labelSize?: Extract<FieldSize, 'default' | 'large' | 'xlarge' | '2xlarge'>;
onBlur?: () => void;
onChange: (item: FieldOption) => void;
optionsDirection?: string;
optionsGap?: string;
optionsYPadding?: string;
value?: FieldOption | null;
}

Expand Down
9 changes: 4 additions & 5 deletions ui/src/components/atoms/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
import { ActivityIndicator, Pressable, Text, View } from 'react-native';

const BUTTON_STYLES = ruffwind`
w-full
justify-center
items-center
`;
Expand All @@ -21,7 +20,7 @@ export const Button = ({
loading,
onPress,
rounded = true,
size = 'standard',
size = 'default',
state = 'default',
text = 'Continue',
iconRight,
Expand All @@ -38,15 +37,15 @@ export const Button = ({
let loadingColor = 'white';

switch (size) {
case 'standard-short':
case 'xsmall':
width = `w-${horizontalScaleTW(150)}`;
height = `h-${moderateScaleTW(36)}`;
fontStyles = 'font-bodyBold text-b3';
break;
case 'small':
width = `w-${horizontalScaleTW(150)}`;
break;
case 'small-short':
width = `w-${horizontalScaleTW(150)}`;
case 'medium':
height = `h-${moderateScaleTW(36)}`;
fontStyles = 'font-bodyBold text-b3';
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { fireEvent, render } from '@testing-library/react-native';
import { CheckboxCardOption } from './checkbox-card-option';

describe('CheckboxCardOption', () => {
const mockOnPress = jest.fn();

afterEach(() => {
jest.clearAllMocks();
});

it('renders with correct label and default state', () => {
const { getByText } = render(
<CheckboxCardOption label="Test Option" onPress={mockOnPress} />
);

const label = getByText('Test Option');
expect(label).toBeTruthy();
});

it('toggles selection state when pressed', () => {
const { getByText } = render(
<CheckboxCardOption label="Test Option" onPress={mockOnPress} />
);

const option = getByText('Test Option').parent.parent;

expect(option).not.toHaveStyle({
backgroundColor: '#F6E8FF',
borderColor: '#9525CB',
});

// Press the option
fireEvent.press(option.parent);

// Check if onPress was called with correct arguments
expect(mockOnPress).toHaveBeenCalledWith({
label: 'Test Option',
value: 'Test Option',
});

expect(option).toHaveStyle({
backgroundColor: '#F6E8FF',
borderColor: '#9525CB',
});

// Press again to toggle back
fireEvent.press(option.parent);

// Check if onPress was called again
expect(mockOnPress).toHaveBeenCalledTimes(2);
});
});
Loading