customer.ts
1 "use server" 2 3 import { sdk } from "@lib/config" 4 import medusaError from "@lib/util/medusa-error" 5 import { HttpTypes } from "@medusajs/types" 6 import { revalidateTag } from "next/cache" 7 import { redirect } from "next/navigation" 8 import { 9 getAuthHeaders, 10 getCacheOptions, 11 getCacheTag, 12 getCartId, 13 removeAuthToken, 14 removeCartId, 15 setAuthToken, 16 } from "./cookies" 17 18 export const retrieveCustomer = 19 async (): Promise<HttpTypes.StoreCustomer | null> => { 20 const authHeaders = await getAuthHeaders() 21 22 if (!authHeaders) return null 23 24 const headers = { 25 ...authHeaders, 26 } 27 28 const next = { 29 ...(await getCacheOptions("customers")), 30 } 31 32 return await sdk.client 33 .fetch<{ customer: HttpTypes.StoreCustomer }>(`/store/customers/me`, { 34 method: "GET", 35 query: { 36 fields: "*orders", 37 }, 38 headers, 39 next, 40 cache: "force-cache", 41 }) 42 .then(({ customer }) => customer) 43 .catch(() => null) 44 } 45 46 export const updateCustomer = async (body: HttpTypes.StoreUpdateCustomer) => { 47 const headers = { 48 ...(await getAuthHeaders()), 49 } 50 51 const updateRes = await sdk.store.customer 52 .update(body, {}, headers) 53 .then(({ customer }) => customer) 54 .catch(medusaError) 55 56 const cacheTag = await getCacheTag("customers") 57 revalidateTag(cacheTag) 58 59 return updateRes 60 } 61 62 export async function signup(_currentState: unknown, formData: FormData) { 63 const password = formData.get("password") as string 64 const customerForm = { 65 email: formData.get("email") as string, 66 first_name: formData.get("first_name") as string, 67 last_name: formData.get("last_name") as string, 68 phone: formData.get("phone") as string, 69 } 70 71 try { 72 const token = await sdk.auth.register("customer", "emailpass", { 73 email: customerForm.email, 74 password: password, 75 }) 76 77 await setAuthToken(token as string) 78 79 const headers = { 80 ...(await getAuthHeaders()), 81 } 82 83 const { customer: createdCustomer } = await sdk.store.customer.create( 84 customerForm, 85 {}, 86 headers 87 ) 88 89 const loginToken = await sdk.auth.login("customer", "emailpass", { 90 email: customerForm.email, 91 password, 92 }) 93 94 await setAuthToken(loginToken as string) 95 96 const customerCacheTag = await getCacheTag("customers") 97 revalidateTag(customerCacheTag) 98 99 await transferCart() 100 101 return createdCustomer 102 } catch (error: any) { 103 return error.toString() 104 } 105 } 106 107 export async function login(_currentState: unknown, formData: FormData) { 108 const email = formData.get("email") as string 109 const password = formData.get("password") as string 110 111 try { 112 await sdk.auth 113 .login("customer", "emailpass", { email, password }) 114 .then(async (token) => { 115 await setAuthToken(token as string) 116 const customerCacheTag = await getCacheTag("customers") 117 revalidateTag(customerCacheTag) 118 }) 119 } catch (error: any) { 120 return error.toString() 121 } 122 123 try { 124 await transferCart() 125 } catch (error: any) { 126 return error.toString() 127 } 128 } 129 130 export async function signout(countryCode: string) { 131 await sdk.auth.logout() 132 133 await removeAuthToken() 134 135 const customerCacheTag = await getCacheTag("customers") 136 revalidateTag(customerCacheTag) 137 138 await removeCartId() 139 140 const cartCacheTag = await getCacheTag("carts") 141 revalidateTag(cartCacheTag) 142 143 redirect(`/${countryCode}/account`) 144 } 145 146 export async function transferCart() { 147 const cartId = await getCartId() 148 149 if (!cartId) { 150 return 151 } 152 153 const headers = await getAuthHeaders() 154 155 await sdk.store.cart.transferCart(cartId, {}, headers) 156 157 const cartCacheTag = await getCacheTag("carts") 158 revalidateTag(cartCacheTag) 159 } 160 161 export const addCustomerAddress = async ( 162 currentState: Record<string, unknown>, 163 formData: FormData 164 ): Promise<any> => { 165 const isDefaultBilling = (currentState.isDefaultBilling as boolean) || false 166 const isDefaultShipping = (currentState.isDefaultShipping as boolean) || false 167 168 const address = { 169 first_name: formData.get("first_name") as string, 170 last_name: formData.get("last_name") as string, 171 company: formData.get("company") as string, 172 address_1: formData.get("address_1") as string, 173 address_2: formData.get("address_2") as string, 174 city: formData.get("city") as string, 175 postal_code: formData.get("postal_code") as string, 176 province: formData.get("province") as string, 177 country_code: formData.get("country_code") as string, 178 phone: formData.get("phone") as string, 179 is_default_billing: isDefaultBilling, 180 is_default_shipping: isDefaultShipping, 181 } 182 183 const headers = { 184 ...(await getAuthHeaders()), 185 } 186 187 return sdk.store.customer 188 .createAddress(address, {}, headers) 189 .then(async ({ customer }) => { 190 const customerCacheTag = await getCacheTag("customers") 191 revalidateTag(customerCacheTag) 192 return { success: true, error: null } 193 }) 194 .catch((err) => { 195 return { success: false, error: err.toString() } 196 }) 197 } 198 199 export const deleteCustomerAddress = async ( 200 addressId: string 201 ): Promise<void> => { 202 const headers = { 203 ...(await getAuthHeaders()), 204 } 205 206 await sdk.store.customer 207 .deleteAddress(addressId, headers) 208 .then(async () => { 209 const customerCacheTag = await getCacheTag("customers") 210 revalidateTag(customerCacheTag) 211 return { success: true, error: null } 212 }) 213 .catch((err) => { 214 return { success: false, error: err.toString() } 215 }) 216 } 217 218 export const updateCustomerAddress = async ( 219 currentState: Record<string, unknown>, 220 formData: FormData 221 ): Promise<any> => { 222 const addressId = 223 (currentState.addressId as string) || (formData.get("addressId") as string) 224 225 if (!addressId) { 226 return { success: false, error: "Address ID is required" } 227 } 228 229 const address = { 230 first_name: formData.get("first_name") as string, 231 last_name: formData.get("last_name") as string, 232 company: formData.get("company") as string, 233 address_1: formData.get("address_1") as string, 234 address_2: formData.get("address_2") as string, 235 city: formData.get("city") as string, 236 postal_code: formData.get("postal_code") as string, 237 province: formData.get("province") as string, 238 country_code: formData.get("country_code") as string, 239 } as HttpTypes.StoreUpdateCustomerAddress 240 241 const phone = formData.get("phone") as string 242 243 if (phone) { 244 address.phone = phone 245 } 246 247 const headers = { 248 ...(await getAuthHeaders()), 249 } 250 251 return sdk.store.customer 252 .updateAddress(addressId, address, {}, headers) 253 .then(async () => { 254 const customerCacheTag = await getCacheTag("customers") 255 revalidateTag(customerCacheTag) 256 return { success: true, error: null } 257 }) 258 .catch((err) => { 259 return { success: false, error: err.toString() } 260 }) 261 }