Skip to content

Commit

Permalink
Feature/events search re 1910 (#775)
Browse files Browse the repository at this point in the history
* feat(event): serach WIP

* WIP

* feat: events filter desktop WIP

* feat: search mobile

* feat: search ipad
  • Loading branch information
OverGlass committed May 14, 2024
1 parent 058115e commit 5b18cb6
Show file tree
Hide file tree
Showing 20 changed files with 3,062 additions and 2,263 deletions.
7 changes: 3 additions & 4 deletions .storybook/storybook.requires.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const normalizedStories = [
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
/^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/,
// @ts-ignore

req: require.context(
"../src",
true,
Expand All @@ -29,7 +29,7 @@ const normalizedStories = [
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
/^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/,
// @ts-ignore

req: require.context(
"../src/screens",
true,
Expand All @@ -46,7 +46,6 @@ const annotations = [

global.STORIES = normalizedStories;

// @ts-ignore
module?.hot?.accept?.();

if (!global.view) {
Expand All @@ -58,7 +57,7 @@ if (!global.view) {
const { importMap } = prepareStories({ storyEntries: normalizedStories });

global.view._preview.onStoriesChanged({
importFn: async (importPath: string) => importMap[importPath],
importFn: async (importPath) => importMap[importPath],
});

global.view._preview.onGetProjectAnnotationsChanged({
Expand Down
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
6 changes: 4 additions & 2 deletions app/(tabs)/evenements/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react'
import BoundarySuspenseWrapper from '@/components/BoundarySuspenseWrapper'
import BottomSheetFilter from '@/components/EventFilterForm/BottomSheetFilters'
import EventFilterForm from '@/components/EventFilterForm/EventFilterForm'
import PageLayout from '@/components/layouts/PageLayout/PageLayout'
import AppDownloadCTA from '@/components/ProfileCards/AppDownloadCTA/AppDownloadCTA'
import BotBilanCTA from '@/components/ProfileCards/BotBilanCTA/BotBilanCTA'
import ProcurationCTA from '@/components/ProfileCards/ProcurationCTA/ProcurationCTA'
import MyProfileCard from '@/components/ProfileCards/ProfileCard/MyProfileCard'
import ProfileLoginCTA from '@/components/ProfileCards/ProfileLoginCTA/ProfileLoginCTA'
Expand Down Expand Up @@ -39,6 +40,7 @@ const EventsScreen: React.FC = () => {
</YStack>
</PageLayout.SideBarLeft>
<PageLayout.MainSingleColumn>
<BottomSheetFilter />
<BoundarySuspenseWrapper
fallback={
<YStack gap="$4" padding="$8" $sm={{ paddingHorizontal: 0, paddingTop: '$4' }}>
Expand Down Expand Up @@ -91,7 +93,7 @@ const EventsScreen: React.FC = () => {
</BoundarySuspenseWrapper>
</PageLayout.MainSingleColumn>
<PageLayout.SideBarRight>
<BotBilanCTA />
<EventFilterForm />
</PageLayout.SideBarRight>
</PageLayout>
</>
Expand Down
18 changes: 8 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@
"@rehookify/datepicker": "^6.6.1",
"@ronradtke/react-native-markdown-display": "^8.0.0",
"@sentry/react-native": "5.19.1",
"@tamagui/babel-plugin": "^1.94.5",
"@tamagui/config": "^1.94.5",
"@tamagui/lucide-icons": "^1.94.5",
"@tamagui/metro-plugin": "^1.94.5",
"@tamagui/select": "1.94.5",
"@tamagui/toast": "^1.94.5",
"@tamagui/babel-plugin": "1.96.0",
"@tamagui/config": "1.96.0",
"@tamagui/lucide-icons": "1.96.0",
"@tamagui/metro-plugin": "1.96.0",
"@tamagui/select": "1.96.0",
"@tamagui/toast": "1.96.0",
"@tanstack/react-query": "^5.25.0",
"@testing-library/react-native": "^12.4.3",
"@types/qs": "^6.9.15",
Expand Down Expand Up @@ -126,7 +126,7 @@
"react-native-webview": "13.6.4",
"react-test-renderer": "18.1.0",
"sentry-expo": "~7.2.0",
"tamagui": "^1.94.5",
"tamagui": "1.96.0",
"tinycolor2": "^1.6.0",
"typescript": "^5.3.3",
"use-debounce": "^10.0.0",
Expand Down Expand Up @@ -165,7 +165,5 @@
"vite-tsconfig-paths": "^4.3.1"
},
"private": true,
"trustedDependencies": [
"@sentry/cli"
]
"trustedDependencies": ["@sentry/cli"]
}
9 changes: 8 additions & 1 deletion src/components/Bento/Inputs/components/inputsParts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,19 @@ export const defaultInputGroupStyles = {
backgroundColor: '$backgroundFocus',
placeHolderColor: '$color',
color: '$colorFocus',

hoverStyle: {
borderColor: '$borderColorFocus',
backgroundColor: '$backgroundFocus',
color: '$colorFocus',
},
},
} as const

const InputGroupFrame = styled(XGroup, {
justifyContent: 'space-between',
context: InputContext,
animation: 'quick',
variants: {
unstyled: {
false: defaultInputGroupStyles,
Expand Down Expand Up @@ -224,7 +231,7 @@ export const InputIconFrame = styled(View, {
size: {
'...size': (val, { tokens }) => {
return {
paddingHorizontal: '$2',
paddingHorizontal: val,
}
},
},
Expand Down
43 changes: 43 additions & 0 deletions src/components/Bento/radios/components/radioParts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { styled, View } from 'tamagui'

export const Card = styled(View, {
name: 'VoxRadio',
animation: 'bouncy',
variants: {
unstyled: {
false: {
justifyContent: 'center',
height: '$3',
cursor: 'pointer',
width: '100%',
borderRadius: '$4',
padding: '$3',
backgroundColor: '$background',
borderColor: '$borderColor',
borderWidth: 1,
focusStyle: {
backgroundColor: '$backgroundFocus',
borderColor: '$borderColorFocus',
},
hoverStyle: {
backgroundColor: '$backgroundHover',
borderColor: '$borderColorHover',
},
},
},
active: {
true: {
color: '$colorFocus',
hoverStyle: {
backgroundColor: '$backgroundFocus',
borderColor: '$borderColorFocus',
},
backgroundColor: '$backgroundFocus',
borderColor: '$borderColorFocus',
},
},
} as const,
defaultVariants: {
unstyled: process.env.TAMAGUI_HEADLESS === '1' ? true : false,
},
})
1 change: 1 addition & 0 deletions src/components/Cards/FeedCard/FeedCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type FeedCardProps =
} & NewsVoxCardProps)

const FeedCard = (props: FeedCardProps) => {
console.log('FeedCard', props)
switch (props.type) {
case 'event':
return <EventCard {...props} />
Expand Down
63 changes: 63 additions & 0 deletions src/components/EventFilterForm/BottomSheetFilters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useEffect } from 'react'
import { Keyboard } from 'react-native'
import EventFilterForm from '@/components/EventFilterForm/EventFilterForm'
import VoxCard from '@/components/VoxCard/VoxCard'
import { Sheet, useMedia } from 'tamagui'
import { create } from 'zustand'

type BottomSheetFilterStates = {
open: boolean
position: number
setOpen: (open: boolean) => void
setPosition: (position: number) => void
}

export const bottomSheetFilterStates = create<BottomSheetFilterStates>((set) => ({
open: false,
position: 1,
setOpen: (open) => set({ open }),
setPosition: (position) => set({ position }),
}))

const BottomSheetFilter = () => {
const states = bottomSheetFilterStates()
const media = useMedia()
useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener('keyboardWillHide', () => {
states.setOpen(false)
})
return () => {
keyboardDidShowListener.remove()
}
})

return media.md ? (
<Sheet
dismissOnSnapToBottom
moveOnKeyboardChange
snapPointsMode="fit"
animation="medium"
onOpenChange={(open: boolean) => {
states.setOpen(open)
if (!open) {
Keyboard.dismiss()
}
}}
open={states.open}
modal
defaultOpen={false}
>
<Sheet.Overlay />
<Sheet.Frame overflow="hidden" bg="$white1" position="relative" flex={1}>
<Sheet.Handle backgroundColor="$gray9" mt="$3" height={5} />
<VoxCard bg="$colorTransparent">
<VoxCard.Content pt="$1">
<EventFilterForm />
</VoxCard.Content>
</VoxCard>
</Sheet.Frame>
</Sheet>
) : null
}

export default BottomSheetFilter
86 changes: 86 additions & 0 deletions src/components/EventFilterForm/EventFilterForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { RefObject } from 'react'
import { TextInput } from 'react-native'
import { LineSwitch } from '@/components/base/Switch/Switch'
import Text from '@/components/base/Text'
import { YStack } from 'tamagui'
import { create } from 'zustand'
import VoxCard from '../VoxCard/VoxCard'
import SearchBox from './SearchBox'
import { ZoneValue, zoneValues } from './ZoneFilter'

export type EventFilters = {
zone: ZoneValue
search: string
showPast: boolean
showCancelled: boolean
}

export type FiltersState = {
searchInputRef: React.RefObject<TextInput | null>
value: EventFilters
setValue: (value: EventFilters) => void
}

export const defaultEventFilters: EventFilters = {
zone: zoneValues[0],
search: '',
showPast: false,
showCancelled: false,
}

export const eventFiltersState = create<FiltersState>((set) => ({
searchInputRef: React.createRef(),
value: defaultEventFilters,
setValue: (x) => set({ value: x }),
}))

export const Controller = <N extends keyof EventFilters>(props: {
name: N
children: (p: { value: EventFilters[N]; onChange: (v: EventFilters[N]) => void; ref: FiltersState['searchInputRef'] | undefined }) => React.ReactNode
}) => {
const { value, setValue, searchInputRef } = eventFiltersState()
return props.children({
value: value[props.name],
onChange: (v) => setValue({ ...value, [props.name]: v }),
ref: props.name === 'search' ? searchInputRef : undefined,
})
}

type EventFiltersProps = {
onSearchFocus?: () => void
}

const EventFilters = ({ onSearchFocus }: EventFiltersProps) => {
return (
<VoxCard bg="$colorTransparent">
<YStack gap="$5">
<Controller name="search">
{(p) => <SearchBox enterKeyHint="done" value={p.value} ref={p.ref as RefObject<TextInput>} onChange={p.onChange} onFocus={onSearchFocus} />}
</Controller>
{/* <Controller name="zone">{(p) => <ZoneFilter {...p} />}</Controller> */}
<YStack gap="$3">
<Text fontWeight="$5">Temporalité</Text>
<Controller name="showPast">
{(p) => (
<LineSwitch checked={p.value} onCheckedChange={p.onChange}>
Afficher les évènements passées
</LineSwitch>
)}
</Controller>
{/* <Controller name="showCancelled">
{(p) => (
<LineSwitch checked={p.value} onCheckedChange={p.onChange}>
Afficher les évènements annulées
</LineSwitch>
)}
</Controller> */}
</YStack>
</YStack>
</VoxCard>
)
}
const MemoizedEF = React.memo(EventFilters)

MemoizedEF.displayName = 'EventFilters'

export default MemoizedEF
41 changes: 41 additions & 0 deletions src/components/EventFilterForm/SearchBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { ComponentProps, forwardRef, useCallback } from 'react'
import { TextInput, TextInputProps } from 'react-native'
import { useForwardRef } from '@/hooks/useForwardRef'
import { Search, XCircle } from '@tamagui/lucide-icons'
import Input from '../base/Input/Input'
import Button from '../Button/Button'

type SearchBoxProps = {
value: string
onChange: (value: string) => void
onFocus?: TextInputProps['onFocus']
} & Omit<ComponentProps<typeof Input>, 'value' | 'onChange' | 'onFocus'>

const SearchBox = forwardRef<TextInput, SearchBoxProps>(({ value, onChange, onFocus, ...rest }, ref) => {
const searchInputRef = useForwardRef(ref)

const IconRight = useCallback((props: { isInputFill: boolean }) => {
return props.isInputFill ? (
<Button variant="text" onPress={() => onChange('')}>
<XCircle />
</Button>
) : (
<Search />
)
}, [])

return (
<Input
placeholder="Rechercher un événement"
size={'$4'}
ref={searchInputRef}
value={value}
onFocus={onFocus}
iconRight={<IconRight isInputFill={value.length > 0} />}
onChangeText={onChange}
{...rest}
/>
)
})

export default SearchBox
Loading

0 comments on commit 5b18cb6

Please sign in to comment.