fixing redirect detail notification tab

This commit is contained in:
2025-12-23 12:17:17 +07:00
parent 36ebab7f9a
commit 016c77a586
6 changed files with 190 additions and 61 deletions

View File

@@ -53,6 +53,7 @@ import IndexHistoryEvent from './pages/history/event/IndexHistoryEvent';
// Image Viewer // Image Viewer
import ImageViewer from './Utils/ImageViewer'; import ImageViewer from './Utils/ImageViewer';
import RedirectWa from './pages/blank/RedirectWa';
const App = () => { const App = () => {
return ( return (
@@ -72,6 +73,8 @@ const App = () => {
element={<IndexVerificationSparepart />} element={<IndexVerificationSparepart />}
/> />
<Route path="/redirect" element={<RedirectWa />} />
{/* Protected Routes */} {/* Protected Routes */}
<Route path="/dashboard" element={<ProtectedRoute />}> <Route path="/dashboard" element={<ProtectedRoute />}>
<Route path="home" element={<Home />} /> <Route path="home" element={<Home />} />

View File

@@ -70,7 +70,18 @@ async function ApiRequest({ method = 'GET', params = {}, prefix = '/', token = t
}, },
}; };
const rawToken = localStorage.getItem('token'); const tokenRedirect = sessionStorage.getItem('token_redirect');
let rawToken = '';
if (tokenRedirect !== null) {
rawToken = tokenRedirect;
// console.log(`sessionStorage: ${tokenRedirect}`);
} else {
rawToken = localStorage.getItem('token');
// console.log(`localStorage: ${rawToken}`);
}
if (token && rawToken) { if (token && rawToken) {
const cleanToken = rawToken.replace(/"/g, ''); const cleanToken = rawToken.replace(/"/g, '');
request.headers['Authorization'] = `Bearer ${cleanToken}`; request.headers['Authorization'] = `Bearer ${cleanToken}`;

View File

@@ -146,7 +146,7 @@ const allItems = [
{ {
key: 'master-sparepart', key: 'master-sparepart',
icon: <ToolOutlined style={{ fontSize: '19px' }} />, icon: <ToolOutlined style={{ fontSize: '19px' }} />,
label: <Link to="/master/sparepart">sparepart</Link>, label: <Link to="/master/sparepart">Sparepart</Link>,
}, },
// { // {
// key: 'master-shift', // key: 'master-shift',

View File

@@ -0,0 +1,49 @@
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { verifyRedirect } from '../../api/auth';
import { encryptData } from '../../components/Global/Formatter';
import NotFound from './NotFound';
import Waiting from './Waiting';
import NotificationDetailTab from '../notificationDetail/IndexNotificationDetail';
export default function RedirectWa() {
const [idData, setIdData] = useState(0);
const [ready, setReady] = useState(0);
const location = useLocation();
// URLSearchParams untuk ambil query
const queryParams = new URLSearchParams(location.search);
const token = queryParams.get('token');
const handleInitForm = async (encodedToken) => {
const originalToken = decodeURIComponent(encodedToken);
// console.log(originalToken);
const response = await verifyRedirect({
tokenRedirect: originalToken,
});
console.log('tes', response);
const tokenResult = JSON.stringify(response.data?.accessToken);
sessionStorage.setItem('token_redirect', tokenResult);
response.data.auth = true;
sessionStorage.setItem('session', encryptData(response?.data));
setIdData(response.data.data.idData);
setReady(1);
};
useEffect(() => {
handleInitForm(token);
}, [idData]);
if (ready == 0) return <Waiting />;
if (idData === 0) return <NotFound />;
return <NotificationDetailTab id={idData} />;
}

View File

@@ -352,7 +352,7 @@ const ListJadwalShift = memo(function ListJadwalShift(props) {
<Title level={3}>Jadwal Shift</Title> <Title level={3}>Jadwal Shift</Title>
<Divider /> <Divider />
<Row> {/* <Row>
<Col xs={24}> <Col xs={24}>
<Row justify="end" align="middle" gutter={[8, 8]}> <Row justify="end" align="middle" gutter={[8, 8]}>
<Col xs={24} sm={24} md={12} lg={12}> <Col xs={24} sm={24} md={12} lg={12}>
@@ -383,7 +383,7 @@ const ListJadwalShift = memo(function ListJadwalShift(props) {
</Col> </Col>
</Row> </Row>
</Col> </Col>
</Row> </Row> */}
<div style={{ marginTop: '24px' }}> <div style={{ marginTop: '24px' }}>
{loading ? ( {loading ? (

View File

@@ -1,6 +1,20 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom'; import { useParams, useNavigate } from 'react-router-dom';
import { Layout, Card, Row, Col, Typography, Space, Button, Spin, Result, Input, message, Avatar, Tag } from 'antd'; import {
Layout,
Card,
Row,
Col,
Typography,
Space,
Button,
Spin,
Result,
Input,
message,
Avatar,
Tag,
} from 'antd';
import { import {
ArrowLeftOutlined, ArrowLeftOutlined,
CloseCircleFilled, CloseCircleFilled,
@@ -20,7 +34,11 @@ import {
SyncOutlined, SyncOutlined,
SendOutlined, SendOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { getNotificationDetail, createNotificationLog, getNotificationLogByNotificationId } from '../../api/notification'; import {
getNotificationDetail,
createNotificationLog,
getNotificationLogByNotificationId,
} from '../../api/notification';
const { Content } = Layout; const { Content } = Layout;
const { Text, Paragraph, Link } = Typography; const { Text, Paragraph, Link } = Typography;
@@ -113,9 +131,17 @@ const getDummyUsers = (notification) => {
const getStatusTag = (status) => { const getStatusTag = (status) => {
switch (status) { switch (status) {
case 'delivered': case 'delivered':
return <Tag icon={<CheckCircleOutlined />} color="success">Delivered</Tag>; return (
<Tag icon={<CheckCircleOutlined />} color="success">
Delivered
</Tag>
);
case 'sent': case 'sent':
return <Tag icon={<SyncOutlined spin />} color="processing">Sent</Tag>; return (
<Tag icon={<SyncOutlined spin />} color="processing">
Sent
</Tag>
);
case 'failed': case 'failed':
return <Tag color="error">Failed</Tag>; return <Tag color="error">Failed</Tag>;
default: default:
@@ -136,8 +162,9 @@ const getIconAndColor = (type) => {
} }
}; };
const NotificationDetailTab = () => { const NotificationDetailTab = (props) => {
const { notificationId } = useParams(); // Mungkin perlu disesuaikan jika route berbeda const params = useParams(); // Mungkin perlu disesuaikan jika route berbeda
const notificationId = props.id ?? params.notificationId;
const navigate = useNavigate(); const navigate = useNavigate();
const [notification, setNotification] = useState(null); const [notification, setNotification] = useState(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@@ -296,6 +323,7 @@ const NotificationDetailTab = () => {
marginBottom: '24px', marginBottom: '24px',
}} }}
> >
{!props.id && (
<Row justify="space-between" align="middle"> <Row justify="space-between" align="middle">
<Col> <Col>
<Button <Button
@@ -308,6 +336,8 @@ const NotificationDetailTab = () => {
</Button> </Button>
</Col> </Col>
</Row> </Row>
)}
<div <div
style={{ style={{
backgroundColor: '#f6ffed', backgroundColor: '#f6ffed',
@@ -426,24 +456,49 @@ const NotificationDetailTab = () => {
{/* Kolom Kanan: User History */} {/* Kolom Kanan: User History */}
<Col xs={24} lg={8}> <Col xs={24} lg={8}>
<Card <Card title="User History" size="small" style={{ height: '100%' }}>
title="User History" <div
size="small" style={{
style={{ height: '100%' }} maxHeight: '400px',
overflowY: 'auto',
padding: '2px',
}}
>
<Space
direction="vertical"
size={2}
style={{ width: '100%' }}
> >
<div style={{ maxHeight: '400px', overflowY: 'auto', padding: '2px' }}>
<Space direction="vertical" size={2} style={{ width: '100%' }}>
{getDummyUsers(notification).map((user) => ( {getDummyUsers(notification).map((user) => (
<Card key={user.id} size="small" style={{ width: '100%', margin: 0 }}> <Card
key={user.id}
size="small"
style={{ width: '100%', margin: 0 }}
>
<Row align="middle" justify="space-between"> <Row align="middle" justify="space-between">
<Col> <Col>
<Space align="center"> <Space align="center">
<Avatar size="large" icon={<UserOutlined />} /> <Avatar
size="large"
icon={<UserOutlined />}
/>
<div> <div>
<Text strong>{user.name}</Text> <Text strong>{user.name}</Text>
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}> <div
<PhoneOutlined style={{ color: '#8c8c8c' }} /> style={{
<Text type="secondary">{user.phone}</Text> display: 'flex',
alignItems: 'center',
gap: '4px',
}}
>
<PhoneOutlined
style={{
color: '#8c8c8c',
}}
/>
<Text type="secondary">
{user.phone}
</Text>
</div> </div>
</div> </div>
</Space> </Space>
@@ -457,7 +512,9 @@ const NotificationDetailTab = () => {
size="small" size="small"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
console.log(`Resend to ${user.name}`); console.log(
`Resend to ${user.name}`
);
}} }}
> >
Resend Resend
@@ -505,9 +562,7 @@ const NotificationDetailTab = () => {
</Card> </Card>
</Col> </Col>
<Col xs={24} md={8}> <Col xs={24} md={8}>
<Card <Card bodyStyle={{ padding: '12px', textAlign: 'center' }}>
bodyStyle={{ padding: '12px', textAlign: 'center' }}
>
<Space> <Space>
<HistoryOutlined <HistoryOutlined
style={{ fontSize: '16px', color: '#1890ff' }} style={{ fontSize: '16px', color: '#1890ff' }}
@@ -797,7 +852,9 @@ const NotificationDetailTab = () => {
rows={2} rows={2}
placeholder="Tuliskan update penanganan di sini..." placeholder="Tuliskan update penanganan di sini..."
value={newLogDescription} value={newLogDescription}
onChange={(e) => setNewLogDescription(e.target.value)} onChange={(e) =>
setNewLogDescription(e.target.value)
}
disabled={submitLoading} disabled={submitLoading}
/> />
</> </>
@@ -806,8 +863,18 @@ const NotificationDetailTab = () => {
type={isAddingLog ? 'primary' : 'dashed'} type={isAddingLog ? 'primary' : 'dashed'}
size="small" size="small"
block block
icon={submitLoading ? <LoadingOutlined /> : (!isAddingLog && <PlusOutlined />)} icon={
onClick={isAddingLog ? handleSubmitLog : () => setIsAddingLog(true)} submitLoading ? (
<LoadingOutlined />
) : (
!isAddingLog && <PlusOutlined />
)
}
onClick={
isAddingLog
? handleSubmitLog
: () => setIsAddingLog(true)
}
loading={submitLoading} loading={submitLoading}
disabled={submitLoading} disabled={submitLoading}
> >
@@ -855,7 +922,6 @@ const NotificationDetailTab = () => {
</Space> </Space>
</Card> </Card>
</Content> </Content>
</Layout> </Layout>
); );
}; };