Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
jinfa-platform
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
shenshaokai
jinfa-platform
Commits
584c0d7e
Commit
584c0d7e
authored
Apr 25, 2022
by
XieZhiXiong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 拆分锚点数据到各个页面
parent
12320742
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
173 additions
and
138 deletions
+173
-138
memberDetailsContext.ts
src/pages/member/memberDetailsContext.ts
+1
-1
archiveInfo.tsx
src/pages/member/memberMaintain/detailed/archiveInfo.tsx
+38
-1
basicInfo.tsx
src/pages/member/memberMaintain/detailed/basicInfo.tsx
+39
-1
changedInfo.tsx
src/pages/member/memberMaintain/detailed/changedInfo.tsx
+17
-1
equityInfo.tsx
src/pages/member/memberMaintain/detailed/equityInfo.tsx
+25
-1
index.tsx
src/pages/member/memberMaintain/detailed/index.tsx
+6
-131
levelInfo.tsx
src/pages/member/memberMaintain/detailed/levelInfo.tsx
+21
-1
sincerityInfo.tsx
src/pages/member/memberMaintain/detailed/sincerityInfo.tsx
+26
-1
No files found.
src/pages/member/memberDetailsContext.ts
View file @
584c0d7e
...
...
@@ -19,7 +19,7 @@ export interface MemberDetailsContextProps {
/**
* 锚点数据
*/
onAnchorsReady
?
:
(
anchores
:
AnchorsItem
[])
=>
void
,
onAnchorsReady
:
(
anchores
:
AnchorsItem
[])
=>
void
,
}
const
MemberDetailsContext
=
React
.
createContext
<
MemberDetailsContextProps
|
null
>
(
null
);
...
...
src/pages/member/memberMaintain/detailed/archiveInfo.tsx
View file @
584c0d7e
...
...
@@ -5,7 +5,7 @@
* @LastEditTime: 2021-11-29 20:07:02
* @Description: 会员档案信息
*/
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
use
Context
,
use
Effect
,
useState
}
from
'react'
;
import
{
useIntl
}
from
'umi'
;
import
{
Row
,
Col
,
Spin
}
from
'antd'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
...
...
@@ -14,6 +14,7 @@ import BASE_CONFIG from '@/../config/base.config.json';
import
{
EditableColumns
}
from
'@/components/PolymericTable/interface'
;
import
AnchorPage
from
'@/components/AnchorPage'
;
import
{
getIncomingInfoAnchorKey
}
from
'../../utils'
;
import
MemberDetailsContext
from
'../../memberDetailsContext'
;
import
MemberDocCategory
from
'../../components/MemberDocCategory'
;
import
MemberDocIncomingInfo
from
'../../components/MemberDocIncomingInfo'
;
import
MemberDocQualification
from
'../../components/MemberDocQualification'
;
...
...
@@ -105,6 +106,8 @@ const MemberArchiveInfo = () => {
const
[
archiveInfo
,
setArchiveInfo
]
=
useState
<
GetMemberAbilityMaintenanceDetailRecordResponse
>
();
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
contenxt
=
useContext
(
MemberDetailsContext
);
const
intl
=
useIntl
();
const
getArchiveInfo
=
()
=>
{
...
...
@@ -255,6 +258,40 @@ const MemberArchiveInfo = () => {
getArchiveInfo
();
},
[]);
useEffect
(()
=>
{
const
anchors
=
[
{
key
:
'categoryInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.categoryInfo'
}),
},
...(
archiveInfo
?.
depositDetails
?
archiveInfo
?.
depositDetails
?.
map
((
item
,
index
)
=>
({
key
:
getIncomingInfoAnchorKey
(
index
),
name
:
item
.
groupName
,
}))
:
[]
),
{
key
:
'qualitiesInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.qualitiesInfo'
}),
},
{
key
:
'inspectInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.inspectInfo'
}),
},
{
key
:
'appraisalInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.appraisalInfo'
}),
},
{
key
:
'rectifyInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.rectifyInfo'
}),
},
].
filter
(
Boolean
);
contenxt
.
onAnchorsReady
(
anchors
);
},
[
archiveInfo
]);
const
handleModifyAfter
=
()
=>
{
getArchiveInfo
();
};
...
...
src/pages/member/memberMaintain/detailed/basicInfo.tsx
View file @
584c0d7e
...
...
@@ -5,7 +5,8 @@
* @LastEditTime: 2021-11-17 18:01:05
* @Description: 会员基础信息详情
*/
import
React
,
{
useContext
}
from
'react'
;
import
React
,
{
useContext
,
useEffect
}
from
'react'
;
import
{
useIntl
}
from
'umi'
;
import
{
Row
,
Col
,
...
...
@@ -32,6 +33,43 @@ const MemberBasicInfo: React.FC<any> = () => {
const
contenxt
=
useContext
(
MemberDetailsContext
);
const
{
details
:
memberInfo
}
=
contenxt
;
const
intl
=
useIntl
();
useEffect
(()
=>
{
const
anchors
=
[
{
key
:
'verifySteps'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.verifySteps'
}),
},
{
key
:
'basicInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
}),
},
(
memberInfo
?.
memberTypeEnum
===
MEMBER_TYPE_CHANNEL_CORPORATE
||
memberInfo
?.
memberTypeEnum
===
MEMBER_TYPE_CHANNEL_INDIVIDUAL
?
{
key
:
'channelInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.channel'
}),
}
:
null
),
...(
memberInfo
&&
memberInfo
.
groups
?
memberInfo
.
groups
.
map
((
item
,
index
)
=>
({
key
:
`group
${
index
}
`
,
name
:
item
.
groupName
,
}))
:
[]
),
{
key
:
'flowRecords'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.flowRecords'
}),
},
].
filter
(
Boolean
);
contenxt
.
onAnchorsReady
(
anchors
);
},
[
memberInfo
]);
const
handleModifyAfter
=
()
=>
{
contenxt
.
refreshDetails
?.();
};
...
...
src/pages/member/memberMaintain/detailed/changedInfo.tsx
View file @
584c0d7e
...
...
@@ -5,16 +5,22 @@
* @LastEditTime: 2021-11-17 18:01:17
* @Description: 会员变更信息详情
*/
import
React
from
'react'
;
import
React
,
{
useContext
,
useEffect
}
from
'react'
;
import
{
useIntl
}
from
'umi'
;
import
{
Row
,
Col
}
from
'antd'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
getMemberAbilityMaintenanceDetailDepositHistoryPage
}
from
'@/services/MemberV2Api'
;
import
AnchorPage
from
'@/components/AnchorPage'
;
import
MemberDetailsContext
from
'../../memberDetailsContext'
;
import
ChangedInfo
,
{
FetchParamsType
,
ReponseType
}
from
'../../components/MemberChangedInfo'
;
const
MemberChangedInfo
=
()
=>
{
const
{
validateId
}
=
usePageStatus
();
const
contenxt
=
useContext
(
MemberDetailsContext
);
const
intl
=
useIntl
();
const
getInspectList
=
(
params
:
FetchParamsType
):
Promise
<
ReponseType
>
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
getMemberAbilityMaintenanceDetailDepositHistoryPage
({
...
...
@@ -33,6 +39,16 @@ const MemberChangedInfo = () => {
});
};
useEffect
(()
=>
{
const
anchors
=
[
{
key
:
'changedInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.changedInfo'
}),
},
];
contenxt
.
onAnchorsReady
(
anchors
);
},
[]);
return
(
<
Row
gutter=
{
[
16
,
16
]
}
>
{
/* 分类信息 */
}
...
...
src/pages/member/memberMaintain/detailed/equityInfo.tsx
View file @
584c0d7e
...
...
@@ -5,11 +5,13 @@
* @LastEditTime: 2021-11-17 18:02:20
* @Description: 会员权益信息详情
*/
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useContext
,
useEffect
,
useState
}
from
'react'
;
import
{
useIntl
}
from
'umi'
;
import
{
Spin
,
Row
,
Col
}
from
'antd'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
getMemberAbilityMaintenanceDetailRightBasic
,
GetMemberAbilityMaintenanceDetailRightBasicResponse
,
getMemberAbilityMaintenanceDetailRightHistoryPage
,
getMemberAbilityMaintenanceDetailRightSpendHistoryPage
}
from
'@/services/MemberV2Api'
;
import
AnchorPage
from
'@/components/AnchorPage'
;
import
MemberDetailsContext
from
'../../memberDetailsContext'
;
import
MemberRightsAnalysis
from
'../../components/MemberRightsAnalysis'
;
import
MemberRights
from
'../../components/MemberRights'
;
import
MemberRightsRecords
,
{
ReceivedData
,
UsageData
}
from
'../../components/MemberRightsRecords'
;
...
...
@@ -19,6 +21,10 @@ const MemberRightsInfo: React.FC<{}> = () => {
const
[
equityInfo
,
setEquityInfo
]
=
useState
<
GetMemberAbilityMaintenanceDetailRightBasicResponse
>
(
null
);
const
[
infoLoading
,
setInfoLoading
]
=
useState
(
false
);
const
contenxt
=
useContext
(
MemberDetailsContext
);
const
intl
=
useIntl
();
const
getEquityInfo
=
()
=>
{
setInfoLoading
(
true
);
getMemberAbilityMaintenanceDetailRightBasic
({
...
...
@@ -40,6 +46,24 @@ const MemberRightsInfo: React.FC<{}> = () => {
getEquityInfo
();
},
[]);
useEffect
(()
=>
{
const
anchors
=
[
{
key
:
'basicInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
}),
},
{
key
:
'memberEquity'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.memberEquity'
}),
},
{
key
:
'equityRecords'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.equityRecords'
}),
},
];
contenxt
.
onAnchorsReady
(
anchors
);
},
[]);
const
getReceivedList
=
params
=>
{
return
new
Promise
<
{
data
:
ReceivedData
[]
,
totalCount
:
number
}
>
((
resolve
,
reject
)
=>
{
getMemberAbilityMaintenanceDetailRightHistoryPage
({
...
...
src/pages/member/memberMaintain/detailed/index.tsx
View file @
584c0d7e
...
...
@@ -18,11 +18,7 @@ import {
}
from
'@ant-design/icons'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
getMemberAbilityMaintenanceDetailBasic
,
GetMemberAbilityMaintenanceDetailBasicResponse
}
from
'@/services/MemberV2Api'
;
import
{
MEMBER_TYPE_CHANNEL_CORPORATE
,
MEMBER_TYPE_CHANNEL_INDIVIDUAL
,
}
from
'@/constants/member'
;
import
AnchorPage
from
'@/components/AnchorPage'
;
import
AnchorPage
,
{
AnchorsItem
}
from
'@/components/AnchorPage'
;
import
AvatarWrap
from
'@/components/AvatarWrap'
;
import
{
MemberDetailsContextProvider
}
from
'../../memberDetailsContext'
;
import
Bookmark
from
'../../components/Bookmark'
;
...
...
@@ -34,6 +30,7 @@ const MemberMaintainDetailed: React.FC<IProps> = props => {
const
{
id
,
validateId
}
=
usePageStatus
();
const
[
memberInfo
,
setMemberInfo
]
=
useState
<
GetMemberAbilityMaintenanceDetailBasicResponse
>
(
null
);
const
[
infoLoading
,
setInfoLoading
]
=
useState
(
false
);
const
[
anchors
,
setAnchors
]
=
useState
<
AnchorsItem
[]
>
([]);
const
intl
=
useIntl
();
...
...
@@ -101,131 +98,8 @@ const MemberMaintainDetailed: React.FC<IProps> = props => {
return
'basicInfo'
;
};
const
getAnchorsArr
=
()
=>
{
const
markKey
=
getBookmarkKey
();
let
ret
=
[];
switch
(
markKey
)
{
case
'basicInfo'
:
ret
=
[
{
key
:
'verifySteps'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.verifySteps'
}),
},
{
key
:
'basicInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
}),
},
(
memberInfo
?.
memberTypeEnum
===
MEMBER_TYPE_CHANNEL_CORPORATE
||
memberInfo
?.
memberTypeEnum
===
MEMBER_TYPE_CHANNEL_INDIVIDUAL
?
{
key
:
'channelInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.channel'
}),
}
:
null
),
...(
memberInfo
&&
memberInfo
.
groups
?
memberInfo
.
groups
.
map
((
item
,
index
)
=>
({
key
:
`group
${
index
}
`
,
name
:
item
.
groupName
,
}))
:
[]
),
{
key
:
'flowRecords'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.flowRecords'
}),
},
].
filter
(
Boolean
);
break
;
case
'levelInfo'
:
ret
=
[
{
key
:
'memberLevel'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.memberLevel'
}),
},
{
key
:
'activePoints'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.activePoints'
}),
},
];
break
;
case
'equityInfo'
:
ret
=
[
{
key
:
'basicInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
}),
},
{
key
:
'memberEquity'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.memberEquity'
}),
},
{
key
:
'equityRecords'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.equityRecords'
}),
},
];
break
;
case
'sincerityInfo'
:
ret
=
[
{
key
:
'basicInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
}),
},
{
key
:
'orderEvaluation'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.orderEvaluation'
}),
},
{
key
:
'afterServiceEvaluation'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.afterServiceEvaluation'
}),
},
{
key
:
'feedbackRecords'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.feedbackRecords'
}),
},
];
break
;
case
'archiveInfo'
:
ret
=
[
{
key
:
'categoryInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.categoryInfo'
}),
},
{
key
:
'depositDetails'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.depositDetails'
}),
},
{
key
:
'qualitiesInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.qualitiesInfo'
}),
},
{
key
:
'inspectInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.inspectInfo'
}),
},
{
key
:
'appraisalInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.appraisalInfo'
}),
},
{
key
:
'rectifyInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.rectifyInfo'
}),
},
];
break
;
case
'changedInfo'
:
ret
=
[
{
key
:
'changedInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.changedInfo'
}),
},
];
break
;
default
:
break
;
}
return
ret
;
const
handleAnchorsReady
=
(
anchors
:
AnchorsItem
[])
=>
{
setAnchors
(
anchors
);
};
return
(
...
...
@@ -242,7 +116,7 @@ const MemberMaintainDetailed: React.FC<IProps> = props => {
/>
)
}
onBack=
{
()
=>
history
.
push
(
`/memberCenter/memberAbility/manage/maintain`
)
}
anchors=
{
getAnchorsArr
()
}
anchors=
{
anchors
}
extra=
{
(
<
Bookmark
value=
{
getBookmarkKey
()
}
onChange=
{
handleBookmarkChange
}
>
<
Bookmark
.
Item
value=
"basicInfo"
title=
{
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
})
}
icon=
{
<
UnorderedListOutlined
/>
}
/>
...
...
@@ -258,6 +132,7 @@ const MemberMaintainDetailed: React.FC<IProps> = props => {
value=
{
{
details
:
memberInfo
,
refreshDetails
:
getBasicInfo
,
onAnchorsReady
:
handleAnchorsReady
,
}
}
>
{
children
}
...
...
src/pages/member/memberMaintain/detailed/levelInfo.tsx
View file @
584c0d7e
...
...
@@ -5,11 +5,13 @@
* @LastEditTime: 2021-11-17 18:03:22
* @Description: 会员等级信息详情
*/
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
React
,
{
useState
,
useEffect
,
useContext
}
from
'react'
;
import
{
useIntl
}
from
'umi'
;
import
{
Spin
,
Row
,
Col
}
from
'antd'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
getMemberAbilityMaintenanceDetailLevelBasic
,
GetMemberAbilityMaintenanceDetailLevelBasicResponse
,
getMemberAbilityMaintenanceDetailLevelHistoryPage
}
from
'@/services/MemberV2Api'
;
import
AnchorPage
from
'@/components/AnchorPage'
;
import
MemberDetailsContext
from
'../../memberDetailsContext'
;
import
LevelInfo
from
'../../components/MemberLevelInfo'
;
import
MemberActivePointRecords
,
{
ListItem
}
from
'../../components/MemberActivePointRecords'
;
...
...
@@ -18,6 +20,10 @@ const MemberLevelInfo: React.FC<{}> = () => {
const
[
levelInfo
,
setLevelInfo
]
=
useState
<
GetMemberAbilityMaintenanceDetailLevelBasicResponse
>
(
null
);
const
[
infoLoading
,
setInfoLoading
]
=
useState
(
false
);
const
contenxt
=
useContext
(
MemberDetailsContext
);
const
intl
=
useIntl
();
const
getMemberLevelInfo
=
()
=>
{
if
(
!
id
&&
!
validateId
)
{
return
;
...
...
@@ -43,6 +49,20 @@ const MemberLevelInfo: React.FC<{}> = () => {
getMemberLevelInfo
();
},
[]);
useEffect
(()
=>
{
const
anchors
=
[
{
key
:
'memberLevel'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.memberLevel'
}),
},
{
key
:
'activePoints'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.activePoints'
}),
},
];
contenxt
.
onAnchorsReady
(
anchors
);
},
[]);
const
getActivePointRecords
=
params
=>
{
return
new
Promise
<
{
data
:
ListItem
[]
,
totalCount
:
number
}
>
((
resolve
,
reject
)
=>
{
getMemberAbilityMaintenanceDetailLevelHistoryPage
({
...
...
src/pages/member/memberMaintain/detailed/sincerityInfo.tsx
View file @
584c0d7e
...
...
@@ -5,12 +5,13 @@
* @LastEditTime: 2021-11-29 20:10:48
* @Description: 会员信用信息详情
*/
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
use
Context
,
use
Effect
,
useState
}
from
'react'
;
import
{
useIntl
}
from
'umi'
;
import
{
Row
,
Col
}
from
'antd'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
getMemberAbilityMaintenanceDetailCreditAftersaleHistoryPage
,
getMemberAbilityMaintenanceDetailCreditAftersaleSummary
,
getMemberAbilityMaintenanceDetailCreditBasic
,
getMemberAbilityMaintenanceDetailCreditComplainHistoryPage
,
getMemberAbilityMaintenanceDetailCreditComplainSummary
,
getMemberAbilityMaintenanceDetailCreditTradeHistoryPage
,
getMemberAbilityMaintenanceDetailCreditTradeSummary
}
from
'@/services/MemberV2Api'
;
import
AnchorPage
from
'@/components/AnchorPage'
;
import
MemberDetailsContext
from
'../../memberDetailsContext'
;
import
MemberSincerityAnalysis
from
'../../components/MemberSincerityAnalysis'
;
import
MemberEvaluation
,
{
EstimateSumItems
,
ListItem
}
from
'../../components/MemberEvaluation'
;
import
MemberFeedbackRecords
,
{
ListItem
as
FeedbackItem
,
AnalysisData
}
from
'../../components/MemberFeedbackRecords'
;
...
...
@@ -46,6 +47,8 @@ const MemberSincerityInfo: React.FC<{}> = () => {
sum
:
0
,
});
const
contenxt
=
useContext
(
MemberDetailsContext
);
const
intl
=
useIntl
();
const
getBasicInfo
=
()
=>
{
...
...
@@ -153,6 +156,28 @@ const MemberSincerityInfo: React.FC<{}> = () => {
getFeedbackSum
();
},
[]);
useEffect
(()
=>
{
const
anchors
=
[
{
key
:
'basicInfo'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.basic'
}),
},
{
key
:
'orderEvaluation'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.orderEvaluation'
}),
},
{
key
:
'afterServiceEvaluation'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.afterServiceEvaluation'
}),
},
{
key
:
'feedbackRecords'
,
name
:
intl
.
formatMessage
({
id
:
'member.management.maintain.detail.feedbackRecords'
}),
},
];
contenxt
.
onAnchorsReady
(
anchors
);
},
[]);
// 交易评论历史记录
const
getOrderEvaluationList
=
(
params
)
=>
{
return
new
Promise
<
{
data
:
ListItem
[]
,
totalCount
:
number
}
>
((
resolve
,
reject
)
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment