mirror of
https://github.com/urosran/cally.git
synced 2025-08-25 13:49:39 +00:00
reorganized and fixed groceries
This commit is contained in:
@ -40,19 +40,26 @@ const AddGroceryItem = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View
|
||||
row
|
||||
spread
|
||||
paddingH-25
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: -300,
|
||||
right: 0,
|
||||
width: "100%",
|
||||
height: 60,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
label="View shopping list"
|
||||
color="#337a11"
|
||||
backgroundColor="#c6e0b3"
|
||||
/>
|
||||
<Button
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: -680,
|
||||
right: 20,
|
||||
height: 60,
|
||||
borderRadius: 30,
|
||||
backgroundColor: "#19ad61",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
color="white"
|
||||
backgroundColor="#19ad61"
|
||||
label="Create new"
|
||||
enableShadow
|
||||
onPress={() => setVisible(true)}
|
||||
|
86
components/pages/grocery/EditGroceryItem.tsx
Normal file
86
components/pages/grocery/EditGroceryItem.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import { StyleSheet } from "react-native";
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Dialog,
|
||||
Text,
|
||||
View,
|
||||
PanningProvider,
|
||||
Switch,
|
||||
Picker,
|
||||
PickerValue,
|
||||
} from "react-native-ui-lib";
|
||||
import { GroceryFrequency, IGrocery } from "./GroceryItem";
|
||||
interface EditGroceryItemProps {
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
item: IGrocery;
|
||||
}
|
||||
const EditGroceryItem = (props: EditGroceryItemProps) => {
|
||||
const [recurring, setRecurring] = useState<boolean>(false);
|
||||
const pickerItems = Object.values(GroceryFrequency).map((value) => ({
|
||||
label: value,
|
||||
value: value,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
visible={props.visible}
|
||||
onDismiss={props.onClose}
|
||||
panDirection={PanningProvider.Directions.DOWN}
|
||||
containerStyle={{ borderRadius: 12, backgroundColor: "white" }}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>Edit grocery frequency</Text>
|
||||
<View style={styles.divider} />
|
||||
<View style={styles.inner}>
|
||||
<View row spread>
|
||||
<Text text70>Recurring</Text>
|
||||
<Switch value={recurring} onValueChange={value => setRecurring(value)} onColor={'lime'}/>
|
||||
</View>
|
||||
<Picker
|
||||
value={props.item.frequency}
|
||||
fieldType="form"
|
||||
useWheelPicker
|
||||
items={pickerItems}
|
||||
onChange={(item: PickerValue) => {
|
||||
const selectedFrequency =
|
||||
GroceryFrequency[item as keyof typeof GroceryFrequency];
|
||||
if (selectedFrequency) {
|
||||
//props.handleFrequency(props.item.id, selectedFrequency);
|
||||
} else {
|
||||
console.error("Invalid frequency selected");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditGroceryItem;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingVertical: 10,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
inner: {
|
||||
paddingHorizontal: 20,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
},
|
||||
title: {
|
||||
fontSize: 20,
|
||||
fontWeight: "400",
|
||||
textAlign: "center",
|
||||
},
|
||||
divider: {
|
||||
width: "100%",
|
||||
height: 1,
|
||||
backgroundColor: "#E0E0E0",
|
||||
marginVertical: 10,
|
||||
},
|
||||
});
|
150
components/pages/grocery/GroceryItem.tsx
Normal file
150
components/pages/grocery/GroceryItem.tsx
Normal file
@ -0,0 +1,150 @@
|
||||
import { View, Text, Button } from "react-native-ui-lib";
|
||||
import React, { useState } from "react";
|
||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
||||
import { MaterialCommunityIcons, AntDesign } from "@expo/vector-icons";
|
||||
import { ListItem } from "react-native-ui-lib";
|
||||
import EditGroceryItem from "./EditGroceryItem";
|
||||
|
||||
export enum GroceryFrequency {
|
||||
Never = "Never",
|
||||
Daily = "Daily",
|
||||
Weekly = "Weekly",
|
||||
BiWeekly = "BiWeekly",
|
||||
Monthly = "Monthly",
|
||||
Quarterly = "Quarterly",
|
||||
}
|
||||
|
||||
export interface IGrocery {
|
||||
id: number;
|
||||
title: String;
|
||||
category: GroceryCategory;
|
||||
approved: boolean;
|
||||
recurring: boolean;
|
||||
frequency: GroceryFrequency;
|
||||
bought: boolean;
|
||||
}
|
||||
|
||||
export enum GroceryCategory {
|
||||
Fruit = "Fruit",
|
||||
Dairy = "Dairy",
|
||||
Vegetables = "Vegetables",
|
||||
Meat = "Meat",
|
||||
Poultry = "Poultry",
|
||||
Bakery = "Bakery",
|
||||
Beverages = "Beverages",
|
||||
Snacks = "Snacks",
|
||||
Household = "Household",
|
||||
PersonalCare = "Personal Care",
|
||||
Frozen = "Frozen",
|
||||
}
|
||||
|
||||
type MaterialIconNames = keyof typeof MaterialCommunityIcons.glyphMap;
|
||||
const iconMapping: { [key in GroceryCategory]: MaterialIconNames } = {
|
||||
//за сад се иконице за категорију бирају одавде
|
||||
[GroceryCategory.Fruit]: "food-apple",
|
||||
[GroceryCategory.Dairy]: "cheese",
|
||||
[GroceryCategory.Vegetables]: "carrot",
|
||||
[GroceryCategory.Meat]: "food-steak",
|
||||
[GroceryCategory.Poultry]: "food-drumstick",
|
||||
[GroceryCategory.Bakery]: "bread-slice",
|
||||
[GroceryCategory.Beverages]: "cup-water",
|
||||
[GroceryCategory.Snacks]: "candy",
|
||||
[GroceryCategory.Household]: "home",
|
||||
[GroceryCategory.PersonalCare]: "face-man-profile",
|
||||
[GroceryCategory.Frozen]: "snowflake",
|
||||
};
|
||||
|
||||
const GroceryItem = ({
|
||||
item,
|
||||
handleItemApproved,
|
||||
}: {
|
||||
item: IGrocery;
|
||||
handleItemApproved: (id: number, approved: boolean) => void;
|
||||
|
||||
}) => {
|
||||
const { profileType } = useAuthContext();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
return (
|
||||
<ListItem
|
||||
backgroundColor="white"
|
||||
onPress={() => {
|
||||
setOpen(true);
|
||||
}}
|
||||
>
|
||||
<EditGroceryItem
|
||||
visible={open}
|
||||
key={item.id}
|
||||
item={item}
|
||||
onClose={() => {
|
||||
setOpen(false);
|
||||
}}
|
||||
/>
|
||||
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 15 }}>
|
||||
<View
|
||||
height={50}
|
||||
width={50}
|
||||
style={{ borderRadius: 15 }}
|
||||
backgroundColor="#e6f1ed"
|
||||
marginR-10
|
||||
children={
|
||||
<MaterialCommunityIcons
|
||||
name={iconMapping[item.category]}
|
||||
size={50}
|
||||
color="orange"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<View>
|
||||
<Text>{item.title}</Text>
|
||||
<Text>{iconMapping[item.category]}</Text>
|
||||
</View>
|
||||
</ListItem.Part>
|
||||
<ListItem.Part right containerStyle={{ paddingEnd: 15 }}>
|
||||
{profileType == ProfileType.PARENT ? (
|
||||
<View row>
|
||||
<Button
|
||||
children={
|
||||
<AntDesign
|
||||
name="check"
|
||||
size={24}
|
||||
style={{
|
||||
color: item.approved ? "green" : "#aaaaaa",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
backgroundColor="transparent"
|
||||
size={Button.sizes.small}
|
||||
onPress={() => {
|
||||
handleItemApproved(item.id, true);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
children={
|
||||
<AntDesign
|
||||
name="close"
|
||||
size={24}
|
||||
style={{ color: item.approved ? "#aaaaaa" : "red" }}
|
||||
/>
|
||||
}
|
||||
backgroundColor="transparent"
|
||||
size={Button.sizes.small}
|
||||
onPress={() => {
|
||||
handleItemApproved(item.id, false);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Text style={{ color: item.bought ? "green" : "red" }}>
|
||||
{item.approved ? (
|
||||
<AntDesign name="check" size={24} color={"green"} />
|
||||
) : (
|
||||
"X"
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</ListItem.Part>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default GroceryItem;
|
@ -2,142 +2,65 @@ import { FlatList } from "react-native";
|
||||
import React, { useState } from "react";
|
||||
import { View, Text, ListItem, Button } from "react-native-ui-lib";
|
||||
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
|
||||
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
|
||||
import { useAuthContext } from "@/contexts/AuthContext";
|
||||
import AntDesign from "@expo/vector-icons/AntDesign";
|
||||
import AddGroceryItem from "./AddGroceryItem";
|
||||
|
||||
export interface IGrocery {
|
||||
title: String;
|
||||
category: GroceryCategory;
|
||||
approved: boolean;
|
||||
bought: boolean;
|
||||
}
|
||||
|
||||
export enum GroceryCategory {
|
||||
Fruit = "Fruit",
|
||||
Dairy = "Dairy",
|
||||
Vegetables = "Vegetables",
|
||||
Meat = "Meat",
|
||||
Poultry = "Poultry",
|
||||
Bakery = "Bakery",
|
||||
Beverages = "Beverages",
|
||||
Snacks = "Snacks",
|
||||
Household = "Household",
|
||||
PersonalCare = "Personal Care",
|
||||
Frozen = "Frozen",
|
||||
}
|
||||
|
||||
type MaterialIconNames = keyof typeof MaterialCommunityIcons.glyphMap;
|
||||
const iconMapping: { [key in GroceryCategory]: MaterialIconNames } = { //за сад се иконице за категорију бирају одавде
|
||||
[GroceryCategory.Fruit]: "food-apple",
|
||||
[GroceryCategory.Dairy]: "cheese",
|
||||
[GroceryCategory.Vegetables]: "carrot",
|
||||
[GroceryCategory.Meat]: "food-steak",
|
||||
[GroceryCategory.Poultry]: "food-drumstick",
|
||||
[GroceryCategory.Bakery]: "bread-slice",
|
||||
[GroceryCategory.Beverages]: "cup-water",
|
||||
[GroceryCategory.Snacks]: "candy",
|
||||
[GroceryCategory.Household]: "home",
|
||||
[GroceryCategory.PersonalCare]: "face-man-profile",
|
||||
[GroceryCategory.Frozen]: "snowflake",
|
||||
};
|
||||
import GroceryItem, { IGrocery, GroceryCategory, GroceryFrequency } from "./GroceryItem";
|
||||
|
||||
const GroceryList = () => {
|
||||
const [groceries, setGroceries] = useState<IGrocery[]>([
|
||||
{
|
||||
id: 0,
|
||||
title: "Carrots",
|
||||
category: GroceryCategory.Vegetables,
|
||||
approved: false,
|
||||
bought: false,
|
||||
recurring: false,
|
||||
frequency: GroceryFrequency.Never
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
title: "Steak",
|
||||
category: GroceryCategory.Meat,
|
||||
approved: true,
|
||||
bought: false,
|
||||
recurring: false,
|
||||
frequency: GroceryFrequency.Never
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Chicken Breast",
|
||||
category: GroceryCategory.Poultry,
|
||||
approved: true,
|
||||
bought: false,
|
||||
recurring: false,
|
||||
frequency: GroceryFrequency.Never
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Greek Yoghurt",
|
||||
category: GroceryCategory.Dairy,
|
||||
approved: false,
|
||||
bought: false,
|
||||
recurring: false,
|
||||
frequency: GroceryFrequency.Never
|
||||
},
|
||||
]);
|
||||
const { profileType } = useAuthContext();
|
||||
const renderItem = ({ item }: { item: IGrocery }) => (
|
||||
<ListItem backgroundColor="white">
|
||||
<ListItem.Part left containerStyle={{ flex: 1, paddingStart: 15 }}>
|
||||
<View
|
||||
height={50}
|
||||
width={50}
|
||||
style={{ borderRadius: 15 }}
|
||||
backgroundColor="#e6f1ed"
|
||||
marginR-10
|
||||
children={
|
||||
<MaterialCommunityIcons
|
||||
name={iconMapping[item.category]}
|
||||
size={50}
|
||||
color="orange"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<View>
|
||||
<Text>{item.title}</Text>
|
||||
<Text>{iconMapping[item.category]}</Text>
|
||||
</View>
|
||||
</ListItem.Part>
|
||||
<ListItem.Part right containerStyle={{ paddingEnd: 15 }}>
|
||||
{profileType == ProfileType.PARENT ? (
|
||||
<View row>
|
||||
<Button
|
||||
children={
|
||||
<AntDesign
|
||||
name="check"
|
||||
size={24}
|
||||
style={{
|
||||
color: item.approved ? "green" : "#aaaaaa",
|
||||
}}
|
||||
/>
|
||||
}
|
||||
backgroundColor="transparent"
|
||||
size={Button.sizes.small}
|
||||
/>
|
||||
<Button
|
||||
children={
|
||||
<AntDesign
|
||||
name="close"
|
||||
size={24}
|
||||
style={{ color: item.approved ? "#aaaaaa" : "red" }}
|
||||
/>
|
||||
}
|
||||
backgroundColor="transparent"
|
||||
size={Button.sizes.small}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Text style={{ color: item.bought ? "green" : "red" }}>
|
||||
{item.approved ? <AntDesign
|
||||
name="check"
|
||||
size={24}
|
||||
color={'green'}
|
||||
/> : "X"}
|
||||
</Text>
|
||||
)}
|
||||
</ListItem.Part>
|
||||
</ListItem>
|
||||
);
|
||||
|
||||
const setItemApproved = (id: number, approved: boolean) => {
|
||||
setGroceries((prevGroceries) =>
|
||||
prevGroceries.map((grocery) =>
|
||||
grocery.id === id ? { ...grocery, approved } : grocery
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<View>
|
||||
<FlatList
|
||||
data={groceries}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={(item) => item.title.toString()}
|
||||
renderItem={({ item }) => <GroceryItem item={item} handleItemApproved={setItemApproved} />}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
Reference in New Issue
Block a user