summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-02-22 10:14:32 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-02-22 10:14:32 +0700
commit3c559031623649a67825ff47f34512f0eb946861 (patch)
tree7b62faeebaf3e344cf01ba1c9ced03c7a4fcaf23 /src/lib
parent50f5a2d8897020acc11f2a20469ffdd42ca7c31b (diff)
fix
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/address/api/addressApi.js8
-rw-r--r--src/lib/address/api/cityApi.js8
-rw-r--r--src/lib/address/api/createAddressApi.js8
-rw-r--r--src/lib/address/api/districtApi.js8
-rw-r--r--src/lib/address/api/editAddressApi.js8
-rw-r--r--src/lib/address/api/subDistrictApi.js8
-rw-r--r--src/lib/address/components/CreateAddress.jsx230
-rw-r--r--src/lib/address/components/EditAddress.jsx256
-rw-r--r--src/lib/wishlist/components/Wishlists.jsx2
9 files changed, 535 insertions, 1 deletions
diff --git a/src/lib/address/api/addressApi.js b/src/lib/address/api/addressApi.js
new file mode 100644
index 00000000..f2fc6c9e
--- /dev/null
+++ b/src/lib/address/api/addressApi.js
@@ -0,0 +1,8 @@
+import odooApi from "@/core/api/odooApi"
+
+const addressApi = async ({ id }) => {
+ const dataAddress = await odooApi('GET', `/api/v1/partner/${id}/address`)
+ return dataAddress
+}
+
+export default addressApi \ No newline at end of file
diff --git a/src/lib/address/api/cityApi.js b/src/lib/address/api/cityApi.js
new file mode 100644
index 00000000..8cf1bedd
--- /dev/null
+++ b/src/lib/address/api/cityApi.js
@@ -0,0 +1,8 @@
+import odooApi from "@/core/api/odooApi"
+
+const cityApi = async () => {
+ const dataCities = await odooApi('GET', '/api/v1/city')
+ return dataCities
+}
+
+export default cityApi \ No newline at end of file
diff --git a/src/lib/address/api/createAddressApi.js b/src/lib/address/api/createAddressApi.js
new file mode 100644
index 00000000..29804d1c
--- /dev/null
+++ b/src/lib/address/api/createAddressApi.js
@@ -0,0 +1,8 @@
+import odooApi from "@/core/api/odooApi"
+
+const createAddressApi = async ({ data }) => {
+ const dataAddress = await odooApi('POST', '/api/v1/partner/address', data)
+ return dataAddress
+}
+
+export default createAddressApi \ No newline at end of file
diff --git a/src/lib/address/api/districtApi.js b/src/lib/address/api/districtApi.js
new file mode 100644
index 00000000..120757e9
--- /dev/null
+++ b/src/lib/address/api/districtApi.js
@@ -0,0 +1,8 @@
+import odooApi from "@/core/api/odooApi"
+
+const districtApi = async ({ cityId }) => {
+ const dataDistricts = await odooApi('GET', `/api/v1/district?city_id=${cityId}`)
+ return dataDistricts
+}
+
+export default districtApi \ No newline at end of file
diff --git a/src/lib/address/api/editAddressApi.js b/src/lib/address/api/editAddressApi.js
new file mode 100644
index 00000000..e01f6015
--- /dev/null
+++ b/src/lib/address/api/editAddressApi.js
@@ -0,0 +1,8 @@
+import odooApi from "@/core/api/odooApi"
+
+const editAddressApi = async ({ id, data }) => {
+ const dataAddress = await odooApi('PUT', `/api/v1/partner/${id}/address`, data)
+ return dataAddress
+}
+
+export default editAddressApi \ No newline at end of file
diff --git a/src/lib/address/api/subDistrictApi.js b/src/lib/address/api/subDistrictApi.js
new file mode 100644
index 00000000..64230838
--- /dev/null
+++ b/src/lib/address/api/subDistrictApi.js
@@ -0,0 +1,8 @@
+import odooApi from "@/core/api/odooApi"
+
+const subDistrictApi = async ({ districtId }) => {
+ const dataSubDistricts = await odooApi('GET', `/api/v1/sub_district?district_id=${districtId}`)
+ return dataSubDistricts
+}
+
+export default subDistrictApi \ No newline at end of file
diff --git a/src/lib/address/components/CreateAddress.jsx b/src/lib/address/components/CreateAddress.jsx
new file mode 100644
index 00000000..4ba99820
--- /dev/null
+++ b/src/lib/address/components/CreateAddress.jsx
@@ -0,0 +1,230 @@
+import HookFormSelect from "@/core/components/elements/Select/HookFormSelect"
+import useAuth from "@/core/hooks/useAuth"
+import { useRouter } from "next/router"
+import { Controller, useForm } from "react-hook-form"
+import * as Yup from "yup"
+import cityApi from "../api/cityApi"
+import districtApi from "../api/districtApi"
+import subDistrictApi from "../api/subDistrictApi"
+import { useEffect, useState } from "react"
+import createAddressApi from "../api/createAddressApi"
+import { toast } from "react-hot-toast"
+import { yupResolver } from "@hookform/resolvers/yup"
+
+const CreateAddress = () => {
+ const auth = useAuth()
+ const router = useRouter()
+ const {
+ register,
+ formState: { errors },
+ handleSubmit,
+ watch,
+ setValue,
+ control,
+ } = useForm({
+ resolver: yupResolver(validationSchema),
+ defaultValues
+ })
+
+ const [ cities, setCities ] = useState([])
+ const [ districts, setDistricts ] = useState([])
+ const [ subDistricts, setSubDistricts ] = useState([])
+
+ useEffect(() => {
+ const loadCities = async () => {
+ let dataCities = await cityApi()
+ dataCities = dataCities.map((city) => ({ value: city.id, label: city.name }))
+ setCities(dataCities)
+ }
+ loadCities()
+ }, [])
+
+ const watchCity = watch('city')
+ useEffect(() => {
+ setValue('district', '')
+ if (watchCity) {
+ const loadDistricts = async () => {
+ let dataDistricts = await districtApi({ cityId: watchCity })
+ dataDistricts = dataDistricts.map((district) => ({ value: district.id, label: district.name }))
+ setDistricts(dataDistricts)
+ }
+ loadDistricts()
+ }
+ }, [ watchCity, setValue ])
+
+ const watchDistrict = watch('district')
+ useEffect(() => {
+ setValue('subDistrict', '')
+ if (watchDistrict) {
+ const loadSubDistricts = async () => {
+ let dataSubDistricts = await subDistrictApi({ districtId: watchDistrict })
+ dataSubDistricts = dataSubDistricts.map((district) => ({ value: district.id, label: district.name }))
+ setSubDistricts(dataSubDistricts)
+ }
+ loadSubDistricts()
+ }
+ }, [ watchDistrict, setValue ])
+
+ const onSubmitHandler = async (values) => {
+ const data = {
+ ...values,
+ city_id: values.city,
+ district_id: values.district,
+ sub_district_id: values.subDistrict,
+ parent_id: auth.partnerId
+ }
+
+ const address = await createAddressApi({ data })
+ if (address?.id) {
+ toast.success('Berhasil menambahkan alamat')
+ router.back()
+ }
+ }
+
+ return (
+ <form className="p-4 flex flex-col gap-y-4" onSubmit={handleSubmit(onSubmitHandler)}>
+ <div>
+ <label className="form-label mb-2">Label Alamat</label>
+ <Controller
+ name="type"
+ control={control}
+ render={props => <HookFormSelect {...props} isSearchable={false} options={types} />}
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.type?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Nama</label>
+ <input
+ {...register('name')}
+ placeholder="John Doe"
+ type="text"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.name?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Email</label>
+ <input
+ {...register('email')}
+ placeholder="contoh@email.com"
+ type="email"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.email?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Mobile</label>
+ <input
+ {...register('mobile')}
+ placeholder="08xxxxxxxx"
+ type="tel"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.mobile?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Alamat</label>
+ <input
+ {...register('street')}
+ placeholder="Jl. Bandengan Utara 85A"
+ type="text"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.street?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kode Pos</label>
+ <input
+ {...register('zip')}
+ placeholder="10100"
+ type="number"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.zip?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kota</label>
+ <Controller
+ name="city"
+ control={control}
+ render={props => <HookFormSelect {...props} options={cities} />}
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">{ errors.city?.message }</div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kecamatan</label>
+ <Controller
+ name="district"
+ control={control}
+ render={props => (
+ <HookFormSelect
+ {...props}
+ options={districts}
+ disabled={!watchCity}
+ />
+ )}
+ />
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kelurahan</label>
+ <Controller
+ name="subDistrict"
+ control={control}
+ render={props => (
+ <HookFormSelect
+ {...props}
+ options={subDistricts}
+ disabled={!watchDistrict}
+ />
+ )}
+ />
+ </div>
+
+ <button
+ type="submit"
+ className="btn-yellow mt-2 w-full"
+ >
+ Simpan
+ </button>
+ </form>
+ )
+}
+
+const validationSchema = Yup.object().shape({
+ type: Yup.string().required('Harus di-pilih'),
+ name: Yup.string().min(3, 'Minimal 3 karakter').required('Harus di-isi'),
+ email: Yup.string().email('Format harus seperti contoh@email.com').required('Harus di-isi'),
+ mobile: Yup.string().required('Harus di-isi'),
+ street: Yup.string().required('Harus di-isi'),
+ zip: Yup.string().required('Harus di-isi'),
+ city: Yup.string().required('Harus di-pilih'),
+})
+
+const defaultValues = {
+ type: '',
+ name: '',
+ email: '',
+ mobile: '',
+ street: '',
+ city: '',
+ district: '',
+ subDistrict: '',
+ zip: '',
+}
+
+const types = [
+ { value: 'contact', label: 'Contact Address' },
+ { value: 'invoice', label: 'Invoice Address' },
+ { value: 'delivery', label: 'Delivery Address' },
+ { value: 'other', label: 'Other Address' },
+]
+
+export default CreateAddress \ No newline at end of file
diff --git a/src/lib/address/components/EditAddress.jsx b/src/lib/address/components/EditAddress.jsx
new file mode 100644
index 00000000..b866a1e6
--- /dev/null
+++ b/src/lib/address/components/EditAddress.jsx
@@ -0,0 +1,256 @@
+import { yupResolver } from "@hookform/resolvers/yup"
+import { useRouter } from "next/router"
+import { useEffect, useState } from "react"
+import * as Yup from "yup"
+import cityApi from "../api/cityApi"
+import { Controller, useForm } from "react-hook-form"
+import districtApi from "../api/districtApi"
+import subDistrictApi from "../api/subDistrictApi"
+import editAddressApi from "../api/editAddressApi"
+import HookFormSelect from "@/core/components/elements/Select/HookFormSelect"
+import { toast } from "react-hot-toast"
+
+const EditAddress = ({ id, defaultValues }) => {
+ const router = useRouter()
+ const {
+ register,
+ formState: { errors },
+ handleSubmit,
+ watch,
+ setValue,
+ getValues,
+ control,
+ } = useForm({
+ resolver: yupResolver(validationSchema),
+ defaultValues,
+ })
+
+ const [cities, setCities] = useState([])
+ const [districts, setDistricts] = useState([])
+ const [subDistricts, setSubDistricts] = useState([])
+
+ useEffect(() => {
+ const loadCities = async () => {
+ let dataCities = await cityApi()
+ dataCities = dataCities.map((city) => ({
+ value: city.id,
+ label: city.name,
+ }))
+ setCities(dataCities)
+ }
+ loadCities()
+ }, [])
+
+ const watchCity = watch("city")
+ useEffect(() => {
+ setValue("district", "")
+ if (watchCity) {
+ const loadDistricts = async () => {
+ let dataDistricts = await districtApi({ cityId: watchCity })
+ dataDistricts = dataDistricts.map((district) => ({
+ value: district.id,
+ label: district.name,
+ }))
+ setDistricts(dataDistricts)
+ let oldDistrict = getValues("oldDistrict")
+ if (oldDistrict) {
+ setValue("district", oldDistrict)
+ setValue("oldDistrict", "")
+ }
+ }
+ loadDistricts()
+ }
+ }, [watchCity, setValue, getValues])
+
+ const watchDistrict = watch("district")
+ useEffect(() => {
+ setValue("subDistrict", "")
+ if (watchDistrict) {
+ const loadSubDistricts = async () => {
+ let dataSubDistricts = await subDistrictApi({
+ districtId: watchDistrict,
+ })
+ dataSubDistricts = dataSubDistricts.map((district) => ({
+ value: district.id,
+ label: district.name,
+ }))
+ setSubDistricts(dataSubDistricts)
+ let oldSubDistrict = getValues("oldSubDistrict")
+
+ if (oldSubDistrict) {
+ setValue("subDistrict", oldSubDistrict)
+ setValue("oldSubDistrict", "")
+ }
+ }
+ loadSubDistricts()
+ }
+ }, [watchDistrict, setValue, getValues])
+
+ const onSubmitHandler = async (values) => {
+ const data = {
+ ...values,
+ city_id: values.city,
+ district_id: values.district,
+ sub_district_id: values.subDistrict,
+ }
+
+ const address = await editAddressApi({ id, data })
+ if (address?.id) {
+ toast.success("Berhasil mengubah alamat")
+ router.back()
+ }
+ }
+
+ return (
+ <form
+ className="p-4 flex flex-col gap-y-4"
+ onSubmit={handleSubmit(onSubmitHandler)}
+ >
+ <div>
+ <label className="form-label mb-2">Label Alamat</label>
+ <Controller
+ name="type"
+ control={control}
+ render={(props) => (
+ <HookFormSelect {...props} isSearchable={false} options={types} />
+ )}
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.type?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Nama</label>
+ <input
+ {...register("name")}
+ placeholder="John Doe"
+ type="text"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.name?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Email</label>
+ <input
+ {...register("email")}
+ placeholder="johndoe@example.com"
+ type="email"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.email?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Mobile</label>
+ <input
+ {...register("mobile")}
+ placeholder="08xxxxxxxx"
+ type="tel"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.mobile?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Alamat</label>
+ <input
+ {...register("street")}
+ placeholder="Jl. Bandengan Utara 85A"
+ type="text"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.street?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kode Pos</label>
+ <input
+ {...register("zip")}
+ placeholder="10100"
+ type="number"
+ className="form-input"
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.zip?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kota</label>
+ <Controller
+ name="city"
+ control={control}
+ render={(props) => <HookFormSelect {...props} options={cities} />}
+ />
+ <div className="text-caption-2 text-red_r-11 mt-1">
+ {errors.city?.message}
+ </div>
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kecamatan</label>
+ <Controller
+ name="district"
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={districts}
+ disabled={!watchCity}
+ />
+ )}
+ />
+ </div>
+
+ <div>
+ <label className="form-label mb-2">Kelurahan</label>
+ <Controller
+ name="subDistrict"
+ control={control}
+ render={(props) => (
+ <HookFormSelect
+ {...props}
+ options={subDistricts}
+ disabled={!watchDistrict}
+ />
+ )}
+ />
+ </div>
+
+ <button type="submit" className="btn-yellow mt-2 w-full">
+ Simpan
+ </button>
+ </form>
+ )
+}
+
+const validationSchema = Yup.object().shape({
+ type: Yup.string().required("Harus di-pilih"),
+ name: Yup.string().min(3, "Minimal 3 karakter").required("Harus di-isi"),
+ email: Yup.string()
+ .email("Format harus seperti johndoe@example.com")
+ .required("Harus di-isi"),
+ mobile: Yup.string().required("Harus di-isi"),
+ street: Yup.string().required("Harus di-isi"),
+ zip: Yup.string().required("Harus di-isi"),
+ city: Yup.string().required("Harus di-pilih"),
+})
+
+const types = [
+ { value: "contact", label: "Contact Address" },
+ { value: "invoice", label: "Invoice Address" },
+ { value: "delivery", label: "Delivery Address" },
+ { value: "other", label: "Other Address" },
+]
+
+export default EditAddress
diff --git a/src/lib/wishlist/components/Wishlists.jsx b/src/lib/wishlist/components/Wishlists.jsx
index 4bb63933..8cbbb0a2 100644
--- a/src/lib/wishlist/components/Wishlists.jsx
+++ b/src/lib/wishlist/components/Wishlists.jsx
@@ -33,7 +33,7 @@ const Wishlists = () => {
<div className="grid grid-cols-2 gap-3">
{wishlists.data?.products.map((product) => (
- <ProductCard key={product.id} data={product} />
+ <ProductCard key={product.id} product={product} />
))}
</div>