From d6fd6a225b3e54c0ed9b94056ac51f253f80e1a2 Mon Sep 17 00:00:00 2001 From: JaPatryk Date: Sun, 1 Jun 2025 09:33:08 +0200 Subject: [PATCH] add filter and cleat btn --- ArtisanConnect/app/(tabs)/notices.jsx | 57 +- .../components/ui/actionsheet/index.tsx | 569 ++++++++++++++++++ ArtisanConnect/package-lock.json | 12 +- 3 files changed, 625 insertions(+), 13 deletions(-) create mode 100644 ArtisanConnect/components/ui/actionsheet/index.tsx diff --git a/ArtisanConnect/app/(tabs)/notices.jsx b/ArtisanConnect/app/(tabs)/notices.jsx index d478f0d..957fdf9 100644 --- a/ArtisanConnect/app/(tabs)/notices.jsx +++ b/ArtisanConnect/app/(tabs)/notices.jsx @@ -1,16 +1,31 @@ +// import React from "react" import {FlatList, Text, ActivityIndicator, RefreshControl} from "react-native"; import {useState, useEffect} from "react"; +import { Ionicons } from "@expo/vector-icons"; import {useNoticesStore} from "@/store/noticesStore"; import {NoticeCard} from "@/components/NoticeCard"; import { useLocalSearchParams } from "expo-router"; -import { HStack } from "@gluestack-ui/themed"; -import { Button, ButtonText } from "@components/ui/Button"; -import { Actionsheet } from "@components/ui/Actionsheet"; +import { HStack } from "@/components/ui/hstack" +import { Box } from "@/components/ui/box" +import { Button, ButtonText, ButtonIcon } from "@/components/ui/button"; +import { + Actionsheet, + ActionsheetContent, + ActionsheetItem, + ActionsheetItemText, + ActionsheetDragIndicator, + ActionsheetDragIndicatorWrapper, + ActionsheetBackdrop, +} from "@/components/ui/actionsheet" +import { useRouter } from "expo-router"; + export default function Notices() { const {notices, fetchNotices} = useNoticesStore(); const [refreshing, setRefreshing] = useState(false); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); + const [showActionsheet, setShowActionsheet] = useState(false) + const handleClose = () => setShowActionsheet(false) const params = useLocalSearchParams(); console.log("GET params:", params); @@ -18,6 +33,8 @@ export default function Notices() { loadData(); }, []); + + const loadData = async () => { setIsLoading(true); try { @@ -30,8 +47,10 @@ export default function Notices() { } }; - let filteredNotices = notices; + const router = useRouter(); + let filteredNotices = notices; + let filterActive = false; if (params.sort) { if( params.sort === "latest") { filteredNotices = [...filteredNotices].sort( @@ -44,8 +63,13 @@ export default function Notices() { filteredNotices = filteredNotices.filter( (notice) => notice.category === params.category ); + filterActive = true; } + if(params.attribute) { + filterActive = true; + } + const onRefresh = async () => { setRefreshing(true); try { @@ -65,9 +89,29 @@ export default function Notices() { return Nie udało sie pobrać listy. {error.message}; } - return ( - +<> + + + {filterActive && ( + )} + + + + + + + + + Kategoria + + + } /> + ); } \ No newline at end of file diff --git a/ArtisanConnect/components/ui/actionsheet/index.tsx b/ArtisanConnect/components/ui/actionsheet/index.tsx new file mode 100644 index 0000000..f50ebd4 --- /dev/null +++ b/ArtisanConnect/components/ui/actionsheet/index.tsx @@ -0,0 +1,569 @@ +'use client'; +import React from 'react'; +import { H4 } from '@expo/html-elements'; +import { createActionsheet } from '@gluestack-ui/actionsheet'; +import { + Pressable, + View, + Text, + ScrollView, + VirtualizedList, + FlatList, + SectionList, + PressableProps, + ViewStyle, +} from 'react-native'; +import { PrimitiveIcon, UIIcon } from '@gluestack-ui/icon'; +import { tva } from '@gluestack-ui/nativewind-utils/tva'; +import type { VariantProps } from '@gluestack-ui/nativewind-utils'; +import { cssInterop } from 'nativewind'; +import { + Motion, + AnimatePresence, + createMotionAnimatedComponent, + MotionComponentProps, +} from '@legendapp/motion'; + +const ItemWrapper = React.forwardRef< + React.ComponentRef, + PressableProps +>(function ItemWrapper({ ...props }, ref) { + return ; +}); + +type IMotionViewProps = React.ComponentProps & + MotionComponentProps; + +const MotionView = Motion.View as React.ComponentType; + +type IAnimatedPressableProps = React.ComponentProps & + MotionComponentProps; + +const AnimatedPressable = createMotionAnimatedComponent( + Pressable +) as React.ComponentType; + +export const UIActionsheet = createActionsheet({ + Root: View, + Content: MotionView, + Item: ItemWrapper, + ItemText: Text, + DragIndicator: View, + IndicatorWrapper: View, + Backdrop: AnimatedPressable, + ScrollView: ScrollView, + VirtualizedList: VirtualizedList, + FlatList: FlatList, + SectionList: SectionList, + SectionHeaderText: H4, + Icon: UIIcon, + AnimatePresence: AnimatePresence, +}); + +cssInterop(UIActionsheet, { className: 'style' }); +cssInterop(UIActionsheet.Content, { className: 'style' }); +cssInterop(ItemWrapper, { className: 'style' }); +cssInterop(UIActionsheet.ItemText, { className: 'style' }); +cssInterop(UIActionsheet.DragIndicator, { className: 'style' }); +cssInterop(UIActionsheet.DragIndicatorWrapper, { className: 'style' }); +cssInterop(UIActionsheet.Backdrop, { className: 'style' }); +cssInterop(UIActionsheet.ScrollView, { + className: 'style', + contentContainerClassName: 'contentContainerStyle', + indicatorClassName: 'indicatorStyle', +}); +cssInterop(UIActionsheet.VirtualizedList, { + className: 'style', + ListFooterComponentClassName: 'ListFooterComponentStyle', + ListHeaderComponentClassName: 'ListHeaderComponentStyle', + contentContainerClassName: 'contentContainerStyle', + indicatorClassName: 'indicatorStyle', +}); +cssInterop(UIActionsheet.FlatList, { + className: 'style', + ListFooterComponentClassName: 'ListFooterComponentStyle', + ListHeaderComponentClassName: 'ListHeaderComponentStyle', + columnWrapperClassName: 'columnWrapperStyle', + contentContainerClassName: 'contentContainerStyle', + indicatorClassName: 'indicatorStyle', +}); +cssInterop(UIActionsheet.SectionList, { className: 'style' }); +cssInterop(UIActionsheet.SectionHeaderText, { className: 'style' }); + +cssInterop(PrimitiveIcon, { + className: { + target: 'style', + nativeStyleToProp: { + height: true, + width: true, + fill: true, + color: 'classNameColor', + stroke: true, + }, + }, +}); + +const actionsheetStyle = tva({ base: 'w-full h-full web:pointer-events-none' }); + +const actionsheetContentStyle = tva({ + base: 'items-center rounded-tl-3xl rounded-tr-3xl p-5 pt-2 bg-background-0 web:pointer-events-auto web:select-none shadow-hard-5 border border-b-0 border-outline-100', +}); + +const actionsheetItemStyle = tva({ + base: 'w-full flex-row items-center p-3 rounded-sm data-[disabled=true]:opacity-40 data-[disabled=true]:web:pointer-events-auto data-[disabled=true]:web:cursor-not-allowed hover:bg-background-50 active:bg-background-100 data-[focus=true]:bg-background-100 web:data-[focus-visible=true]:bg-background-100 web:data-[focus-visible=true]:outline-indicator-primary gap-2', +}); + +const actionsheetItemTextStyle = tva({ + base: 'text-typography-700 font-normal font-body', + variants: { + isTruncated: { + true: '', + }, + bold: { + true: 'font-bold', + }, + underline: { + true: 'underline', + }, + strikeThrough: { + true: 'line-through', + }, + size: { + '2xs': 'text-2xs', + 'xs': 'text-xs', + 'sm': 'text-sm', + 'md': 'text-base', + 'lg': 'text-lg', + 'xl': 'text-xl', + '2xl': 'text-2xl', + '3xl': 'text-3xl', + '4xl': 'text-4xl', + '5xl': 'text-5xl', + '6xl': 'text-6xl', + }, + }, +}); + +const actionsheetDragIndicatorStyle = tva({ + base: 'w-16 h-1 bg-background-400 rounded-full', +}); + +const actionsheetDragIndicatorWrapperStyle = tva({ + base: 'w-full py-1 items-center', +}); + +const actionsheetBackdropStyle = tva({ + base: 'absolute left-0 top-0 right-0 bottom-0 bg-background-dark web:cursor-default web:pointer-events-auto', +}); + +const actionsheetScrollViewStyle = tva({ + base: 'w-full h-auto', +}); + +const actionsheetVirtualizedListStyle = tva({ + base: 'w-full h-auto', +}); + +const actionsheetFlatListStyle = tva({ + base: 'w-full h-auto', +}); + +const actionsheetSectionListStyle = tva({ + base: 'w-full h-auto', +}); + +const actionsheetSectionHeaderTextStyle = tva({ + base: 'leading-5 font-bold font-heading my-0 text-typography-500 p-3 uppercase', + variants: { + isTruncated: { + true: '', + }, + bold: { + true: 'font-bold', + }, + underline: { + true: 'underline', + }, + strikeThrough: { + true: 'line-through', + }, + size: { + '5xl': 'text-5xl', + '4xl': 'text-4xl', + '3xl': 'text-3xl', + '2xl': 'text-2xl', + 'xl': 'text-xl', + 'lg': 'text-lg', + 'md': 'text-base', + 'sm': 'text-sm', + 'xs': 'text-xs', + }, + + sub: { + true: 'text-xs', + }, + italic: { + true: 'italic', + }, + highlight: { + true: 'bg-yellow500', + }, + }, + defaultVariants: { + size: 'xs', + }, +}); + +const actionsheetIconStyle = tva({ + base: 'text-background-500 fill-none', + variants: { + size: { + '2xs': 'h-3 w-3', + 'xs': 'h-3.5 w-3.5', + 'sm': 'h-4 w-4', + 'md': 'w-[18px] h-[18px]', + 'lg': 'h-5 w-5', + 'xl': 'h-6 w-6', + }, + }, +}); + +type IActionsheetProps = VariantProps & + React.ComponentPropsWithoutRef; + +type IActionsheetContentProps = VariantProps & + React.ComponentPropsWithoutRef & { + className?: string; + }; + +type IActionsheetItemProps = VariantProps & + React.ComponentPropsWithoutRef; + +type IActionsheetItemTextProps = VariantProps & + React.ComponentPropsWithoutRef; + +type IActionsheetDragIndicatorProps = VariantProps< + typeof actionsheetDragIndicatorStyle +> & + React.ComponentPropsWithoutRef; + +type IActionsheetDragIndicatorWrapperProps = VariantProps< + typeof actionsheetDragIndicatorWrapperStyle +> & + React.ComponentPropsWithoutRef; + +type IActionsheetBackdropProps = VariantProps & + React.ComponentPropsWithoutRef & { + className?: string; + }; + +type IActionsheetScrollViewProps = VariantProps< + typeof actionsheetScrollViewStyle +> & + React.ComponentPropsWithoutRef; + +type IActionsheetVirtualizedListProps = VariantProps< + typeof actionsheetVirtualizedListStyle +> & + React.ComponentPropsWithoutRef; + +type IActionsheetFlatListProps = VariantProps & + React.ComponentPropsWithoutRef; + +type IActionsheetSectionListProps = VariantProps< + typeof actionsheetSectionListStyle +> & + React.ComponentPropsWithoutRef; + +type IActionsheetSectionHeaderTextProps = VariantProps< + typeof actionsheetSectionHeaderTextStyle +> & + React.ComponentPropsWithoutRef; + +type IActionsheetIconProps = VariantProps & + React.ComponentPropsWithoutRef & { + className?: string; + as?: React.ElementType; + height?: number; + width?: number; + }; + +const Actionsheet = React.forwardRef< + React.ComponentRef, + IActionsheetProps +>(function Actionsheet({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetContent = React.forwardRef< + React.ComponentRef, + IActionsheetContentProps +>(function ActionsheetContent({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetItem = React.forwardRef< + React.ComponentRef, + IActionsheetItemProps +>(function ActionsheetItem({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetItemText = React.forwardRef< + React.ComponentRef, + IActionsheetItemTextProps +>(function ActionsheetItemText( + { + isTruncated, + bold, + underline, + strikeThrough, + size = 'sm', + className, + ...props + }, + ref +) { + return ( + + ); +}); + +const ActionsheetDragIndicator = React.forwardRef< + React.ComponentRef, + IActionsheetDragIndicatorProps +>(function ActionsheetDragIndicator({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetDragIndicatorWrapper = React.forwardRef< + React.ComponentRef, + IActionsheetDragIndicatorWrapperProps +>(function ActionsheetDragIndicatorWrapper({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetBackdrop = React.forwardRef< + React.ComponentRef, + IActionsheetBackdropProps +>(function ActionsheetBackdrop({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetScrollView = React.forwardRef< + React.ComponentRef, + IActionsheetScrollViewProps +>(function ActionsheetScrollView({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetVirtualizedList = React.forwardRef< + React.ComponentRef, + IActionsheetVirtualizedListProps +>(function ActionsheetVirtualizedList({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetFlatList = React.forwardRef< + React.ComponentRef, + IActionsheetFlatListProps +>(function ActionsheetFlatList({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetSectionList = React.forwardRef< + React.ComponentRef, + IActionsheetSectionListProps +>(function ActionsheetSectionList({ className, ...props }, ref) { + return ( + + ); +}); + +const ActionsheetSectionHeaderText = React.forwardRef< + React.ComponentRef, + IActionsheetSectionHeaderTextProps +>(function ActionsheetSectionHeaderText( + { + className, + isTruncated, + bold, + underline, + strikeThrough, + size, + sub, + italic, + highlight, + ...props + }, + ref +) { + return ( + + ); +}); + +const ActionsheetIcon = React.forwardRef< + React.ComponentRef, + IActionsheetIconProps +>(function ActionsheetIcon({ className, size = 'sm', ...props }, ref) { + if (typeof size === 'number') { + return ( + + ); + } else if ( + (props.height !== undefined || props.width !== undefined) && + size === undefined + ) { + return ( + + ); + } + return ( + + ); +}); + +export { + Actionsheet, + ActionsheetContent, + ActionsheetItem, + ActionsheetItemText, + ActionsheetDragIndicator, + ActionsheetDragIndicatorWrapper, + ActionsheetBackdrop, + ActionsheetScrollView, + ActionsheetVirtualizedList, + ActionsheetFlatList, + ActionsheetSectionList, + ActionsheetSectionHeaderText, + ActionsheetIcon, +}; diff --git a/ArtisanConnect/package-lock.json b/ArtisanConnect/package-lock.json index d736031..6f0e69f 100644 --- a/ArtisanConnect/package-lock.json +++ b/ArtisanConnect/package-lock.json @@ -1704,7 +1704,9 @@ } }, "node_modules/@expo/html-elements": { - "version": "0.4.3", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@expo/html-elements/-/html-elements-0.4.2.tgz", + "integrity": "sha512-lNioCgdtOrCMMqzHY+PCTdyuWBTU4yMBlOzPSkS4YFIWt9bq0zexM2ZJkpybTXmowNdE3zHO93xxAmiA2yDi2w==", "license": "MIT" }, "node_modules/@expo/image-utils": { @@ -1999,6 +2001,8 @@ }, "node_modules/@gluestack-ui/actionsheet": { "version": "0.2.53", + "resolved": "https://registry.npmjs.org/@gluestack-ui/actionsheet/-/actionsheet-0.2.53.tgz", + "integrity": "sha512-93qHvq6BHezJ7wt2lce4OQ38wXCGsDtglj5nlmwo2T41vj4ubOtDVoSUhXT+hfH0EmRr0TxFNeFqIgesO46qVw==", "dependencies": { "@gluestack-ui/hooks": "0.1.13", "@gluestack-ui/overlay": "^0.1.22", @@ -2434,12 +2438,6 @@ "react-native-web": ">=0.19" } }, - "node_modules/@gluestack-ui/themed/node_modules/@expo/html-elements": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@expo/html-elements/-/html-elements-0.12.5.tgz", - "integrity": "sha512-28KWO88YKykKU7ke5sEQs5TivFRMs1Aktz13xxgqAf5rTgb+lka0VKVt3W2fG7ksbUQ407rtUqz7SEAq298NvQ==", - "license": "MIT" - }, "node_modules/@gluestack-ui/toast": { "version": "1.0.9", "dependencies": {