Compare commits
9 Commits
95d467c513
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f5da9bee4 | |||
| c98e72d8d9 | |||
| 3f896d3824 | |||
| 989b78175e | |||
| 657ee9931c | |||
| 0838235f89 | |||
| 7e5f71d345 | |||
| e4d533dd18 | |||
| d9eae27d20 |
4
.env
4
.env
@@ -1,2 +1,2 @@
|
||||
# NEXT_PUBLIC_BASE_URL=https://api-staging.cariparkir.co.id
|
||||
NEXT_PUBLIC_BASE_URL=https://d2cc-101-255-119-166.ap.ngrok.io
|
||||
NEXT_PUBLIC_STAGING_CP_URL=https://api-staging.cariparkir.co.id
|
||||
NEXT_PUBLIC_BASE_URL=https://api-bookinglockey-staging.cariparkir.co.id
|
||||
@@ -52,10 +52,10 @@ const Ask = () => {
|
||||
aplikasi ini.</p>
|
||||
</div>
|
||||
<div className={'absolute top-3 left-0 z-0'}>
|
||||
<Image src={'/assets/backgrounds/cloud-left.svg'} alt={'cloud-left'}/>
|
||||
<Image src={'/assets/backgrounds/cloud-left.svg'} alt={'cloud-left'} preview={false} />
|
||||
</div>
|
||||
<div className={'absolute top-1 right-0 z-0'}>
|
||||
<Image src={'/assets/backgrounds/cloud-right.svg'} alt={'cloud-right'}/>
|
||||
<Image src={'/assets/backgrounds/cloud-right.svg'} alt={'cloud-right'} preview={false} />
|
||||
</div>
|
||||
|
||||
<div className={'flex flex-col gap-4 m-5'}>
|
||||
@@ -66,7 +66,7 @@ const Ask = () => {
|
||||
<span className={'font-bold'}>{it.no}</span>
|
||||
<span className={'text-xs text-[#9B9B9B]'}>{it.timetable}</span>
|
||||
</div>
|
||||
<Image src={it.icon} alt={'icon'}width={40} height={40} />
|
||||
<Image src={it.icon} alt={'icon'} width={40} height={40} preview={false} />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -2,19 +2,15 @@ import React from 'react';
|
||||
import Image from "next/image";
|
||||
import {Divider} from "antd";
|
||||
|
||||
const Location = () => {
|
||||
const Location = ({location}) => {
|
||||
return (
|
||||
<div>
|
||||
<div className={'flex flex-col items-center gap-4'}>
|
||||
<Image src={'/assets/images/location.svg'} width={80} height={80} alt={'location'}/>
|
||||
|
||||
<div className={'text-center'}>
|
||||
<h1 className={'font-bold'}>LOCKEY Lippo Mall Kemang</h1>
|
||||
<p className={'text-sm text-[#B7BAC2]'}>Jl. Pangeran Antasari No.36, Bangka, Kec. Mampang Prpt.,
|
||||
Kota, Daerah
|
||||
Khusus Ibukota
|
||||
Jakarta
|
||||
12150</p>
|
||||
<h1 className={'font-bold'}>{location?.data?.[0]?.name}</h1>
|
||||
<p className={'text-sm text-[#B7BAC2]'}>{location?.data?.[0]?.address}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export const appConfig = {
|
||||
apiUrl: process.env.NEXT_PUBLIC_BASE_URL
|
||||
apiUrl: process.env.NEXT_PUBLIC_BASE_URL,
|
||||
apiCpUrl: process.env.NEXT_PUBLIC_STAGING_CP_URL,
|
||||
}
|
||||
11
package-lock.json
generated
11
package-lock.json
generated
@@ -17,6 +17,7 @@
|
||||
"babel-plugin-import": "^1.13.5",
|
||||
"date-fns": "^2.29.3",
|
||||
"framer-motion": "^7.6.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"mobx": "^6.6.1",
|
||||
"mobx-react-lite": "^3.4.0",
|
||||
"next": "12.2.2",
|
||||
@@ -3456,6 +3457,11 @@
|
||||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jwt-decode": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
|
||||
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
||||
},
|
||||
"node_modules/klona": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
|
||||
@@ -8624,6 +8630,11 @@
|
||||
"object.assign": "^4.1.2"
|
||||
}
|
||||
},
|
||||
"jwt-decode": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
|
||||
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
||||
},
|
||||
"klona": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz",
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"babel-plugin-import": "^1.13.5",
|
||||
"date-fns": "^2.29.3",
|
||||
"framer-motion": "^7.6.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"mobx": "^6.6.1",
|
||||
"mobx-react-lite": "^3.4.0",
|
||||
"next": "12.2.2",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import DefaultLayout from "../../../components/Layout/DefaultLayout";
|
||||
import { useRouter } from 'next/router';
|
||||
import { Image } from 'antd';
|
||||
@@ -9,6 +9,11 @@ import { observer } from 'mobx-react-lite';
|
||||
const FlashScreen = observer(() => {
|
||||
const router = useRouter();
|
||||
const store = useStore()
|
||||
const [startOrder, setStartOrder] = useState(false)
|
||||
|
||||
setTimeout(() => {
|
||||
setStartOrder(true)
|
||||
}, 3000)
|
||||
|
||||
const { qrCode } = router.query;
|
||||
|
||||
@@ -22,12 +27,22 @@ const FlashScreen = observer(() => {
|
||||
if (isAvailable) {
|
||||
localStorage.setItem("lockey_id", isAvailable?.id)
|
||||
localStorage.setItem("location_name", isAvailable?.location_name);
|
||||
if (startOrder) {
|
||||
store.lockey.createOrder({
|
||||
lockeyId: isAvailable.id
|
||||
})
|
||||
.then(res => {
|
||||
router.push(`/${qrCode}/payment-order/`)
|
||||
localStorage.setItem("idOrder", res?.data?.id)
|
||||
localStorage.setItem("bookingCode", res?.data?.booking_code);
|
||||
localStorage.setItem("checkInTime", res?.data?.check_in_time)
|
||||
localStorage.setItem("validTime", res?.data?.valid_time)
|
||||
localStorage.setItem("price", res?.data?.lockey?.price)
|
||||
console.log(res, "data order")
|
||||
})
|
||||
} else {
|
||||
console.log("loading")
|
||||
}
|
||||
} else if (isNotAvailable) {
|
||||
localStorage.setItem("lockey_id", isNotAvailable?.id)
|
||||
localStorage.setItem("location_name", isNotAvailable?.location_name);
|
||||
@@ -35,7 +50,7 @@ const FlashScreen = observer(() => {
|
||||
}
|
||||
console.log(isAvailable, "jj")
|
||||
}
|
||||
}, [router.isReady, listLockeys])
|
||||
}, [startOrder])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -7,18 +7,22 @@ import Ask from "../../../components/Ask";
|
||||
import Location from "../../../components/Location";
|
||||
import DownloadApps from "../../../components/DownloadApps";
|
||||
import Sheet from 'react-modal-sheet';
|
||||
import Countdown from "react-countdown";
|
||||
import Countdown, { zeroPad } from "react-countdown";
|
||||
import {useRouter} from "next/router";
|
||||
import BottomSheet from "../../../components/BottomSheet";
|
||||
import { botsRepository } from '../../../repository/bots';
|
||||
import { useStore } from '../../../components/StoreProvider';
|
||||
import { format } from 'date-fns';
|
||||
import Link from 'next/link';
|
||||
|
||||
const Payment = observer(() => {
|
||||
const [form] = Form.useForm();
|
||||
const router = useRouter();
|
||||
const store = useStore();
|
||||
const { qrCode } = router.query;
|
||||
const [orderId, setOrderId] = useState('');
|
||||
const [price, setPrice] = useState(0);
|
||||
const [checkInTime, setCheckInTime] = useState('');
|
||||
const [open, setOpen] = useState(false);
|
||||
const [openOrderOut, setOpenOrderOut] = useState(false);
|
||||
const [notOrder, setNotOrder] = useState(false);
|
||||
@@ -33,19 +37,36 @@ const Payment = observer(() => {
|
||||
};
|
||||
|
||||
const { data: location } = botsRepository.hooks.useGetLocationByQR(qrCode)
|
||||
console.log(location, "he")
|
||||
|
||||
const expiredOrder = async () => {
|
||||
try {
|
||||
await botsRepository.api.updateStatusExpiredOrder(orderId)
|
||||
setIsNotComplete(true)
|
||||
setOpenOrderOut(true)
|
||||
} catch (err) {
|
||||
console.log("session epxired failed")
|
||||
setIsNotComplete(true)
|
||||
setOpenOrderOut(true)
|
||||
}
|
||||
}
|
||||
|
||||
const renderer = ({minutes, seconds, completed}) => {
|
||||
if (completed) {
|
||||
// router.push('/flash-screen');
|
||||
console.log("session complite")
|
||||
} else {
|
||||
return <span>{minutes}:{seconds}</span>;
|
||||
return <span>{zeroPad(minutes)}:{zeroPad(seconds)}</span>;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== undefined) {
|
||||
let price = localStorage.getItem("price")
|
||||
let price = localStorage.getItem("price");
|
||||
let getCheckInTime = localStorage.getItem("checkInTime");
|
||||
let orderId = localStorage.getItem("idOrder")
|
||||
setOrderId(orderId);
|
||||
setPrice(price)
|
||||
const checkInTime = format(new Date(getCheckInTime), "mm")
|
||||
console.log(checkInTime, "time")
|
||||
}
|
||||
}, [])
|
||||
|
||||
@@ -72,17 +93,14 @@ const Payment = observer(() => {
|
||||
<>
|
||||
{isNotComplete ? (
|
||||
<div className="flex items-center justify-center bg-[#FF4F34] h-10 text-base">
|
||||
<span className={'text-white'}>Batas Penyelesaian Pesanan mu Habis</span>
|
||||
<span className={'text-white'}>Batas Penyelesaian pesanan Anda Habis</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-center bg-[#00AED6] h-10 text-base">
|
||||
<span className={'text-white'}>Selesaikan Pesanan mu dalam <Countdown
|
||||
date={Date.now() + 300000}
|
||||
<span className={'text-white'}>selesaikan pesananmu dalam <Countdown
|
||||
date={Date.now(checkInTime) + 300000}
|
||||
renderer={renderer}
|
||||
onComplete={() => {
|
||||
setIsNotComplete(true)
|
||||
setOpenOrderOut(true)
|
||||
}}/>
|
||||
onComplete={expiredOrder}/>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -104,7 +122,7 @@ const Payment = observer(() => {
|
||||
type={'number'}
|
||||
className={'rounded-lg'}
|
||||
size={'large'}
|
||||
suffix={<Image src={'/assets/icons/gopay.svg'} width={80} height={30} alt={'icon gopay'} />}
|
||||
suffix={<Image src={'/assets/icons/gopay.svg'} width={80} height={30} preview={false} alt={'icon gopay'} />}
|
||||
placeholder={'08xxxxxxxxx'}
|
||||
disabled={
|
||||
notOrder === true
|
||||
@@ -194,8 +212,8 @@ const Payment = observer(() => {
|
||||
<BottomSheet onOpen={openOrderOut} onClose={() => setOpenOrderOut(false)}>
|
||||
<div className={'px-5 max-w-lg'}>
|
||||
<div className={'flex justify-center'}>
|
||||
<Image src={'/assets/images/illustration-order-out.svg'} width={200} height={200}
|
||||
alt={'confirmation'}/>
|
||||
<Image src={'/assets/images/Illustration-order-out.svg'} width={200} height={200}
|
||||
alt={'confirmation'} preview={false} />
|
||||
</div>
|
||||
|
||||
<h3 className={'text-lg font-bold'}>Ingin pesan kembali?</h3>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {http} from "../utils/http";
|
||||
import { http2 } from "../utils/http2"
|
||||
|
||||
const url = {
|
||||
contacts: () => '/product/api/v5/customer-service'
|
||||
@@ -8,7 +8,7 @@ const hooks = {}
|
||||
|
||||
const api = {
|
||||
async getContacts() {
|
||||
return await http.fetcher(url.contacts())
|
||||
return await http2.fetcher(url.contacts())
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ const url = {
|
||||
findLocationByQrCode: (qrCode) => `/locations/findOne/${qrCode}`,
|
||||
createOrder: () => `/bots/create-order`,
|
||||
checkTransaction: (orderId) => `/bots/find/one-history/${orderId}`,
|
||||
expiredOrder: (id) => `/bots/expired-status/${id}`,
|
||||
}
|
||||
|
||||
const hooks = {
|
||||
@@ -22,6 +23,14 @@ const api = {
|
||||
const res = await http.fetcher(url.checkTransaction(orderId));
|
||||
return res
|
||||
},
|
||||
|
||||
async createOrder(body) {
|
||||
return await http.post(url.createOrder(), body)
|
||||
},
|
||||
|
||||
updateStatusExpiredOrder(id) {
|
||||
return http.put(url.expiredOrder(id));
|
||||
}
|
||||
}
|
||||
|
||||
export const botsRepository = {
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import {http} from "../utils/http";
|
||||
|
||||
const url = {
|
||||
payment: () => '/usermanagement/api/v5/validate/check-phone-register'
|
||||
payment: () => '/usermanagement/api/v5/validate/check-phone-register',
|
||||
sendInvoice: () => '/payment-service/api/v6/send-invoice',
|
||||
}
|
||||
|
||||
const hooks = {}
|
||||
|
||||
const api = {
|
||||
// async usePayment(data) {
|
||||
// return await http.post(url.payment, data)
|
||||
// },
|
||||
}
|
||||
const api = {}
|
||||
|
||||
export const orderRepository = {
|
||||
url,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { http } from "../utils/http";
|
||||
import { http2 } from "../utils/http2";
|
||||
import {botsRepository} from "../repository/bots";
|
||||
import { orderRepository } from "../repository/order";
|
||||
|
||||
@@ -12,6 +13,6 @@ export class LockeyStore {
|
||||
}
|
||||
|
||||
createPayment(body) {
|
||||
return http.post(orderRepository.url.payment(), body);
|
||||
return http2.post(orderRepository.url.payment(), body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,3 +19,13 @@ body {
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input[type=number]{
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
78
utils/http2.js
Normal file
78
utils/http2.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import {appConfig} from "../config/app";
|
||||
import {TokenUtil} from "./token";
|
||||
import axios from "axios";
|
||||
|
||||
const instanceCp = axios.create({
|
||||
baseURL: appConfig.apiCpUrl,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
instanceCp.interceptors.request.use(
|
||||
(config) => {
|
||||
if (TokenUtil.accessToken) {
|
||||
config.headers["Authorization"] = 'Bearer ' + TokenUtil.accessToken; // for Node.js Express back-end
|
||||
}
|
||||
config.headers["ngrok-skip-browser-warning"] = true
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
instanceCp.interceptors.response.use(
|
||||
(res) => {
|
||||
return res;
|
||||
},
|
||||
async (err) => {
|
||||
const originalConfig = err.config;
|
||||
|
||||
if (originalConfig.url !== "/auth/login" && err.response) {
|
||||
// Access Token was expired
|
||||
if (err.response.status === 401 && !originalConfig._retry) {
|
||||
originalConfig._retry = true;
|
||||
|
||||
try {
|
||||
if (TokenUtil.refreshToken) {
|
||||
await authenticationRepository.api.refreshToken()
|
||||
}
|
||||
return instanceCp(originalConfig);
|
||||
} catch (_error) {
|
||||
return Promise.reject(_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
|
||||
export const http2 = {
|
||||
fetcher: async (url) => {
|
||||
const resp = await instanceCp.get(appConfig.apiCpUrl + url);
|
||||
|
||||
return resp.data;
|
||||
},
|
||||
get: async (url, opts = {}) => {
|
||||
const resp = await instanceCp.post(appConfig.apiCpUrl + url);
|
||||
|
||||
return resp.data;
|
||||
},
|
||||
post: async (url, data, opts) => {
|
||||
const resp = await instanceCp.post(appConfig.apiCpUrl + url, data);
|
||||
|
||||
return resp.data;
|
||||
},
|
||||
put: async (url, data, opts) => {
|
||||
const resp = await instanceCp.put(appConfig.apiCpUrl + url, data);
|
||||
|
||||
return resp.data;
|
||||
},
|
||||
del: async (url, opts) => {
|
||||
const resp = await instanceCp.delete(appConfig.apiCpUrl + url);
|
||||
|
||||
return resp.data;
|
||||
},
|
||||
};
|
||||
@@ -2096,6 +2096,11 @@
|
||||
"array-includes" "^3.1.3"
|
||||
"object.assign" "^4.1.2"
|
||||
|
||||
"jwt-decode@^3.1.2":
|
||||
"integrity" "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
||||
"resolved" "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz"
|
||||
"version" "3.1.2"
|
||||
|
||||
"klona@^2.0.4":
|
||||
"integrity" "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA=="
|
||||
"resolved" "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz"
|
||||
|
||||
Reference in New Issue
Block a user