Skip to content

Commit

Permalink
feat: edit product
Browse files Browse the repository at this point in the history
  • Loading branch information
mrevanzak committed Nov 26, 2023
1 parent ea42dfa commit b70d56c
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 193 deletions.
3 changes: 2 additions & 1 deletion apps/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"superjson": "1.13.1",
"tus-js-client": "^3.1.1",
"use-tus": "^0.7.3",
"uuid": "^9.0.1",
"zod": "^3.21.4",
"zustand": "^4.4.6"
},
Expand Down Expand Up @@ -79,4 +80,4 @@
]
},
"prettier": "@vivat/prettier-config"
}
}
167 changes: 3 additions & 164 deletions apps/expo/src/app/(app)/(tabs)/listing.tsx
Original file line number Diff line number Diff line change
@@ -1,172 +1,11 @@
import React from "react";
import { ActivityIndicator, Alert } from "react-native";
import {
AnimatedImage,
AnimatedScanner,
BorderRadiuses,
Button,
KeyboardAwareScrollView,
Text,
View,
} from "react-native-ui-lib";
import { useRouter } from "expo-router";
import Input from "@/components/forms/Input";
import Picker from "@/components/forms/Picker";
import { useSelectImage } from "@/lib/hooks/useSelectImage";
import { api } from "@/utils/api";
import colors from "@/utils/colors";
import { storageClient } from "@/utils/supabase";
import { useUser } from "@clerk/clerk-expo";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { zodResolver } from "@hookform/resolvers/zod";
import { FormProvider, useForm } from "react-hook-form";
import { z } from "zod";

const schema = z.object({
name: z.string().min(3),
description: z.string().min(3),
price: z.coerce.number(),
stock: z.coerce.number(),
categoryId: z.string(),
});
import { View } from "react-native-ui-lib";
import ProductForm from "@/components/ProductForm";

export default function UploadProductScreen() {
const router = useRouter();
const { user } = useUser();

const { data } = api.category.getCategories.useQuery({ partial: true });
const { mutate, isPending } = api.product.addProduct.useMutation();

const { image, onSelectImage, onUpload, uploadProggres } = useSelectImage();

const methods = useForm<z.infer<typeof schema>>({
resolver: zodResolver(schema),
});
const { handleSubmit, reset } = methods;
const onSubmit = handleSubmit(async (data) => {
const filePath = `${user?.id}/${data.name}.png`;

const { error } = await onUpload("products", filePath);
if (error) {
Alert.alert("Gagal mengupload gambar");
return;
}

const imgUrl = storageClient.from("products").getPublicUrl(filePath);
mutate(
{
...data,
image: imgUrl.data.publicUrl,
},
{
onSuccess: () => {
reset();
router.push("/home");
},
},
);
});

return (
<View bg-white padding-s4 flex>
<KeyboardAwareScrollView>
<FormProvider {...methods}>
<View
marginB-s4
br40
className="border-primary border bg-white"
padding-s4
flex
>
<Text text70 primary>
Upload Gambar
</Text>
<View flex center paddingV-s6 className="space-y-2">
{image?.assets ? (
<>
<AnimatedImage
source={{ uri: image.assets[0]?.uri }}
style={{ width: 200, height: 200 }}
loader={
<ActivityIndicator
color={colors.secondary}
size="small"
/>
}
/>
{!!uploadProggres && (
<AnimatedScanner progress={uploadProggres} />
)}
<Button
onPress={onSelectImage}
label="Ganti Gambar"
bg-primary
/>
</>
) : (
<Button
onPress={onSelectImage}
bg-primary
outline
outlineColor={colors.primary}
borderRadius={BorderRadiuses.br40}
padding-s2
iconSource={() => (
<MaterialCommunityIcons
name="file-image-plus"
size={40}
color={colors.primary}
/>
)}
/>
)}
</View>
</View>
<Input
id="name"
label="Nama Produk"
placeholder="Masukan nama produk"
/>
<Input
id="description"
label="Deskripsi Produk"
multiline
placeholder="Masukan deskripsi produk"
/>
<Input
id="price"
label="Harga Produk"
placeholder="Masukan harga produk"
inputMode="numeric"
/>
<Input
id="stock"
label="Stok Produk"
placeholder="Masukan stok produk"
inputMode="numeric"
/>
<Picker
id="categoryId"
label="Kategori Produk"
placeholder="Pilih kategori produk"
topBarProps={{ title: "Kategori" }}
items={
data?.map((category) => ({
label: category.name,
value: category.id,
})) ?? [{ label: "Loading...", value: "loading" }]
}
useSafeArea
/>
</FormProvider>
<Button
label="Simpan"
onPress={onSubmit}
bg-primary
br40
disabled={!!uploadProggres ?? isPending}
/>
</KeyboardAwareScrollView>
<ProductForm />
</View>
);
}
36 changes: 25 additions & 11 deletions apps/expo/src/app/(app)/[productId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import { Link, usePathname } from "expo-router";
import { api } from "@/utils/api";
import colors from "@/utils/colors";
import rupiahFormatter from "@/utils/rupiahFormatter";
import { useUser } from "@clerk/clerk-expo";
import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";

export default function ProductDetailScreen() {
const { user } = useUser();
const pathname = usePathname();

const { data, isLoading, refetch } = api.product.showProduct.useQuery({
id: pathname.slice(1),
});
Expand Down Expand Up @@ -50,7 +53,7 @@ export default function ProductDetailScreen() {
paddingL-s4
centerV
flex
className="-ml-4 rounded-l-none space-y-1"
className="-ml-4 space-y-1 rounded-l-none"
>
<Text white text65>
{data?.name}
Expand Down Expand Up @@ -115,16 +118,27 @@ export default function ProductDetailScreen() {
spread
className="space-x-4 rounded-b-none"
>
{/* <Button bg-white primary label="Keranjang" br40 flex /> */}
<Link
href={{
pathname: "/checkout",
params: { productId: data?.id ?? "" },
}}
asChild
>
<Button bg-secondary primary label="Beli" br40 flex />
</Link>
{user?.id === data?.user.id ? (
<Link
href={{
pathname: "/edit-product",
params: { productId: data?.id ?? "" },
}}
asChild
>
<Button bg-secondary primary label="Ubah Detil Produk" br40 flex />
</Link>
) : (
<Link
href={{
pathname: "/checkout",
params: { productId: data?.id ?? "" },
}}
asChild
>
<Button bg-secondary primary label="Beli" br40 flex />
</Link>
)}
</View>
</View>
</SafeAreaView>
Expand Down
6 changes: 6 additions & 0 deletions apps/expo/src/app/(app)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ export default function AuthLayout() {
headerTitle: "Konfirmasi Pembayaran",
}}
/>
<Stack.Screen
name="edit-product"
options={{
headerTitle: "Ubah detil produk",
}}
/>
<Stack.Screen
name="address/index"
options={{
Expand Down
10 changes: 10 additions & 0 deletions apps/expo/src/app/(app)/edit-product.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import ProductForm from "@/components/ProductForm";
import { View } from "react-native-ui-lib";

export default function EditProductScreen() {
return (
<View bg-white padding-s4 flex>
<ProductForm edit />
</View>
);
}
Loading

0 comments on commit b70d56c

Please sign in to comment.