├── .gitignore ├── App.tsx ├── app.json ├── assets ├── adaptive-icon.png ├── display │ ├── image1.png │ ├── image10.png │ ├── image11.png │ ├── image12.png │ ├── image13.png │ ├── image14.png │ ├── image15.png │ ├── image16.png │ ├── image17.png │ ├── image18.png │ ├── image2.png │ ├── image3.png │ ├── image4.png │ ├── image5.png │ ├── image6.png │ ├── image7.png │ ├── image8.png │ └── image9.png ├── favicon.png ├── icon.png └── splash.png ├── babel.config.js ├── eas.json ├── gluestack-ui.config.ts ├── index.js ├── kitchensink-components ├── Banner.tsx ├── ExplorePage.tsx ├── Header.tsx ├── HomestayPage.tsx ├── LogoutAlertDialog.tsx ├── MobileBottomTabs.tsx ├── MobileModeChangeButton.tsx ├── MobileProfilePage.tsx ├── MobileSidebarActionsheet.tsx ├── Sidebar.tsx ├── WebSidebar.tsx ├── header │ ├── HeaderTabs.tsx │ ├── HomestayLogo.tsx │ ├── ToggleMode.tsx │ └── UserProfile.tsx ├── main-content │ ├── HomestayInformationFold.tsx │ ├── ListYourPlaceModal.tsx │ ├── MainContent.tsx │ ├── MainContentHeader.tsx │ ├── NewThisWeekFold.tsx │ └── PriceRangeSection.tsx └── sidebar │ ├── AmenitiesSection.tsx │ ├── BookingOptions.tsx │ ├── CustomerRatingSection.tsx │ ├── FiltersAppliedSection.tsx │ ├── PlaceTypeSection.tsx │ ├── PriceRangeSection.tsx │ └── SortBySection.tsx ├── metro.config.js ├── package-lock.json ├── package.json ├── readme.md ├── styles ├── index.ts ├── index.web.ts └── main.css ├── tsconfig.json ├── webpack.config.js ├── yarn-error.log └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | dist/ 4 | npm-debug.* 5 | *.jks 6 | *.p8 7 | *.p12 8 | *.key 9 | *.mobileprovision 10 | *.orig.* 11 | web-build/ 12 | ios/ 13 | 14 | # macOS 15 | .DS_Store 16 | 17 | # Temporary files created by Metro to check the health of the file watcher 18 | .metro-health-check* 19 | 20 | # @generated expo-cli sync-647791c5bd841d5c91864afb91c302553d300921 21 | # The following patterns were generated by expo-cli 22 | 23 | # OSX 24 | # 25 | .DS_Store 26 | 27 | # Xcode 28 | # 29 | build/ 30 | *.pbxuser 31 | !default.pbxuser 32 | *.mode1v3 33 | !default.mode1v3 34 | *.mode2v3 35 | !default.mode2v3 36 | *.perspectivev3 37 | !default.perspectivev3 38 | xcuserdata 39 | *.xccheckout 40 | *.moved-aside 41 | DerivedData 42 | *.hmap 43 | *.ipa 44 | *.xcuserstate 45 | project.xcworkspace 46 | 47 | # Android/IntelliJ 48 | # 49 | build/ 50 | .idea 51 | .gradle 52 | local.properties 53 | *.iml 54 | *.hprof 55 | .cxx/ 56 | *.keystore 57 | !debug.keystore 58 | 59 | # node.js 60 | # 61 | node_modules/ 62 | npm-debug.log 63 | yarn-error.log 64 | 65 | # Bundle artifacts 66 | *.jsbundle 67 | 68 | # CocoaPods 69 | /ios/Pods/ 70 | 71 | # Temporary files created by Metro to check the health of the file watcher 72 | .metro-health-check* 73 | 74 | # Expo 75 | .expo/ 76 | web-build/ 77 | dist/ 78 | 79 | # @end expo-cli -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SafeAreaView, StyleSheet } from "react-native"; 3 | import { GluestackUIProvider } from "@gluestack-ui/themed"; 4 | import { config } from "./gluestack-ui.config"; 5 | import HomestayPage from "./kitchensink-components/HomestayPage"; 6 | import { SSRProvider } from "@react-native-aria/utils"; 7 | import { useFonts } from "expo-font"; 8 | import { 9 | Inter_400Regular, 10 | Inter_500Medium, 11 | Inter_600SemiBold, 12 | Inter_700Bold, 13 | Inter_900Black, 14 | } from "@expo-google-fonts/inter"; 15 | import "./styles"; 16 | 17 | type ThemeContextType = { 18 | colorMode?: "dark" | "light"; 19 | toggleColorMode?: () => void; 20 | }; 21 | 22 | export const ThemeContext = React.createContext({ 23 | colorMode: "light", 24 | toggleColorMode: () => {}, 25 | }); 26 | 27 | export default function App() { 28 | const [colorMode, setColorMode] = React.useState<"dark" | "light">("light"); 29 | 30 | const [fontsLoaded] = useFonts({ 31 | Inter_400Regular, 32 | Inter_500Medium, 33 | Inter_600SemiBold, 34 | Inter_700Bold, 35 | Inter_900Black, 36 | }); 37 | 38 | if (!fontsLoaded) { 39 | return null; 40 | } 41 | 42 | const toggleColorMode = async () => { 43 | setColorMode((prev) => (prev === "light" ? "dark" : "light")); 44 | }; 45 | 46 | return ( 47 | <> 48 | {/* top SafeAreaView */} 49 | 54 | {/* bottom SafeAreaView */} 55 | 61 | {/* gluestack-ui provider */} 62 | 63 | 64 | {/* main app page */} 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | ); 73 | } 74 | 75 | const styles = StyleSheet.create({ 76 | container: { 77 | flex: 1, 78 | overflow: "hidden", 79 | }, 80 | }); 81 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "kitchensink-app", 4 | "slug": "kitchensink-app", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "jsEngine": "hermes", 9 | "userInterfaceStyle": "light", 10 | "splash": { 11 | "image": "./assets/splash.png", 12 | "resizeMode": "contain", 13 | "backgroundColor": "#ffffff" 14 | }, 15 | "assetBundlePatterns": ["**/*"], 16 | "ios": { 17 | "supportsTablet": true, 18 | "jsEngine": "hermes", 19 | "bundleIdentifier": "com.meenumakkar.ui-kitchensink" 20 | }, 21 | "android": { 22 | "adaptiveIcon": { 23 | "foregroundImage": "./assets/adaptive-icon.png", 24 | "backgroundColor": "#ffffff" 25 | }, 26 | "package": "com.meenumakkar.clitestexpo" 27 | }, 28 | "web": { 29 | "favicon": "./assets/favicon.png" 30 | }, 31 | "runtimeVersion": { 32 | "policy": "sdkVersion" 33 | }, 34 | "updates": { 35 | "url": "https://u.expo.dev/72e83d84-acc2-4675-a0a8-95d0f5fea5b4" 36 | }, 37 | "extra": { 38 | "eas": { 39 | "projectId": "72e83d84-acc2-4675-a0a8-95d0f5fea5b4" 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/adaptive-icon.png -------------------------------------------------------------------------------- /assets/display/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image1.png -------------------------------------------------------------------------------- /assets/display/image10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image10.png -------------------------------------------------------------------------------- /assets/display/image11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image11.png -------------------------------------------------------------------------------- /assets/display/image12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image12.png -------------------------------------------------------------------------------- /assets/display/image13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image13.png -------------------------------------------------------------------------------- /assets/display/image14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image14.png -------------------------------------------------------------------------------- /assets/display/image15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image15.png -------------------------------------------------------------------------------- /assets/display/image16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image16.png -------------------------------------------------------------------------------- /assets/display/image17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image17.png -------------------------------------------------------------------------------- /assets/display/image18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image18.png -------------------------------------------------------------------------------- /assets/display/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image2.png -------------------------------------------------------------------------------- /assets/display/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image3.png -------------------------------------------------------------------------------- /assets/display/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image4.png -------------------------------------------------------------------------------- /assets/display/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image5.png -------------------------------------------------------------------------------- /assets/display/image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image6.png -------------------------------------------------------------------------------- /assets/display/image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image7.png -------------------------------------------------------------------------------- /assets/display/image8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image8.png -------------------------------------------------------------------------------- /assets/display/image9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/display/image9.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/favicon.png -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gluestack/ui-examples/e4df1bcf5c617a569ecf40ab5f2f6dae9ffdab01/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ["babel-preset-expo"], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /eas.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "development": { 4 | "developmentClient": true, 5 | "distribution": "internal" 6 | }, 7 | "preview": { 8 | "distribution": "internal" 9 | }, 10 | "production": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /gluestack-ui.config.ts: -------------------------------------------------------------------------------- 1 | import { config as defaultConfig } from "@gluestack-ui/config"; 2 | 3 | export const config = { 4 | ...defaultConfig, 5 | tokens: { 6 | ...defaultConfig.tokens, 7 | colors: { 8 | ...defaultConfig.tokens.colors, 9 | primary0: "#ffffff", 10 | primary50: "#FFF1F2", 11 | primary100: "#FFE4E6", 12 | primary200: "#FECDD3", 13 | primary300: "#FDA4AF", 14 | primary400: "#EE596F", 15 | primary500: "#F43F5E", 16 | primary600: "#E11d48", 17 | primary600_alpha60: "#5C93C8", 18 | primary700: "#BE123C", 19 | primary800: "#9F1239", 20 | primary900: "#881337", 21 | primary950: "#440A1C", 22 | }, 23 | } as const, 24 | }; 25 | 26 | type Config = typeof config; 27 | declare module "@gluestack-ui/config" { 28 | interface IConfig extends Config {} 29 | } 30 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { registerRootComponent } from 'expo'; 2 | 3 | import App from './App'; 4 | 5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 6 | // It also ensures that whether you load the app in Expo Go or in a native build, 7 | // the environment is set up appropriately 8 | registerRootComponent(App); 9 | -------------------------------------------------------------------------------- /kitchensink-components/Banner.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HStack, Link, LinkText, Text } from "@gluestack-ui/themed"; 3 | 4 | const Banner = () => { 5 | return ( 6 | 16 | 23 | Show total prices up front 24 | 25 | 26 | 34 | Learn more 35 | 36 | 37 | 38 | ); 39 | }; 40 | export default Banner; 41 | -------------------------------------------------------------------------------- /kitchensink-components/ExplorePage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box, HStack } from "@gluestack-ui/themed"; 3 | import Banner from "./Banner"; 4 | import Header from "./Header"; 5 | import WebSidebar from "./WebSidebar"; 6 | import MainContent from "./main-content/MainContent"; 7 | import { ScrollView } from "react-native"; 8 | 9 | const Explorepage = ({ activeTab, setActiveTab }: any) => { 10 | return ( 11 | <> 12 | 18 | {/* top banner */} 19 | 20 | {/* header */} 21 |
22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ); 43 | }; 44 | 45 | export default Explorepage; 46 | -------------------------------------------------------------------------------- /kitchensink-components/Header.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Box, 4 | HStack, 5 | Input, 6 | InputField, 7 | InputIcon, 8 | InputSlot, 9 | } from "@gluestack-ui/themed"; 10 | import { SearchIcon } from "@gluestack-ui/themed"; 11 | import HeaderTabs from "./header/HeaderTabs"; 12 | import HomestayLogo from "./header/HomestayLogo"; 13 | import ToggleMode from "./header/ToggleMode"; 14 | import UserProfile from "./header/UserProfile"; 15 | 16 | const Header = React.memo(() => { 17 | return ( 18 | 19 | {/* big screen */} 20 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | {/* small screen */} 48 | 57 | 58 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | ); 72 | }); 73 | export default Header; 74 | -------------------------------------------------------------------------------- /kitchensink-components/HomestayPage.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { StatusBar, Platform } from "react-native"; 3 | import { Box } from "@gluestack-ui/themed"; 4 | import MobileBottomTabs from "./MobileBottomTabs"; 5 | import MobileModeChangeButton from "./MobileModeChangeButton"; 6 | import { 7 | Plus, 8 | Home, 9 | MessageCircle, 10 | User, 11 | SlidersHorizontal, 12 | } from "lucide-react-native"; 13 | import MobileProfilePage from "./MobileProfilePage"; 14 | import Explorepage from "./ExplorePage"; 15 | import MobileSidebarActionsheet from "./MobileSidebarActionsheet"; 16 | 17 | const bottomTabs = [ 18 | { 19 | icon: Home, 20 | label: "Home", 21 | }, 22 | { 23 | icon: SlidersHorizontal, 24 | label: "Filter", 25 | }, 26 | { 27 | icon: Plus, 28 | label: "Listing", 29 | }, 30 | { 31 | icon: MessageCircle, 32 | label: "Inbox", 33 | disabled: true, 34 | }, 35 | { 36 | icon: User, 37 | label: "Profile", 38 | }, 39 | ]; 40 | 41 | const HomestayPage = () => { 42 | useEffect(() => { 43 | if (Platform.OS === "web") { 44 | document.body.style.overflow = "hidden"; 45 | document.body.style.height = "100%"; 46 | } 47 | }, []); 48 | 49 | const [activeTab, setActiveTab] = React.useState("Home"); 50 | 51 | return ( 52 | <> 53 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {/* mobile bottom tabs */} 70 | 83 | 88 | 89 | 90 | {/* )} */} 91 | 92 | ); 93 | }; 94 | export default HomestayPage; 95 | -------------------------------------------------------------------------------- /kitchensink-components/LogoutAlertDialog.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | AlertDialog, 4 | Text, 5 | Heading, 6 | Icon, 7 | Button, 8 | CloseIcon, 9 | AlertDialogBackdrop, 10 | AlertDialogContent, 11 | ButtonText, 12 | AlertDialogHeader, 13 | AlertDialogCloseButton, 14 | AlertDialogBody, 15 | AlertDialogFooter, 16 | } from "@gluestack-ui/themed"; 17 | 18 | const LogoutAlertDialog = ({ 19 | openLogoutAlertDialog, 20 | setOpenLogoutAlertDialog, 21 | }: any) => { 22 | const handleClose = () => { 23 | setOpenLogoutAlertDialog(false); 24 | }; 25 | 26 | return ( 27 | 28 | 29 | 30 | 31 | Logout 32 | 33 | 34 | 35 | 36 | 37 | Are you sure, you want to logout? 38 | 39 | 40 | 48 | 51 | 52 | 53 | 54 | ); 55 | }; 56 | 57 | export default LogoutAlertDialog; 58 | -------------------------------------------------------------------------------- /kitchensink-components/MobileBottomTabs.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HStack, Icon, Pressable, Text, VStack } from "@gluestack-ui/themed"; 3 | import ListYourPlaceModal from "./main-content/ListYourPlaceModal"; 4 | import MobileSidebarActionsheet from "./MobileSidebarActionsheet"; 5 | 6 | const MobileBottomTabs = ({ bottomTabs, activeTab, setActiveTab }: any) => { 7 | const [modalVisible, setModalVisible] = React.useState(false); 8 | const [actionsheetVisible, setActionsheetVisible] = React.useState(false); 9 | 10 | return ( 11 | <> 12 | 24 | {bottomTabs.map((tab: any) => { 25 | return ( 26 | { 29 | if (tab.label !== "Listing" && tab.label !== "Filter") { 30 | setActiveTab(tab.label); 31 | } 32 | if (tab.label === "Listing") { 33 | setModalVisible(true); 34 | } 35 | if (tab.label === "Filter") { 36 | setActionsheetVisible(true); 37 | } 38 | }} 39 | disabled={tab.disabled} 40 | opacity={tab.disabled ? 0.5 : 1} 41 | > 42 | 43 | 50 | 64 | {tab.label} 65 | 66 | 67 | 68 | ); 69 | })} 70 | 71 | {modalVisible && ( 72 | 76 | )} 77 | {actionsheetVisible && ( 78 | 82 | )} 83 | 84 | ); 85 | }; 86 | 87 | export default MobileBottomTabs; 88 | -------------------------------------------------------------------------------- /kitchensink-components/MobileModeChangeButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Fab, FabIcon } from "@gluestack-ui/themed"; 3 | import { Moon, Sun } from "lucide-react-native"; 4 | import { ThemeContext } from "../App"; 5 | 6 | const MobileModeChangeButton = () => { 7 | const { colorMode, toggleColorMode } = useContext(ThemeContext); 8 | return ( 9 | <> 10 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | export default MobileModeChangeButton; 29 | -------------------------------------------------------------------------------- /kitchensink-components/MobileProfilePage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { 4 | HStack, 5 | Text, 6 | Heading, 7 | Avatar, 8 | VStack, 9 | Link, 10 | Icon, 11 | Pressable, 12 | Divider, 13 | Button, 14 | ButtonText, 15 | } from "@gluestack-ui/themed"; 16 | import { 17 | Blinds, 18 | ChevronRight, 19 | Headphones, 20 | HeartHandshake, 21 | Settings, 22 | Tablets, 23 | User, 24 | } from "lucide-react-native"; 25 | import { ScrollView } from "react-native"; 26 | import LogoutAlertDialog from "./LogoutAlertDialog"; 27 | 28 | const MobileProfilePage = ({ isActive }: any) => { 29 | const [openLogoutAlertDialog, setOpenLogoutAlertDialog] = 30 | React.useState(false); 31 | return ( 32 | 33 | 34 | Profile 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 47 | 48 | 52 | 53 | ); 54 | }; 55 | 56 | const ProfileCard = () => { 57 | return ( 58 | 59 | 60 | 61 | Henry Stan 62 | 67 | 68 | 69 | Henry Stan 70 | 71 | 72 | Show Profile 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | ); 82 | }; 83 | 84 | const PersonalInfoSection = () => { 85 | return ( 86 | 87 | 88 | 89 | 90 | Personal Info 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | Account 100 | 101 | 102 | 103 | 104 | 105 | 106 | ); 107 | }; 108 | 109 | const HostingSection = () => { 110 | return ( 111 | 112 | Hosting 113 | 114 | 115 | 116 | Host a home 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | Host an experience 126 | 127 | 128 | 129 | 130 | 131 | 132 | ); 133 | }; 134 | 135 | const SupportSection = () => { 136 | return ( 137 | 138 | Support 139 | 140 | 141 | 142 | Get Help 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | Contact Support 152 | 153 | 154 | 155 | 156 | 157 | 158 | ); 159 | }; 160 | 161 | const LogoutButton = ({ setOpenLogoutAlertDialog }: any) => { 162 | return ( 163 | 172 | ); 173 | }; 174 | 175 | export default MobileProfilePage; 176 | -------------------------------------------------------------------------------- /kitchensink-components/MobileSidebarActionsheet.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Box, 4 | Actionsheet, 5 | ActionsheetDragIndicatorWrapper, 6 | ActionsheetDragIndicator, 7 | ActionsheetScrollView, 8 | ActionsheetBackdrop, 9 | ActionsheetContent, 10 | } from "@gluestack-ui/themed"; 11 | import Sidebar from "./Sidebar"; 12 | 13 | const MobileSidebarActionsheet = ({ 14 | actionsheetVisible, 15 | setActionsheetVisible, 16 | }: any) => { 17 | const handleClose = () => { 18 | setActionsheetVisible(false); 19 | }; 20 | return ( 21 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ); 47 | }; 48 | export default MobileSidebarActionsheet; 49 | -------------------------------------------------------------------------------- /kitchensink-components/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ScrollView } from "react-native"; 3 | import { VStack } from "@gluestack-ui/themed"; 4 | import AmenitiesSection from "./sidebar/AmenitiesSection"; 5 | import BookingOptions from "./sidebar/BookingOptions"; 6 | import CustomerRatingSection from "./sidebar/CustomerRatingSection"; 7 | import FiltersAppliedSection from "./sidebar/FiltersAppliedSection"; 8 | import PlaceTypeSection from "./sidebar/PlaceTypeSection"; 9 | import PriceRangeSection from "./sidebar/PriceRangeSection"; 10 | import SortBySection from "./sidebar/SortBySection"; 11 | 12 | const Sidebar = () => { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | }; 29 | export default Sidebar; 30 | -------------------------------------------------------------------------------- /kitchensink-components/WebSidebar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box } from "@gluestack-ui/themed"; 3 | import Sidebar from "./Sidebar"; 4 | 5 | const WebSidebar = () => { 6 | return ( 7 | 22 | {/* common sidebar contents for web and mobile */} 23 | 24 | 25 | ); 26 | }; 27 | export default WebSidebar; 28 | -------------------------------------------------------------------------------- /kitchensink-components/header/HeaderTabs.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SearchIcon } from "@gluestack-ui/themed"; 3 | import { HStack, Icon, Pressable, Text } from "@gluestack-ui/themed"; 4 | 5 | const HeaderTabs = () => { 6 | const [selectedTab, setSelectedTab] = React.useState("Anywhere"); 7 | return ( 8 | 9 | 17 | setSelectedTab("Anywhere")} 31 | px="$3" 32 | py="$1.5" 33 | > 34 | 35 | Anywhere 36 | 37 | 38 | setSelectedTab("Anyweek")} 52 | > 53 | 54 | Anyweek 55 | 56 | 57 | setSelectedTab("Add guests")} 73 | > 74 | 75 | Add guests 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | ); 84 | }; 85 | export default HeaderTabs; 86 | -------------------------------------------------------------------------------- /kitchensink-components/header/HomestayLogo.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Svg, Path } from "react-native-svg"; 3 | 4 | const HomestayLogo = () => { 5 | return ( 6 | 7 | 11 | 15 | 16 | ); 17 | }; 18 | 19 | export default HomestayLogo; 20 | -------------------------------------------------------------------------------- /kitchensink-components/header/ToggleMode.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Icon, MoonIcon, SunIcon, Button } from "@gluestack-ui/themed"; 3 | import { ThemeContext } from "../../App"; 4 | 5 | const ToggleMode = () => { 6 | const { colorMode, toggleColorMode } = useContext(ThemeContext); 7 | return ( 8 | 21 | ); 22 | }; 23 | export default ToggleMode; 24 | -------------------------------------------------------------------------------- /kitchensink-components/header/UserProfile.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { 3 | Avatar, 4 | AvatarFallbackText, 5 | AvatarImage, 6 | AvatarBadge, 7 | Menu, 8 | MenuItem, 9 | MenuItemLabel, 10 | Pressable, 11 | } from "@gluestack-ui/themed"; 12 | import LogoutAlertDialog from "../LogoutAlertDialog"; 13 | 14 | const userMenuItems = [ 15 | { 16 | title: "Messages", 17 | }, 18 | { 19 | title: "Notifications", 20 | }, 21 | { 22 | title: "Trips", 23 | }, 24 | { 25 | title: "Wishlists", 26 | }, 27 | { 28 | title: "Post your home", 29 | }, 30 | { 31 | title: "Host an experience", 32 | }, 33 | { 34 | title: "Accounts", 35 | }, 36 | { 37 | title: "Help", 38 | }, 39 | { 40 | title: "Log out", 41 | }, 42 | ]; 43 | const UserProfile = () => { 44 | const [openLogoutAlertDialog, setOpenLogoutAlertDialog] = useState(false); 45 | return ( 46 | <> 47 | { 53 | if (e.currentKey === "Log out") { 54 | setOpenLogoutAlertDialog(true); 55 | } 56 | }} 57 | trigger={({ ...triggerProps }) => { 58 | return ( 59 | 60 | 61 | Henry Stan 62 | 67 | 75 | 76 | 77 | ); 78 | }} 79 | > 80 | {userMenuItems.map((item) => ( 81 | 82 | {item.title} 83 | 84 | ))} 85 | 86 | 90 | 91 | ); 92 | }; 93 | 94 | export default UserProfile; 95 | -------------------------------------------------------------------------------- /kitchensink-components/main-content/HomestayInformationFold.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Box, 4 | Button, 5 | HStack, 6 | Icon, 7 | Image, 8 | Pressable, 9 | Text, 10 | Tooltip, 11 | VStack, 12 | } from "@gluestack-ui/themed"; 13 | import { ChevronRight, Heart, Star } from "lucide-react-native"; 14 | import { AnimatePresence, Motion } from "@legendapp/motion"; 15 | import { ScrollView } from "react-native"; 16 | 17 | const homestayInfoData = [ 18 | { 19 | title: "ImageView Inn", 20 | src: require("../../assets/display/image16.png"), 21 | location: "401 Platte River Rd, Gothenburg, United States", 22 | price: "$1,481", 23 | rating: 4.9, 24 | }, 25 | { 26 | title: "Spinner Resort", 27 | src: require("../../assets/display/image17.png"), 28 | location: "1502 Silica Ave, Sacramento California", 29 | price: "$1,381", 30 | rating: 4.89, 31 | }, 32 | { 33 | title: "DropDown Den", 34 | src: require("../../assets/display/image18.png"), 35 | location: "2945 Entry Point Blvd, Kissimmee, Florida", 36 | price: "$2,481", 37 | rating: 4.6, 38 | }, 39 | ]; 40 | 41 | const tabsData = [ 42 | { 43 | title: "Tropical", 44 | }, 45 | { 46 | title: "Amazing views", 47 | }, 48 | { 49 | title: "Caves", 50 | }, 51 | { 52 | title: "Mansions", 53 | }, 54 | { 55 | title: "Amazing pools", 56 | }, 57 | { 58 | title: "Cabins", 59 | }, 60 | { 61 | title: "Beachfront", 62 | }, 63 | { 64 | title: "Countryside", 65 | }, 66 | { 67 | title: "Tiny homes", 68 | }, 69 | { 70 | title: "National parks", 71 | }, 72 | ]; 73 | 74 | const HomestayInformationFold = () => { 75 | return ( 76 | 77 | 78 | 79 | 80 | ); 81 | }; 82 | 83 | const HomestayInfoTabs = ({ tabsData }: any) => { 84 | const [activeTab, setActiveTab] = React.useState(tabsData[0]); 85 | return ( 86 | 94 | 95 | 96 | 97 | {tabsData.map((tab: any) => { 98 | return ( 99 | setActiveTab(tab)} 124 | > 125 | 138 | {tab.title} 139 | 140 | 141 | ); 142 | })} 143 | 144 | 145 | 146 | 147 | ); 148 | }; 149 | 150 | const TabPanelData = () => { 151 | const [likes, setLikes]: any = React.useState([]); 152 | return ( 153 | 161 | {homestayInfoData.map((image: any, index: any) => { 162 | return ( 163 | 175 | 176 | {(props: any) => { 177 | return ( 178 | <> 179 | 180 | Explore 188 | 189 | {props.hovered && ( 190 | 197 | )} 198 | 212 | 213 | ); 214 | }} 215 | 216 | { 218 | if (likes.includes(image.title)) { 219 | const newLikes = likes.filter( 220 | (like: any) => like !== image.title 221 | ); 222 | setLikes(newLikes); 223 | return; 224 | } else { 225 | setLikes([...likes, image.title]); 226 | } 227 | }} 228 | position="absolute" 229 | top={12} 230 | right={16} 231 | h="$6" 232 | w="$6" 233 | justifyContent="center" 234 | alignItems="center" 235 | > 236 | 237 | 258 | 266 | 267 | 268 | 269 | 274 | 275 | 282 | {image.title} 283 | 284 | 291 | {image.location} 292 | 293 | 294 | 302 | {image.price} 303 | 304 | 312 | night 313 | 314 | 315 | 316 | { 318 | return ( 319 | 320 | 321 | 330 | 338 | {image.rating} 339 | 340 | 341 | 342 | ); 343 | }} 344 | > 345 | 346 | 353 | Ratings 354 | 355 | 356 | 357 | 358 | 359 | ); 360 | })} 361 | 362 | ); 363 | }; 364 | export default HomestayInformationFold; 365 | -------------------------------------------------------------------------------- /kitchensink-components/main-content/ListYourPlaceModal.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { 3 | Box, 4 | Modal, 5 | useToast, 6 | ToastDescription, 7 | ToastTitle, 8 | VStack, 9 | Icon, 10 | Center, 11 | Spinner, 12 | HStack, 13 | FormControl, 14 | Input, 15 | Button, 16 | Heading, 17 | Radio, 18 | Checkbox, 19 | Textarea, 20 | Select, 21 | Toast, 22 | ChevronDownIcon, 23 | CheckCircleIcon, 24 | CloseIcon, 25 | CheckIcon, 26 | CircleIcon, 27 | FormControlLabelText, 28 | FormControlLabel, 29 | InputField, 30 | TextareaInput, 31 | SelectTrigger, 32 | SelectDragIndicatorWrapper, 33 | SelectDragIndicator, 34 | SelectBackdrop, 35 | SelectIcon, 36 | SelectInput, 37 | SelectContent, 38 | SelectPortal, 39 | CheckboxGroup, 40 | CheckboxIndicator, 41 | CheckboxLabel, 42 | CheckboxIcon, 43 | ButtonText, 44 | ModalBody, 45 | ModalCloseButton, 46 | ModalHeader, 47 | ModalBackdrop, 48 | ModalContent, 49 | RadioIndicator, 50 | RadioLabel, 51 | RadioIcon, 52 | RadioGroup, 53 | } from "@gluestack-ui/themed"; 54 | 55 | const sidebarFiltersAmmenities = [ 56 | { 57 | label: "Wifi", 58 | value: "wifi", 59 | }, 60 | { 61 | label: "Washing machine", 62 | value: "washing-machine", 63 | }, 64 | { 65 | label: "Air conditioning", 66 | value: "air-conditioning", 67 | }, 68 | { 69 | label: "Kitchen", 70 | value: "kitchen", 71 | }, 72 | { 73 | label: "Dryer", 74 | value: "dryer", 75 | }, 76 | { 77 | label: "Iron", 78 | value: "iron", 79 | }, 80 | { 81 | label: "Hair Dryer", 82 | value: "hair-dryer", 83 | }, 84 | ]; 85 | const phoneNumberCodes = [ 86 | { code: "+1", country: "USA" }, 87 | { code: "+44", country: "UK" }, 88 | { code: "+91", country: "India" }, 89 | { code: "+61", country: "Australia" }, 90 | { code: "+33", country: "France" }, 91 | { code: "+49", country: "Germany" }, 92 | { code: "+81", country: "Japan" }, 93 | { code: "+86", country: "China" }, 94 | { code: "+7", country: "Russia" }, 95 | { code: "+971", country: "United Arab Emirates" }, 96 | ]; 97 | const propertyType = [ 98 | "Flat/Apartment", 99 | "Independent House / Villa", 100 | "Independent Floor/Builder Floor", 101 | "Plot / Land", 102 | ]; 103 | const sellOrRentOptions = ["Sell", "Rent/Lease"]; 104 | 105 | const handleClose = (setModalVisible: any) => { 106 | setModalVisible(false); 107 | }; 108 | 109 | const ListYourPlaceModal = ({ modalVisible, setModalVisible }: any) => { 110 | const [modalFormStep, setModalFormStep] = React.useState(0); 111 | 112 | useEffect(() => { 113 | setModalFormStep(0); 114 | }, []); 115 | 116 | const toast = useToast(); 117 | const getModalStepContent = (step: number) => { 118 | switch (step) { 119 | case 0: 120 | return ( 121 | 127 | ); 128 | case 1: 129 | return ( 130 | 136 | ); 137 | case 2: 138 | return ( 139 | 145 | ); 146 | } 147 | }; 148 | 149 | return ( 150 | 151 | {/* Modal: example */} 152 | { 156 | setModalVisible(false); 157 | }} 158 | avoidKeyboard 159 | > 160 | 161 | 162 | 163 | 164 | 165 | List your place 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | {getModalStepContent(modalFormStep)} 174 | 175 | 176 | 177 | 178 | ); 179 | }; 180 | 181 | const SaveForLaterButton = ({ setModalVisible, toast }: any) => { 182 | const [showSpinner, setShowSpinner] = useState(false); 183 | 184 | const handleSaveForLater = () => { 185 | handleClose(setModalVisible); 186 | // toast example 187 | toast.show({ 188 | placement: "top", 189 | render: ({ id }: any) => { 190 | return ( 191 | 195 | ); 196 | }, 197 | }); 198 | }; 199 | 200 | return ( 201 | 202 | {showSpinner ? ( 203 |
204 | 205 |
206 | ) : ( 207 | 220 | )} 221 |
222 | ); 223 | }; 224 | 225 | const PreviousStepperButton = ({ setModalFormStep, step }: any) => { 226 | return ( 227 | 236 | ); 237 | }; 238 | 239 | const RenderToast = ({ description, title, id }: any) => { 240 | return ( 241 | 242 | 243 | 244 | {title} 245 | {description} 246 | 247 | 248 | ); 249 | }; 250 | 251 | const NextStepperButton = ({ setModalFormStep, step }: any) => { 252 | return ( 253 | 260 | ); 261 | }; 262 | 263 | const PostNowButton = ({ setModalVisible, toast }: any) => { 264 | return ( 265 | 284 | ); 285 | }; 286 | 287 | const ModalContent1 = ({ setModalFormStep, toast }: any) => { 288 | const [values, setValues]: any = React.useState("Residential"); 289 | const [selectedSellOrRentOption, setSelectedSellOrRentOption] = useState( 290 | sellOrRentOptions[0] 291 | ); 292 | const [selectedPropertyTypeOptions, setSelectedPropertyTypeOptions]: any = 293 | useState([]); 294 | 295 | const handlePropertyTypeSelection = (item: any) => { 296 | if (selectedPropertyTypeOptions.includes(item)) { 297 | setSelectedPropertyTypeOptions( 298 | selectedPropertyTypeOptions.filter((option: string) => option !== item) 299 | ); 300 | } else { 301 | setSelectedPropertyTypeOptions([...selectedPropertyTypeOptions, item]); 302 | } 303 | }; 304 | return ( 305 | 306 | 307 | 308 | 309 | I want to... 310 | 311 | 312 | {sellOrRentOptions.map((item, index) => ( 313 | 328 | ))} 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | Property is... 337 | 338 | 343 | 344 | 345 | 346 | 347 | 348 | Residential 349 | 350 | 351 | 352 | 353 | 354 | Commercial 355 | 356 | 357 | 358 | 359 | 360 | 361 | {propertyType.map((item: string, index: any) => ( 362 | 379 | ))} 380 | 381 | 382 | 383 | 384 | ); 385 | }; 386 | 387 | const ModalContent2 = ({ setModalFormStep }: any) => { 388 | return ( 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | ); 397 | }; 398 | 399 | const ModalContent3 = ({ setModalVisible, toast }: any) => { 400 | return ( 401 | 402 | 403 | 404 | Title 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | Description 413 | 414 | {/* textarea: example */} 415 | 418 | 419 | 420 | 421 | 422 | Contact me 423 | 424 | 425 | {/* select: example */} 426 | 447 | {/* input: example */} 448 | 449 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | ); 463 | }; 464 | 465 | const AmenitiesSection = () => { 466 | const [values, setValues] = React.useState(["wifi", "air-conditioning"]); 467 | return ( 468 | 469 | 470 | 471 | Ammenities 472 | 473 | 478 | {sidebarFiltersAmmenities.map((ammenity: any) => { 479 | return ( 480 | 487 | 488 | 489 | 490 | {ammenity.label} 491 | 492 | ); 493 | })} 494 | 495 | 496 | 497 | ); 498 | }; 499 | 500 | export default ListYourPlaceModal; 501 | -------------------------------------------------------------------------------- /kitchensink-components/main-content/MainContent.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box } from "@gluestack-ui/themed"; 3 | import HomestayInformationFold from "./HomestayInformationFold"; 4 | import MainContentHeader from "./MainContentHeader"; 5 | import NewThisWeekFold from "./NewThisWeekFold"; 6 | 7 | const MainContent = ({ 8 | modalVisible, 9 | setModalVisible, 10 | setActiveTab, 11 | activeTab, 12 | }: any) => { 13 | return ( 14 | 18 | 19 | {/* explore page main content header */} 20 | 26 | {/* explore page new this week fold 1 */} 27 | 28 | {/* explore page homestay info fold 2 */} 29 | 30 | 31 | 32 | ); 33 | }; 34 | export default MainContent; 35 | -------------------------------------------------------------------------------- /kitchensink-components/main-content/MainContentHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Box, 4 | Button, 5 | ButtonIcon, 6 | ButtonText, 7 | Heading, 8 | HStack, 9 | } from "@gluestack-ui/themed"; 10 | import { List } from "lucide-react-native"; 11 | import ListYourPlaceModal from "./ListYourPlaceModal"; 12 | 13 | const MainContentHeader = ({ setActiveTab, activeTab }: any) => { 14 | const [modalVisible, setModalVisible] = React.useState(false); 15 | return ( 16 | 17 | 18 | New this week 19 | {/* Hidden for mobile screens */} 20 | 49 | 50 | {modalVisible && ( 51 | // list your place modal 52 | 58 | )} 59 | 60 | ); 61 | }; 62 | 63 | export default MainContentHeader; 64 | -------------------------------------------------------------------------------- /kitchensink-components/main-content/NewThisWeekFold.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState } from "react"; 2 | import { 3 | Box, 4 | HStack, 5 | Image, 6 | Center, 7 | Icon, 8 | Pressable, 9 | } from "@gluestack-ui/themed"; 10 | import { ScrollView } from "react-native"; 11 | import { ChevronLeft, ChevronRight } from "lucide-react-native"; 12 | 13 | const data = [ 14 | { 15 | src: require("../../assets/display/image1.png"), 16 | }, 17 | { 18 | src: require("../../assets/display/image2.png"), 19 | }, 20 | 21 | { 22 | src: require("../../assets/display/image4.png"), 23 | }, 24 | // { 25 | // src: require("../../assets/display/image5.png"), 26 | // }, 27 | { 28 | src: require("../../assets/display/image6.png"), 29 | }, 30 | // { 31 | // src: require("../../assets/display/image7.png"), 32 | // }, 33 | { 34 | src: require("../../assets/display/image8.png"), 35 | }, 36 | // { 37 | // src: require("../../assets/display/image9.png"), 38 | // }, 39 | { 40 | src: require("../../assets/display/image10.png"), 41 | }, 42 | { 43 | src: require("../../assets/display/image3.png"), 44 | }, 45 | { 46 | src: require("../../assets/display/image11.png"), 47 | }, 48 | { 49 | src: require("../../assets/display/image12.png"), 50 | }, 51 | { 52 | src: require("../../assets/display/image13.png"), 53 | }, 54 | { 55 | src: require("../../assets/display/image14.png"), 56 | }, 57 | // { 58 | // src: require("../../assets/display/image15.png"), 59 | // }, 60 | ]; 61 | 62 | const NewThisWeekFold = () => { 63 | const scrollViewRef = useRef(null); 64 | const scrollAmount = 400; 65 | const [scrollPosition, setScrollPosition] = useState(0); 66 | const [isContentAtRight, setIsContentAtRight] = useState(true); 67 | 68 | const handleScrollLeft = () => { 69 | const newScrollPosition = scrollPosition - scrollAmount; 70 | if (scrollViewRef.current) { 71 | // @ts-ignore 72 | scrollViewRef?.current?.scrollTo({ 73 | x: newScrollPosition, 74 | animated: true, 75 | }); 76 | setScrollPosition(newScrollPosition); 77 | } 78 | }; 79 | 80 | const handleScrollRight = () => { 81 | const newScrollPosition = scrollPosition + scrollAmount; 82 | if (scrollViewRef.current) 83 | // @ts-ignore 84 | scrollViewRef?.current?.scrollTo({ 85 | x: newScrollPosition, 86 | animated: true, 87 | }); 88 | setScrollPosition(newScrollPosition); 89 | }; 90 | 91 | const checkContentAtLeft = () => { 92 | if (scrollPosition > 0) { 93 | return true; 94 | } 95 | return false; 96 | }; 97 | 98 | const isCloseToRight = (event: any) => { 99 | const { contentOffset, layoutMeasurement, contentSize } = event.nativeEvent; 100 | const isScrollAtEnd = 101 | contentOffset.x + layoutMeasurement.width >= contentSize.width; 102 | if (isScrollAtEnd) { 103 | return true; 104 | } 105 | return false; 106 | }; 107 | 108 | return ( 109 | 110 | { 117 | if (isCloseToRight(event)) { 118 | setIsContentAtRight(false); 119 | } else { 120 | setIsContentAtRight(true); 121 | } 122 | setScrollPosition(event.nativeEvent.contentOffset.x); 123 | }} 124 | > 125 | 126 | {data.map((image, index) => { 127 | return ( 128 | 129 | {"place" 138 | 139 | ); 140 | })} 141 | 142 | 143 | 147 | 151 | 152 | ); 153 | }; 154 | 155 | const ScrollLeft = ({ handleScrollLeft, disabled }: any) => { 156 | return ( 157 |
168 | 197 | 207 | 208 |
209 | ); 210 | }; 211 | 212 | const ScrollRight = ({ handleScrollRight, disabled }: any) => { 213 | return ( 214 |
225 | 251 | 261 | 262 |
263 | ); 264 | }; 265 | 266 | export default NewThisWeekFold; 267 | -------------------------------------------------------------------------------- /kitchensink-components/main-content/PriceRangeSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Checkbox, 4 | Slider, 5 | Text, 6 | Tooltip, 7 | VStack, 8 | Heading, 9 | CheckboxGroup, 10 | SliderTrack, 11 | SliderFilledTrack, 12 | CheckboxIndicator, 13 | CheckboxLabel, 14 | CheckboxIcon, 15 | } from "@gluestack-ui/themed"; 16 | import { CheckIcon } from "@gluestack-ui/themed"; 17 | 18 | const PriceRangeSection = () => { 19 | const [sliderValue, setSliderValue] = React.useState(3500); 20 | const [values, setValues] = React.useState(["entirePlace"]); 21 | const handleChange = (value: any) => { 22 | setSliderValue(value); 23 | }; 24 | 25 | const sidebarFiltersPriceRange = [ 26 | { 27 | label: "below ₹2001", 28 | value: "below ₹2001", 29 | }, 30 | { 31 | label: "₹2001 - ₹3000", 32 | value: "₹2001 - ₹3000", 33 | }, 34 | { 35 | label: "₹3001 - ₹4001", 36 | value: "₹3001 - ₹4001", 37 | }, 38 | { 39 | label: "above ₹3001", 40 | value: "above ₹3001", 41 | }, 42 | ]; 43 | 44 | return ( 45 | 46 | Price Range 47 | { 54 | handleChange(value); 55 | }} 56 | > 57 | 58 | 59 | 60 | { 63 | return ; 64 | }} 65 | > 66 | 67 | ₹{sliderValue} 68 | 69 | 70 | 71 | 77 | {sidebarFiltersPriceRange.map((priceRange: any) => { 78 | return ( 79 | 86 | 87 | 88 | 89 | {priceRange.label} 90 | 91 | ); 92 | })} 93 | 94 | 95 | ); 96 | }; 97 | export default PriceRangeSection; 98 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/AmenitiesSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Checkbox, 4 | CheckboxGroup, 5 | CheckboxIcon, 6 | CheckboxIndicator, 7 | CheckboxLabel, 8 | HStack, 9 | Heading, 10 | Icon, 11 | Pressable, 12 | Text, 13 | VStack, 14 | CheckIcon, 15 | ChevronDownIcon, 16 | ChevronUpIcon, 17 | } from "@gluestack-ui/themed"; 18 | 19 | const AmenitiesSection = () => { 20 | const sidebarFiltersAmmenities = [ 21 | { 22 | label: "Wifi", 23 | value: "wifi", 24 | }, 25 | { 26 | label: "Washing machine", 27 | value: "washing-machine", 28 | }, 29 | { 30 | label: "Air conditioning", 31 | value: "air-conditioning", 32 | }, 33 | { 34 | label: "Kitchen", 35 | value: "kitchen", 36 | }, 37 | { 38 | label: "Dryer", 39 | value: "dryer", 40 | }, 41 | { 42 | label: "Iron", 43 | value: "iron", 44 | }, 45 | { 46 | label: "Hair Dryer", 47 | value: "hair-dryer", 48 | }, 49 | ]; 50 | 51 | const [values, setValues] = React.useState(["wifi", "air-conditioning"]); 52 | const [viewAllComponents, setViewAllComponents] = React.useState(false); 53 | 54 | return ( 55 | 56 | Ammenities 57 | 62 | {sidebarFiltersAmmenities.map((ammenity: any, index: any) => { 63 | if (index > 4 && !viewAllComponents) return null; 64 | return ( 65 | 73 | 74 | 75 | 76 | {ammenity.label} 77 | 78 | ); 79 | })} 80 | 81 | {viewAllComponents ? ( 82 | { 84 | setViewAllComponents(false); 85 | }} 86 | > 87 | 88 | 89 | Show less 90 | 91 | 92 | 93 | 94 | ) : ( 95 | { 97 | setViewAllComponents(true); 98 | }} 99 | > 100 | 101 | 102 | Show more 103 | 104 | 105 | 106 | 107 | )} 108 | 109 | ); 110 | }; 111 | export default AmenitiesSection; 112 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/BookingOptions.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Box, 4 | HStack, 5 | Heading, 6 | Switch, 7 | Text, 8 | VStack, 9 | } from "@gluestack-ui/themed"; 10 | 11 | const BookingOptions = () => { 12 | const [selfCheckIn, setSelfCheckIn] = React.useState(false); 13 | const [mealsIncluded, setMealsIncluded] = React.useState(false); 14 | 15 | return ( 16 | 17 | Booking Options 18 | 19 | 20 | 21 | 26 | Self check-in 27 | 28 | 29 | Access a place without needing the Host 30 | 31 | 32 | setSelfCheckIn(val)} 36 | /> 37 | 38 | 39 | 40 | 41 | 42 | 47 | Meals included 48 | 49 | 50 | Have a prefered meal for your comfy stay 51 | 52 | 53 | setMealsIncluded(val)} 57 | /> 58 | 59 | 60 | 61 | ); 62 | }; 63 | export default BookingOptions; 64 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/CustomerRatingSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Checkbox, 4 | CheckboxGroup, 5 | CheckboxIcon, 6 | CheckboxIndicator, 7 | CheckboxLabel, 8 | Heading, 9 | Icon, 10 | VStack, 11 | } from "@gluestack-ui/themed"; 12 | import { CheckIcon } from "@gluestack-ui/themed"; 13 | import { Star } from "lucide-react-native"; 14 | 15 | const CustomerRatingSection = () => { 16 | const sidebarFiltersCustomerRatings = [ 17 | { 18 | label: "5 stars", 19 | value: "5 stars", 20 | }, 21 | { 22 | label: "4+ stars", 23 | value: "4+ stars", 24 | }, 25 | { 26 | label: "3+ stars", 27 | value: "3+ stars", 28 | }, 29 | { 30 | label: "2+ stars", 31 | value: "2+ stars", 32 | }, 33 | ]; 34 | const [values, setValues] = React.useState(["wifi", "air-conditioning"]); 35 | 36 | return ( 37 | 38 | Customer Ratings 39 | 44 | {sidebarFiltersCustomerRatings.map((placeType: any, index: any) => { 45 | return ( 46 | 53 | 54 | 55 | 56 | 57 | {" "} 64 | {placeType.label} 65 | 66 | 67 | ); 68 | })} 69 | 70 | 71 | ); 72 | }; 73 | export default CustomerRatingSection; 74 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/FiltersAppliedSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Badge, 4 | BadgeText, 5 | Box, 6 | Button, 7 | HStack, 8 | Icon, 9 | Pressable, 10 | Text, 11 | } from "@gluestack-ui/themed"; 12 | import { CloseIcon } from "@gluestack-ui/themed"; 13 | 14 | const FiltersAppliedSection = () => { 15 | const filters = ["Private room", "Wifi", "Air conditioning"]; 16 | const [appliedFilters, setAppliedFilters]: any = React.useState(filters); 17 | return ( 18 | 27 | 28 | 29 | Filters applied 30 | 31 | 42 | 43 | 44 | {appliedFilters.map((item: any) => ( 45 | 54 | 59 | {item} 60 | 61 | { 72 | const newFilters = appliedFilters.filter((item1: any) => { 73 | return item1 !== item; 74 | }); 75 | setAppliedFilters(newFilters); 76 | }} 77 | > 78 | 86 | 87 | 88 | ))} 89 | 90 | 91 | ); 92 | }; 93 | export default FiltersAppliedSection; 94 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/PlaceTypeSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Checkbox, 4 | CheckboxGroup, 5 | CheckboxIcon, 6 | CheckboxIndicator, 7 | CheckboxLabel, 8 | Heading, 9 | VStack, 10 | CheckIcon, 11 | } from "@gluestack-ui/themed"; 12 | 13 | const PlaceTypeSection = () => { 14 | const sidebarFiltersPlaceType = [ 15 | { 16 | label: "Entire place", 17 | value: "entirePlace", 18 | }, 19 | { 20 | label: "Private room", 21 | value: "privateRoom", 22 | }, 23 | { 24 | label: "Shared room", 25 | value: "sharedRoom", 26 | }, 27 | ]; 28 | 29 | const [values, setValues] = React.useState(["entirePlace"]); 30 | 31 | return ( 32 | 33 | Type of place 34 | 39 | {sidebarFiltersPlaceType.map((placeType: any) => { 40 | return ( 41 | 49 | 50 | 51 | 52 | {placeType.label} 53 | 54 | ); 55 | })} 56 | 57 | 58 | ); 59 | }; 60 | export default PlaceTypeSection; 61 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/PriceRangeSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Checkbox, 4 | Slider, 5 | Text, 6 | Tooltip, 7 | VStack, 8 | Heading, 9 | SliderTrack, 10 | SliderFilledTrack, 11 | SliderThumb, 12 | CheckboxIndicator, 13 | CheckboxLabel, 14 | CheckIcon, 15 | CheckboxIcon, 16 | } from "@gluestack-ui/themed"; 17 | 18 | const PriceRangeSection = () => { 19 | const [sliderValue, setSliderValue] = React.useState(3500); 20 | const [values, setValues] = React.useState(["entirePlace"]); 21 | const handleChange = (value: any) => { 22 | setSliderValue(value); 23 | }; 24 | 25 | const sidebarFiltersPriceRange = [ 26 | { 27 | label: "below ₹2001", 28 | value: "below ₹2001", 29 | }, 30 | { 31 | label: "₹2001 - ₹3000", 32 | value: "₹2001 - ₹3000", 33 | }, 34 | { 35 | label: "₹3001 - ₹4001", 36 | value: "₹3001 - ₹4001", 37 | }, 38 | { 39 | label: "above ₹3001", 40 | value: "above ₹3001", 41 | }, 42 | ]; 43 | 44 | return ( 45 | 46 | Price Range 47 | { 54 | handleChange(value); 55 | }} 56 | > 57 | 58 | 59 | 60 | { 64 | return ; 65 | }} 66 | > 67 | 68 | ₹{sliderValue} 69 | 70 | 71 | 72 | 78 | {sidebarFiltersPriceRange.map((priceRange: any) => { 79 | return ( 80 | 87 | 88 | 89 | 90 | {priceRange.label} 91 | 92 | ); 93 | })} 94 | 95 | 96 | ); 97 | }; 98 | export default PriceRangeSection; 99 | -------------------------------------------------------------------------------- /kitchensink-components/sidebar/SortBySection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | CircleIcon, 4 | Heading, 5 | Radio, 6 | RadioGroup, 7 | RadioIndicator, 8 | RadioLabel, 9 | VStack, 10 | } from "@gluestack-ui/themed"; 11 | import { RadioIcon } from "@gluestack-ui/themed"; 12 | 13 | const SortBySection = () => { 14 | const sidebarFiltersCustomerRatings = [ 15 | { 16 | label: "Top ratings", 17 | value: "Top ratings", 18 | }, 19 | { 20 | label: "Best price", 21 | value: "Best price", 22 | }, 23 | { 24 | label: "Discount", 25 | value: "Discount", 26 | }, 27 | { 28 | label: "What’s new", 29 | value: "What’s new", 30 | }, 31 | ]; 32 | const [values, setValues] = React.useState("Top ratings"); 33 | 34 | return ( 35 | 36 | Sort by 37 | 42 | {sidebarFiltersCustomerRatings.map((placeType: any) => { 43 | return ( 44 | 51 | 52 | 53 | 54 | {placeType.label} 55 | 56 | ); 57 | })} 58 | 59 | 60 | ); 61 | }; 62 | export default SortBySection; 63 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | // Learn more https://docs.expo.dev/guides/monorepos 2 | const { getDefaultConfig } = require('expo/metro-config'); 3 | const path = require('path'); 4 | 5 | // Find the project and workspace directories 6 | const projectRoot = __dirname; 7 | 8 | const config = getDefaultConfig(projectRoot); 9 | 10 | // 2. Let Metro know where to resolve packages and in what order 11 | config.resolver.nodeModulesPaths = [ 12 | path.resolve(projectRoot, 'node_modules'), 13 | ]; 14 | // 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths` 15 | config.resolver.disableHierarchicalLookup = true; 16 | 17 | module.exports = config; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui-kitchensink", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "expo start --dev-client", 6 | "android": "expo run:android", 7 | "ios": "expo run:ios", 8 | "web": "expo start --web" 9 | }, 10 | "dependencies": { 11 | "@expo-google-fonts/inter": "^0.2.3", 12 | "@expo/html-elements": "latest", 13 | "@gluestack-style/react": "^1.0.48", 14 | "@gluestack-ui/config": "^1.1.5", 15 | "@gluestack-ui/themed": "^1.1.8", 16 | "@legendapp/motion": "latest", 17 | "expo": "^51.0.5", 18 | "expo-app-loading": "^2.1.1", 19 | "expo-crypto": "^12.8.1", 20 | "expo-font": "~11.1.1", 21 | "expo-image": "~1.0.2", 22 | "expo-linear-gradient": "~12.1.2", 23 | "expo-splash-screen": "~0.18.2", 24 | "expo-status-bar": "~1.4.4", 25 | "expo-updates": "~0.16.4", 26 | "install": "^0.13.0", 27 | "lucide-react-native": "^0.161.0", 28 | "react": "18.2.0", 29 | "react-dom": "18.2.0", 30 | "react-native": "0.73.2", 31 | "react-native-svg": "14.1.0" 32 | }, 33 | "devDependencies": { 34 | "@babel/core": "^7.20.0", 35 | "@babel/plugin-transform-modules-commonjs": "^7.21.5", 36 | "@babel/preset-env": "^7.22.4", 37 | "@babel/preset-react": "^7.22.3", 38 | "@expo/webpack-config": "~19.0.1", 39 | "@gluestack-style/babel-plugin-styled-resolver": "^0.2.6", 40 | "@types/react": "~18.2.45", 41 | "@types/react-native": "^0.72.2", 42 | "babel-loader": "^9.1.2", 43 | "postcss-loader": "^7.3.2", 44 | "react-native-web": "~0.18.11", 45 | "typescript": "^5.1.3" 46 | }, 47 | "private": true 48 | } 49 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # gluestack-ui Kitchensink Application 2 | 3 | ## Installation 4 | Ensure you have Node.js and Expo CLI installed on your machine. 5 | 6 | Clone this repository: 7 | 8 | ```bash 9 | git clone git@github.com:gluestack/ui-examples.git gluestack-kitchensink 10 | cd gluestack-kitchensink 11 | ``` 12 | 13 | Install dependencies: 14 | 15 | ```bash 16 | npm install 17 | or 18 | yarn 19 | ``` 20 | 21 | > **In the file app.json, Please remove the _extra_ and _owner_ property from the file** 22 | 23 | Run the KitchenSink app: 24 | ```bash 25 | expo start 26 | ``` 27 | 28 | This will start the Expo development server, and you can choose to run the app on an emulator, a physical device, or the web. 29 | 30 | For detailed information on each component and its props, refer to the documentation provided. => https://ui.gluestack.io/docs/getting-started/installation 31 | 32 | ## Created By GeekyAnts 33 | 34 | GeekyAnts is a team of React Native experts who love open-source and solving developer problems. We’ve been working on React Native since 2015 and have designed and built React Native apps for almost 200+ clients across the globe. Our clients include startups to big enterprises! Need help with your React Native app? 35 | 36 | [Contact Us](https://geekyants.com/?utm_source=gluestack-ui-home&utm_medium=home-page&utm_campaign=meet-the-creators) 37 | 38 | ## Contributing 39 | We welcome contributions from the community! If you want to report bugs, suggest improvements, or add new features, please create an issue, we will actively look into it. 40 | 41 | ## License 42 | This project is licensed under the MIT License. 43 | 44 | ## Contact 45 | For any inquiries or feedback join our Discord Channel => https://discord.gg/C9FaprHrUU 46 | -------------------------------------------------------------------------------- /styles/index.ts: -------------------------------------------------------------------------------- 1 | // Intentionally left empty 2 | export {}; 3 | -------------------------------------------------------------------------------- /styles/index.web.ts: -------------------------------------------------------------------------------- 1 | import "./main.css"; 2 | -------------------------------------------------------------------------------- /styles/main.css: -------------------------------------------------------------------------------- 1 | /* styles.css */ 2 | 3 | body { 4 | overflow: hidden; 5 | height: 100%; 6 | } 7 | 8 | ::-webkit-scrollbar { 9 | width: 6px; 10 | height: 8px; 11 | } 12 | 13 | ::-webkit-scrollbar-corner, 14 | ::-webkit-scrollbar-track { 15 | background: transparent; 16 | } 17 | 18 | .gs-dark ::-webkit-scrollbar-thumb { 19 | background-color: #525252; 20 | border-radius: 20px; 21 | border: 3px solid transparent; 22 | } 23 | 24 | ::-webkit-scrollbar-thumb { 25 | background-color: #dbdbdb; 26 | border-radius: 20px; 27 | border: 3px solid transparent; 28 | } 29 | 30 | ::-webkit-scrollbar-corner, 31 | ::-webkit-scrollbar-track { 32 | background: transparent; 33 | } 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": {}, 3 | "extends": "expo/tsconfig.base" 4 | } 5 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const createExpoWebpackConfigAsync = require("@expo/webpack-config"); 2 | 3 | module.exports = async function (env, argv) { 4 | const config = await createExpoWebpackConfigAsync(env, argv); 5 | config.resolve.fallback = { 6 | ...config.resolve.fallback, 7 | crypto: require.resolve("expo-crypto"), 8 | }; 9 | return config; 10 | }; 11 | --------------------------------------------------------------------------------