update transaction detail
This commit is contained in:
@ -1,95 +1,50 @@
|
|||||||
import { useState, useContext, useEffect, useCallback, MouseEvent } from 'react';
|
import { useState, useContext, useCallback, MouseEvent } from 'react';
|
||||||
import { AccountUserProfileContext } from '../hooks';
|
import { AccountUserProfileContext } from '../hooks';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { useAuthContext } from '@/auth';
|
import { useAuthContext } from '@/auth';
|
||||||
import { KeenIcon } from '@/components';
|
import { KeenIcon } from '@/components';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
type PasswordType = 'password' | 'retype_password' | 'current_password';
|
type PasswordType = 'password';
|
||||||
|
|
||||||
const PinCode = () => {
|
const PinCode = () => {
|
||||||
const { setPassword } = useContext(AccountUserProfileContext);
|
const { setPincode } = useContext(AccountUserProfileContext);
|
||||||
const { getUser } = useAuthContext();
|
const { getUser } = useAuthContext();
|
||||||
|
|
||||||
const [newPassword, setNewPassword] = useState('');
|
const [newPincode, setNewPincode] = useState('');
|
||||||
const [currentPassword, setCurrentPassword] = useState('');
|
|
||||||
const [confirmPassword, setConfirmPassword] = useState('');
|
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [messagePassword, setMessagePassword] = useState(true);
|
|
||||||
const [showPassword, setShowPassword] = useState({
|
const [showPassword, setShowPassword] = useState({
|
||||||
current_password: false,
|
|
||||||
password: false,
|
password: false,
|
||||||
retype_password: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const [passwordErrors, setPasswordErrors] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const validatePassword = (password: string) => {
|
|
||||||
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
|
|
||||||
const hasCapitalLetter = /[A-Z]/.test(password);
|
|
||||||
const hasNumber = /[0-9]/.test(password);
|
|
||||||
return hasSpecialChar && hasCapitalLetter && hasNumber;
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const passwordsMatch = newPassword === confirmPassword;
|
|
||||||
const isPasswordValid = validatePassword(newPassword);
|
|
||||||
setMessagePassword(passwordsMatch && isPasswordValid);
|
|
||||||
|
|
||||||
const errors: string[] = [];
|
|
||||||
if (newPassword) {
|
|
||||||
if (!/[A-Z]/.test(newPassword)) {
|
|
||||||
errors.push('Password must contain at least one capital letter');
|
|
||||||
}
|
|
||||||
if (!/[0-9]/.test(newPassword)) {
|
|
||||||
errors.push('Password must contain at least one number');
|
|
||||||
}
|
|
||||||
if (!/[!@#$%^&*(),.?":{}|<>]/.test(newPassword)) {
|
|
||||||
errors.push('Password must contain at least one special character');
|
|
||||||
}
|
|
||||||
if (newPassword !== confirmPassword) {
|
|
||||||
errors.push('Passwords do not match');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setPasswordErrors(errors);
|
|
||||||
}, [newPassword, confirmPassword]);
|
|
||||||
|
|
||||||
const handleResetPassword = useCallback(async () => {
|
const handleResetPassword = useCallback(async () => {
|
||||||
const user: any = await getUser();
|
const user: any = await getUser();
|
||||||
|
|
||||||
if (!messagePassword) {
|
|
||||||
toast.error('Passwords do not match!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await setPassword({
|
await setPincode({
|
||||||
current_password: currentPassword,
|
newpincode: newPincode,
|
||||||
password: newPassword,
|
|
||||||
retype_password: confirmPassword,
|
|
||||||
username: user.data.username ?? ''
|
|
||||||
});
|
});
|
||||||
|
|
||||||
setNewPassword('');
|
setNewPincode('');
|
||||||
setConfirmPassword('');
|
toast.success('Pin code updated successfully');
|
||||||
setCurrentPassword('');
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMessage =
|
const errorMessage =
|
||||||
error?.response?.data?.message ||
|
error?.response?.data?.message ||
|
||||||
error?.message ||
|
error?.message ||
|
||||||
'An error occurred while resetting the password.';
|
'An error occurred while updating the pin code.';
|
||||||
toast.error(errorMessage);
|
toast.error(errorMessage);
|
||||||
} finally {
|
} finally {
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
}, [currentPassword, newPassword, newPassword, messagePassword, getUser]);
|
}, [newPincode, setPincode, getUser]);
|
||||||
|
|
||||||
const isButtonDisabled = isSubmitting || !newPassword || !confirmPassword || !messagePassword;
|
const isButtonDisabled = isSubmitting || !newPincode;
|
||||||
|
|
||||||
const togglePassword = useCallback((event: MouseEvent<HTMLButtonElement>, key: string) => {
|
const togglePassword = useCallback((event: MouseEvent<HTMLButtonElement>, key: PasswordType) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setShowPassword((prev) => ({ ...prev, [key]: !prev[key as PasswordType] }));
|
setShowPassword((prev) => ({ ...prev, [key]: !prev[key] }));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -99,89 +54,28 @@ const PinCode = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="card-body grid gap-5">
|
<div className="card-body grid gap-5">
|
||||||
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||||
<label className="form-label max-w-56">Current Pin Code</label>
|
<label className="form-label max-w-56">New Pin Code</label>
|
||||||
<div className="input">
|
<div className="input relative">
|
||||||
<input
|
<input
|
||||||
type={showPassword.current_password ? 'text' : 'password'}
|
className="form-control pr-10" // untuk kasih jarak buat tombol mata
|
||||||
className="form-control"
|
|
||||||
placeholder="Current Pin Code"
|
|
||||||
value={currentPassword}
|
|
||||||
onChange={(e) => setCurrentPassword(e.target.value)}
|
|
||||||
disabled={isSubmitting}
|
|
||||||
/>
|
|
||||||
<button className="btn btn-icon" onClick={(e) => togglePassword(e, 'current_password')}>
|
|
||||||
<KeenIcon
|
|
||||||
icon="eye"
|
|
||||||
className={clsx('text-gray-500', { hidden: showPassword.current_password })}
|
|
||||||
/>
|
|
||||||
<KeenIcon
|
|
||||||
icon="eye-slash"
|
|
||||||
className={clsx('text-gray-500', { hidden: !showPassword.current_password })}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
|
||||||
<label className="form-label max-w-56">Pin Code</label>
|
|
||||||
<div className="input">
|
|
||||||
<input
|
|
||||||
className="form-control"
|
|
||||||
placeholder="New Pin Code"
|
placeholder="New Pin Code"
|
||||||
value={newPassword}
|
value={newPincode}
|
||||||
onChange={(e) => setNewPassword(e.target.value)}
|
onChange={(e) => setNewPincode(e.target.value)} // ✅ fix
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
type={showPassword.password ? 'text' : 'password'}
|
type={showPassword.password ? 'text' : 'password'}
|
||||||
/>
|
/>
|
||||||
<button className="btn btn-icon" onClick={(e) => togglePassword(e, 'password')}>
|
<button
|
||||||
|
className="btn btn-icon absolute right-2 top-1/2 transform -translate-y-1/2"
|
||||||
|
onClick={(e) => togglePassword(e, 'password')}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
<KeenIcon
|
<KeenIcon
|
||||||
icon="eye"
|
icon={showPassword.password ? 'eye-slash' : 'eye'}
|
||||||
className={clsx('text-gray-500', { hidden: showPassword.password })}
|
className="text-gray-500"
|
||||||
/>
|
|
||||||
<KeenIcon
|
|
||||||
icon="eye-slash"
|
|
||||||
className={clsx('text-gray-500', { hidden: !showPassword.password })}
|
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-2.5">
|
|
||||||
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
|
||||||
<label className="form-label max-w-56">Confirm New Pin Code</label>
|
|
||||||
<div className="input">
|
|
||||||
<input
|
|
||||||
type={showPassword.retype_password ? 'text' : 'password'}
|
|
||||||
className="form-control"
|
|
||||||
placeholder="Confirm New Pin Code"
|
|
||||||
value={confirmPassword}
|
|
||||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
||||||
disabled={isSubmitting}
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
className="btn btn-icon"
|
|
||||||
onClick={(e) => togglePassword(e, 'retype_password')}
|
|
||||||
>
|
|
||||||
<KeenIcon
|
|
||||||
icon="eye"
|
|
||||||
className={clsx('text-gray-500', { hidden: showPassword.retype_password })}
|
|
||||||
/>
|
|
||||||
<KeenIcon
|
|
||||||
icon="eye-slash"
|
|
||||||
className={clsx('text-gray-500', { hidden: !showPassword.retype_password })}
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
|
||||||
<label className="form-label max-w-56 text-white">Confirm New Pin Code</label>
|
|
||||||
{passwordErrors.length > 0 && (
|
|
||||||
<div className="text-xs text-red-500 mt-1 ms-3">
|
|
||||||
{passwordErrors.map((error, index) => (
|
|
||||||
<p key={index}>{error}</p>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -18,9 +18,15 @@ interface Profile {
|
|||||||
username: string;
|
username: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PinCode {
|
||||||
|
newpincode: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface ContextProps {
|
interface ContextProps {
|
||||||
password: Password | null;
|
password: Password | null;
|
||||||
profile: Profile | null;
|
profile: Profile | null;
|
||||||
|
pincode: PinCode | null;
|
||||||
|
setPincode: (pincode: PinCode) => Promise<void>;
|
||||||
setPassword: (password: Password) => Promise<void>;
|
setPassword: (password: Password) => Promise<void>;
|
||||||
setProfile: (profile: Profile) => Promise<void>;
|
setProfile: (profile: Profile) => Promise<void>;
|
||||||
}
|
}
|
||||||
@ -28,8 +34,10 @@ interface ContextProps {
|
|||||||
const initialProps: ContextProps = {
|
const initialProps: ContextProps = {
|
||||||
profile: null,
|
profile: null,
|
||||||
password: null,
|
password: null,
|
||||||
|
pincode: null,
|
||||||
setPassword: async () => {},
|
setPassword: async () => {},
|
||||||
setProfile: async () => {}
|
setProfile: async () => {},
|
||||||
|
setPincode: async () => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const AccountUserProfileContext = createContext<ContextProps>(initialProps);
|
const AccountUserProfileContext = createContext<ContextProps>(initialProps);
|
||||||
@ -39,25 +47,29 @@ const API_URL = apiConfig.service_dashboard;
|
|||||||
const AccountUserProfileContextProvider = ({ children }: { children: React.ReactNode }) => {
|
const AccountUserProfileContextProvider = ({ children }: { children: React.ReactNode }) => {
|
||||||
/* state */
|
/* state */
|
||||||
const { login } = useAuthContext();
|
const { login } = useAuthContext();
|
||||||
const [profile, setProfile] = useState<Profile | null>(null);
|
const [profile, setProfileState] = useState<Profile | null>(null);
|
||||||
const [password, setPassword] = useState<Password | null>(null);
|
const [password, setPasswordState] = useState<Password | null>(null);
|
||||||
|
const [pinCode, setPincodeState] = useState<PinCode | null>(null);
|
||||||
const [alert, setAlert] = useState({
|
const [alert, setAlert] = useState({
|
||||||
show: false,
|
show: false,
|
||||||
message: ''
|
message: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
const { PutData } = useCallApi();
|
const { PutData, PostData } = useCallApi();
|
||||||
const { PostData } = useCallApi();
|
|
||||||
const handleSetPassword = async (newPassword: Password) => {
|
|
||||||
setPassword(newPassword);
|
|
||||||
|
|
||||||
const handleError = (error: any, defaultMessage: string) => {
|
// Helper function to handle API errors
|
||||||
const errorMessage = error?.response?.data?.message || error?.message || defaultMessage;
|
const handleError = (error: any, defaultMessage: string) => {
|
||||||
setAlert({ show: true, message: errorMessage });
|
const errorMessage = error?.response?.data?.message || error?.message || defaultMessage;
|
||||||
toast.error(errorMessage);
|
setAlert({ show: true, message: errorMessage });
|
||||||
};
|
toast.error(errorMessage);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to handle password update
|
||||||
|
const handleSetPassword = async (newPassword: Password) => {
|
||||||
|
setPasswordState(newPassword);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Validate the current password
|
||||||
const validate = await PostData(`${API_URL}/login`, {
|
const validate = await PostData(`${API_URL}/login`, {
|
||||||
password: newPassword.current_password,
|
password: newPassword.current_password,
|
||||||
username: newPassword.username
|
username: newPassword.username
|
||||||
@ -68,6 +80,7 @@ const AccountUserProfileContextProvider = ({ children }: { children: React.React
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the password
|
||||||
const response = await PutData(`${API_URL}/user/update_password`, {
|
const response = await PutData(`${API_URL}/user/update_password`, {
|
||||||
password: newPassword.password,
|
password: newPassword.password,
|
||||||
retype_password: newPassword.retype_password
|
retype_password: newPassword.retype_password
|
||||||
@ -83,9 +96,10 @@ const AccountUserProfileContextProvider = ({ children }: { children: React.React
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Function to handle profile update
|
||||||
const handleSetProfile = async (newProfile: Profile) => {
|
const handleSetProfile = async (newProfile: Profile) => {
|
||||||
try {
|
try {
|
||||||
setProfile(newProfile);
|
setProfileState(newProfile);
|
||||||
|
|
||||||
const response = await PutData(`${API_URL}/user/update_profile/`, {
|
const response = await PutData(`${API_URL}/user/update_profile/`, {
|
||||||
name: newProfile.name,
|
name: newProfile.name,
|
||||||
@ -95,9 +109,19 @@ const AccountUserProfileContextProvider = ({ children }: { children: React.React
|
|||||||
|
|
||||||
toast.success('Profile updated successfully.');
|
toast.success('Profile updated successfully.');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMessage = error?.message || 'Failed to update Profile. Please try again.';
|
handleError(error, 'Failed to update Profile. Please try again.');
|
||||||
setAlert({ show: true, message: errorMessage });
|
}
|
||||||
toast.error(errorMessage);
|
};
|
||||||
|
|
||||||
|
// Function to handle pin code update
|
||||||
|
const handleSetPinCode = async (newPinCode: PinCode) => {
|
||||||
|
try {
|
||||||
|
setPincodeState(newPinCode);
|
||||||
|
|
||||||
|
// You can make an API call here to update the pin code in the backend if needed
|
||||||
|
toast.success('Pin code updated successfully.');
|
||||||
|
} catch (error: any) {
|
||||||
|
handleError(error, 'Failed to update Pin Code. Please try again.');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,8 +130,10 @@ const AccountUserProfileContextProvider = ({ children }: { children: React.React
|
|||||||
value={{
|
value={{
|
||||||
password,
|
password,
|
||||||
profile,
|
profile,
|
||||||
|
pincode: pinCode,
|
||||||
setPassword: handleSetPassword,
|
setPassword: handleSetPassword,
|
||||||
setProfile: handleSetProfile
|
setProfile: handleSetProfile,
|
||||||
|
setPincode: handleSetPinCode
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -125,7 +125,17 @@ const DetailApprovalTransaction = () => {
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Transaction Date</p>
|
<p className="text-sm text-gray-500">Transaction Date</p>
|
||||||
<p className="font-medium">{transactionDetails?.transaction_date}</p>
|
<p className="font-medium">{transactionDetails?.transaction_date
|
||||||
|
? new Date(transactionDetails.transaction_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Full Name</p>
|
<p className="text-sm text-gray-500">Full Name</p>
|
||||||
@ -299,8 +309,17 @@ const DetailApprovalTransaction = () => {
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Transaction Date</p>
|
<p className="text-sm text-gray-500">Transaction Date</p>
|
||||||
<p className="font-medium">{transactionDetails?.transaction_date}</p>
|
<p className="font-medium">{transactionDetails?.transaction_date
|
||||||
</div>
|
? new Date(transactionDetails.transaction_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</p> </div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Full Name</p>
|
<p className="text-sm text-gray-500">Full Name</p>
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
@ -607,7 +626,7 @@ const DetailApprovalTransaction = () => {
|
|||||||
<tr className="bg-gray-100">
|
<tr className="bg-gray-100">
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Type</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Type</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Date</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Date</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Body</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Date</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Body</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Body</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Code</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Code</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Endpoint</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Endpoint</th>
|
||||||
@ -618,8 +637,29 @@ const DetailApprovalTransaction = () => {
|
|||||||
transactionDetails.p24.map((log: { request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
|
transactionDetails.p24.map((log: { request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
|
||||||
<tr key={index} className="border-t">
|
<tr key={index} className="border-t">
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.type}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.type}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_date}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.request_date
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.response_date}</td>
|
? new Date(log.request_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</td>
|
||||||
|
|
||||||
|
<td className="px-4 py-2 text-sm text-gray-500">{log.response_date
|
||||||
|
? new Date(log.response_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_body}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.request_body}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.response_body}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.response_body}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint ?? '-'}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint ?? '-'}</td>
|
||||||
|
|||||||
@ -45,8 +45,8 @@ const DetailTransaction = () => {
|
|||||||
id: selectedTransactionId
|
id: selectedTransactionId
|
||||||
});
|
});
|
||||||
setTransactionDetails(response?.data);
|
setTransactionDetails(response?.data);
|
||||||
console.log(response?.data);
|
// console.log(response?.data);
|
||||||
console.log(selectedTransactionId);
|
// console.log(selectedTransactionId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching transaction', error);
|
console.error('Error fetching transaction', error);
|
||||||
}
|
}
|
||||||
@ -141,7 +141,20 @@ const DetailTransaction = () => {
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Transaction Date</p>
|
<p className="text-sm text-gray-500">Transaction Date</p>
|
||||||
<p className="font-medium">{transactionDetails?.transaction_date}</p>
|
<p className="font-medium">
|
||||||
|
{transactionDetails?.transaction_date
|
||||||
|
? new Date(transactionDetails.transaction_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}
|
||||||
|
</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Full Name</p>
|
<p className="text-sm text-gray-500">Full Name</p>
|
||||||
@ -312,7 +325,17 @@ const DetailTransaction = () => {
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Transaction Date</p>
|
<p className="text-sm text-gray-500">Transaction Date</p>
|
||||||
<p className="font-medium">{transactionDetails?.transaction_date}</p>
|
<p className="font-medium">{transactionDetails?.transaction_date
|
||||||
|
? new Date(transactionDetails.transaction_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm text-gray-500">Full Name</p>
|
<p className="text-sm text-gray-500">Full Name</p>
|
||||||
@ -614,7 +637,7 @@ const DetailTransaction = () => {
|
|||||||
<tr className="bg-gray-100">
|
<tr className="bg-gray-100">
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Type</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Type</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Date</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Date</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Body</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Date</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Body</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Body</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Code</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Response Code</th>
|
||||||
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Endpoint</th>
|
<th className="px-4 py-2 text-left text-sm text-gray-500">Request Endpoint</th>
|
||||||
@ -625,8 +648,29 @@ const DetailTransaction = () => {
|
|||||||
transactionDetails.p24.map((log: { request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
|
transactionDetails.p24.map((log: { request_endpoint: string, type: string; request_date: string; response_date: string; request_body: string; response_body: string; response_code: number }, index: number) => (
|
||||||
<tr key={index} className="border-t">
|
<tr key={index} className="border-t">
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.type}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.type}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_date}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.request_date
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.response_date}</td>
|
? new Date(log.request_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</td>
|
||||||
|
|
||||||
|
<td className="px-4 py-2 text-sm text-gray-500">{log.response_date
|
||||||
|
? new Date(log.response_date).toLocaleDateString('en-GB', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
})
|
||||||
|
: ''}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_body}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.request_body}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.response_body}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.response_body}</td>
|
||||||
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint ?? '-'}</td>
|
<td className="px-4 py-2 text-sm text-gray-500">{log.request_endpoint ?? '-'}</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user