Commit 932190a7 authored by XieZhiXiong's avatar XieZhiXiong
parents 95d3a2a1 6f40bdc7
......@@ -11,6 +11,7 @@ const config: any = {
"process.env.BACK_GATEWAY": process.env.BACK_GATEWAY
},
// layout: {},
esbuild: {},
antd: {},
locale: {
antd: true,
......
......@@ -52,6 +52,7 @@ const AuthConfigRoute = {
name: 'accountSetting',
component: '@/pages/accountSetting'
},
// 账号修改
{
path: '/memberCenter/systemSetting/editAccount',
name: 'editAccount',
......
......@@ -184,15 +184,7 @@ const CommodityRoute = {
icon: 'smile',
hideInMenu: true,
component: './repositories/adjustRepository',
},
{
path: '/memberCenter/commodityAbility/repositories/viewRepository',
name: 'viewRepository',
key: 'viewRepository',
icon: 'smile',
hideInMenu: true,
component: './repositories/viewRepository',
},
}
]
}
......
......@@ -36,6 +36,7 @@
"@formily/antd": "^1.3.3",
"@formily/antd-components": "^1.3.3",
"@umijs/hooks": "^1.9.3",
"@umijs/plugin-esbuild": "^1.0.1",
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0",
"antd-img-crop": "^3.12.0",
......
......@@ -105,9 +105,11 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
const animationFrameId = requestAnimationFrame(() => {
setSelectedKeys(keys);
});
console.log(currentRouter, "currentRouter")
return () =>
window.cancelAnimationFrame &&
window.cancelAnimationFrame(animationFrameId);
}, [location.pathname]);
useEffect(() => {
......@@ -122,9 +124,10 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
setOpenKeys([])
}
}, [currentRouter, location.pathname, collapsed])
return (
<ProLayout
title={``}
pageTitleRender={() => currentRouter ? currentRouter.name : window.location.href}
style={{ minHeight: '100vh' }}
logo={logo}
formatMessage={formatMessage}
......
......@@ -250,16 +250,25 @@ const EditDataComponent = (props) => {
}
}
// 获取手机验证码
// 获取新手机手机验证码
const getCode = useCallback(() => {
const value = props.type == 'phone'
? props.form.getFieldValue('newPhone')
: props.form.getFieldValue('email')
const { form, type } = props
const SERVICE_CHECK = {
'email': PublicApi.postMemberSecurityEmailEmailTonew,
// 'phone': PublicApi.postmembersecur
'phone': PublicApi.postMemberSecurityPhoneSmsTonew,
}
const service = SERVICE_CHECK[type];
const postData = (
props.type == 'phone'
? {
countryCode: form.getFieldValue('country'),
phone: form.getFieldValue('newPhone')
}
: { email: form.getFieldValue('email') }
)
console.log(postData);
// return ;
service(postData)
}, [])
return (
......
const phoneRegExp = {
'86': /^1[345789]\d{9}$/,
'86': /^1[345789]\d{9}$/, // 内地
'852': /^(5|6|8|9)\\d{7}$/, // 香港
'81': /0?[789](?:\d{8}|\d{9})$/, // 日本
'1': /[2-9]\d{2}[2-9](?!11)\d{6}$/, // 美国
'33': /[67]\d{8}$/, //'法国'
}
export default phoneRegExp;
\ No newline at end of file
......@@ -37,20 +37,21 @@ const TypeVerify: React.FC<IProps> = (props) => {
const descRender = () => {
if(type == 'email' && email == '') {
return "你还没有绑定邮箱"
} else if(type == 'paycode') {
return "请前往设置支付密码"
} else if(type == 'paycode' && paycode == 0) {
return "您未设置支付密码"
}
return TITLE_NAP[type].desc.replace(/\{\{(.*?)\}\}/, (match, key) => { return props[key] });
}
const renderLink = () => {
let title = "修改";
if(type == 'email' && email == '') {
return <a>设置邮箱</a>
} else if(type == 'paycode' && paycode == 0) {
return <a>设置支付密码</a>
title = "设置邮箱"
} else if(type == 'paycode') {
title = paycode == 0 ? "设置支付密码" : "重置支付密码"
}
return <Link to={`/memberCenter/systemSetting/editAccount?type=${type}`}>修改</Link>
return <Link to={`/memberCenter/systemSetting/editAccount?type=${type}`}>{title}</Link>
}
return (
......
import React, { useState, useCallback } from 'react';
// import { SchemaForm } from '@formily/antd';
import { Form, Input, Button, Row, Col } from 'antd';
import { Form, Input, Button, Row, Col, message } from 'antd';
import SafeVerification from '../../SafeVerification';
import TypeForHeader from '../../TypeForHeader';
import EditDataComponent from '../../EditDataComponent';
import { PublicApi } from '@/services/api';
import GetCaptchaCode from '../../GetCaptchaCode';
import { history } from 'umi';
const layout = {
labelCol: { span: 3 },
......@@ -42,15 +43,18 @@ const EmailVerifyPanel = (props) => {
} else {
params = {
...params,
smsCode: values.emailCaptcha,
smsCode: values.phoneCaptcha,
countryCode: values.country,
phone: values.newPhone
}
}
console.log(params);
return ;
service(params).then((data) => {
console.log("success")
if(data.code == 1000) {
console.log("success")
history.push('/memberCenter/systemSetting/accountSetting')
}
})
}
......@@ -68,8 +72,6 @@ const EmailVerifyPanel = (props) => {
// 验证旧的邮箱验证码
const handleVerifySuccess = () => {
setVisible(true);
return ;
const captcha = form.getFieldValue('captcha');
let SERVICE_CHECK = {
'loginPwd': PublicApi.postMemberSecurityPswEmailCheck,
......@@ -77,13 +79,15 @@ const EmailVerifyPanel = (props) => {
'phone': PublicApi.postMemberSecurityPhoneEmailCheck
}
const service = SERVICE_CHECK[props.pageType];
service({smsCode: captcha}).then((data) => {
service({smsCode: captcha}, { ctlType: 'none' }).then((data) => {
console.log(data);
if(data.code == 1000) {
message.success("验证成功")
setVisible(true);
} else {
message.error(data.error)
}
})
}
return (
......
import React, {useState} from 'react';
// import { SchemaForm } from '@formily/antd';
import { Form, Input, Button, Row, Col } from 'antd';
import { Form, Input, Button, Row, Col, message } from 'antd';
import SafeVerification from '../../SafeVerification';
import TypeForHeader from '../../TypeForHeader';
import EditDataComponent from '../../EditDataComponent';
import { PublicApi } from '@/services/api';
import { history } from 'umi'
const layout = {
labelCol: { span: 3 },
......@@ -25,20 +25,54 @@ const PaycodeVerifyPanel: React.FC<IProps> = (props) => {
const [ visible, setVisible ] = useState(false);
const [form] = Form.useForm();
const handleVerifySuccess = () => {
setVisible(true);
console.log(123);
}
const onFinish = (values) => {
const handleFinish = (values) => {
const { pageType } = props;
///member/security/email/
const UPDATE_SERVICE = {
'loginPwd': PublicApi.postMemberSecurityPswUpdate,
'email': PublicApi.postMemberSecurityEmailUpdate,
'phone': PublicApi.postMemberSecurityPhoneUpdate,
}
const service = UPDATE_SERVICE[pageType];
let params = {};
if(pageType == 'loginPwd') {
console.log(values);
PublicApi.postMemberSecurityPswUpdatePay({
payPassword: values.captcha,
password: values.password
})
params['password'] = values.password
} else if(pageType == 'email') {
params = {
...params,
smsCode: values.emailCaptcha,
email: values.email
}
} else {
params = {
...params,
smsCode: values.phoneCaptcha,
countryCode: values.country,
phone: values.newPhone
}
}
console.log(values);
console.log(params);
service(params).then((data) => {
console.log("success")
if(data.code == 1000) {
history.push('/memberCenter/systemSetting/accountSetting')
}
})
}
// 验证旧的支付密码
const handleVerifySuccess = () => {
const payPassword = form.getFieldValue('paycode');
const service = PublicApi.postMemberSecurityPayCheck;
service({payPassword: payPassword}, { ctlType: "none" }).then((data) => {
console.log(data);
if(data.code == 1000) {
message.success("验证成功")
setVisible(true);
} else {
message.error(data.message)
}
})
}
return (
<div>
......@@ -48,26 +82,29 @@ const PaycodeVerifyPanel: React.FC<IProps> = (props) => {
labelAlign="left"
name="basic"
form={form}
onFinish={onFinish}
onFinish={handleFinish}
>
<Form.Item label="支付密码">
<Row gutter={10}>
<Col span={18}>
<Form.Item
name="paycode"
noStyle
rules={[{ required: true, message: '请填写支付密码' }]}
>
<Input />
</Form.Item>
</Col>
</Row>
</Form.Item>
{
!visible
? <div style={{marginBottom: '130px'}}>
<SafeVerification handleVerifySuccess={handleVerifySuccess} />
</div>
? <>
<Form.Item label="支付密码">
<Row gutter={10}>
<Col span={18}>
<Form.Item
name="paycode"
noStyle
rules={[{ required: true, message: '请填写支付密码' }]}
>
<Input />
</Form.Item>
</Col>
</Row>
</Form.Item>
<div style={{marginBottom: '130px'}}>
<SafeVerification handleVerifySuccess={handleVerifySuccess} />
</div>
</>
: null
}
{
......
import React, { useCallback, useState } from 'react';
// import { SchemaForm } from '@formily/antd';
import { Form, Input, Button, Row, Col } from 'antd';
import { Form, Input, Button, Row, Col, message } from 'antd';
import SafeVerification from '../../SafeVerification';
import TypeForHeader from '../../TypeForHeader';
import EditDataComponent from '../../EditDataComponent';
import GetCaptchaCode from '../../GetCaptchaCode';
import { PublicApi } from '@/services/api';
import { history } from 'umi';
const layout = {
labelCol: { span: 3 },
......@@ -29,7 +30,6 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
const { phone, pageType } = props;
const onFinish = (values) => {
const { pageType } = props;
///member/security/email/
const UPDATE_SERVICE = {
'loginPwd': PublicApi.postMemberSecurityPswUpdate,
'email': PublicApi.postMemberSecurityEmailUpdate,
......@@ -48,13 +48,16 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
} else {
params = {
...params,
smsCode: values.emailCaptcha,
smsCode: values.phoneCaptcha,
countryCode: values.country,
phone: values.newPhone
}
}
service(params).then((data) => {
console.log("success")
if(data.code == 1000) {
console.log("success")
history.push('/memberCenter/systemSetting/accountSetting')
}
})
console.log(params);
}
......@@ -71,20 +74,21 @@ const PhoneVerifyPanel: React.FC<IProps> = (props) => {
}, [])
const handleVerifySuccess = () => {
// setVisible(true);
// return ;
const captcha = form.getFieldValue('captcha');
// 验证旧手机短信/member/security/email/sms/
let SERVICE_CHECK = {
'loginPwd': PublicApi.postMemberSecurityPswSmsCheck,
'email': PublicApi.postMemberSecurityPswEmailCheck,
'email': PublicApi.postMemberSecurityEmailSmsCheck,
'phone': PublicApi.postMemberSecurityPhoneSmsCheck
}
const service = SERVICE_CHECK[props.pageType];
service({smsCode: captcha}).then((data) => {
service({smsCode: captcha}, { ctlType: 'none' }).then((data) => {
console.log(data);
if(data.code == 1000) {
message.success("验证成功")
setVisible(true);
} else {
message.error(data.message)
}
})
......
......@@ -4,7 +4,7 @@ import { PublicApi } from '@/services/api';
import GetCaptchaCode from '../../GetCaptchaCode';
import SafeVerification from '../../SafeVerification';
import TypeForHeader from '../../TypeForHeader';
import EditDataComponent from '../../EditDataComponent';
import { history } from 'umi'
const layout = {
labelCol: { span: 3 },
......@@ -26,19 +26,36 @@ const ResetPayCode: React.FC<IProps> = (props) => {
const [form] = Form.useForm();
const { phone, pageType } = props;
const onFinish = (values) => {
const postData = {
payPassword: values.password
}
// /member/security/pay/update
const service = PublicApi.postMemberSecurityPayUpdate;
service(postData).then((data) => {
if(data.code == 1000) {
console.log("success")
history.push('/memberCenter/systemSetting/accountSetting')
}
})
console.log(values);
}
// 手机验证码
// 获取手机验证码
const getCode = useCallback(() => {
const service = PublicApi.postMemberSecurityPaySms;
service();
}, [])
// 检验 验证码
const handleVerifySuccess = () => {
setVisible(true);
// 验证旧手机短信
const captcha = form.getFieldValue('captcha');
const service = PublicApi.postMemberSecurityPaySmsCheck
service({smsCode: captcha}).then((data) => {
console.log(data);
if(data.code == 1000) {
setVisible(true);
}
})
}
// 密码验证
......@@ -48,17 +65,19 @@ const ResetPayCode: React.FC<IProps> = (props) => {
}
}
// 支付密码
const renderPwd = () => {
return (
<>
<Form.Item
label="登录密码"
label="设置新的支付密码"
>
<Row gutter={10}>
<Col span={18}>
<Form.Item
name="password"
rules={[{ required: true, message: "请填写支付面膜"}]}
noStyle
rules={[{ required: true, message: "请填写支付密码"}]}
>
<Input.Password />
</Form.Item>
......@@ -99,9 +118,10 @@ const ResetPayCode: React.FC<IProps> = (props) => {
onFinish={onFinish}
form={form}
>
{
!visible
? <Form.Item label="验证码">
{
!visible
? <>
<Form.Item label="验证码">
<Row gutter={10}>
<Col span={14}>
<Form.Item
......@@ -119,14 +139,10 @@ const ResetPayCode: React.FC<IProps> = (props) => {
</Col>
</Row>
</Form.Item>
: null
}
{
!visible
? <div style={{marginBottom: '130px'}}>
<SafeVerification handleVerifySuccess={handleVerifySuccess} />
</div>
<div style={{marginBottom: '130px'}}>
<SafeVerification handleVerifySuccess={handleVerifySuccess} />
</div>
</>
: null
}
{
......
......@@ -18,7 +18,7 @@ const VerifyPanel: React.FC<Iprops> = (props) => {
<TabPane tab="邮箱验证" disabled={email == ''} key="2">
<EmailVerifyPanel email={email} pageType={pageType} />
</TabPane>
<TabPane tab="支付密码验证" disabled={false} key="3">
<TabPane tab="支付密码验证" disabled={!hasPaycode} key="3">
<PaycodeVerifyPanel pageType={pageType} />
</TabPane>
</Tabs>
......
......@@ -6,13 +6,9 @@ import { history } from 'umi';
import VerifyPanel from './components/VerifyPanel';
import { PublicApi } from '@/services/api';
import EditAccountContext from './context/EditAccountContext';
import ResetPayCode from './components/VerifyPanel/Panel/ResetPayCode'
const MAP = {
'loginPwd': '修改登录密码',
'email': '修改邮箱',
'phone': '修改手机',
'paycode': '重置支付密码'
}
const getData = async () => {
const res = await PublicApi.getMemberSecurityGet();
......@@ -23,13 +19,19 @@ interface accountProps {
userId?: number | string | null
phone?: string,
email?: string,
hasPayPassword: number, // 0 | 1
hasPayPassword?: number, // 0 | 1
}
const EditAccount = (props) => {
const { type = 'loginPwd' } = props.location.query
const [account, setAccount] = useState<accountProps>({})
const MAP = {
'loginPwd': '修改登录密码',
'email': account.email ? '修改邮箱' : '设置邮箱',
'phone': '修改手机',
'paycode': account.hasPayPassword ? '重置支付密码' : '设置支付密码'
}
useEffect(() => {
async function init() {
const res = await getData();
......@@ -44,16 +46,21 @@ const EditAccount = (props) => {
title={MAP[type]}
>
<Card>
<EditAccountContext.Provider
value={{
phone: account.phone,
email: "735051883@qq.com",
hasPaycode: !!account.hasPayPassword,
pageType: type
}}
>
<VerifyPanel />
</EditAccountContext.Provider>
{
type == 'paycode'
? <ResetPayCode phone={account.phone} pageType={type} />
: <EditAccountContext.Provider
value={{
phone: account.phone,
email: account.email,
hasPaycode: !!account.hasPayPassword,
pageType: type
}}
>
<VerifyPanel />
</EditAccountContext.Provider>
}
</Card>
</PageHeaderWrapper>
)
......
......@@ -11,11 +11,10 @@ const getData = async () => {
return res.data
}
const AccountSetting = () => {
const [account, setAccount] = useState({})
const [account, setAccount] = useState<any>({})
useEffect(() => {
async function init() {
const res = await getData();
console.log(res);
setAccount(res);
}
init()
......
import React, { useState, useRef, ReactNode } from 'react'
import { history } from 'umi'
import { Card, Space, Radio, Row, Col, Descriptions, Table, Tag } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
EyeOutlined,
} from '@ant-design/icons'
import {
Chart,
Interval,
Tooltip,
Axis,
Coordinate,
Interaction,
Legend,
} from 'bizcharts'
import { ColumnType } from 'antd/lib/table/interface'
import ReutrnEle from '@/components/ReturnEle'
import styles from './index.less'
const ViewRepository: React.FC<{}> = () => {
const [memberType, setMemberType] = useState(1)
const dataRecord = [
{
key: '1',
inRepository: '牛皮仓-渠道商城-所有渠道',
outRepository: '牛皮仓-直销商城-会员渠道',
productName: '进口头层牛皮荔枝纹/天青色/XXXLL',
inAmount: 10232,
outAmount: 981232,
unit: '吨',
time: '1250-51-02 45:23:99',
},
{
key: '2',
inRepository: '牛皮仓-渠道商城-所有渠道',
outRepository: '牛皮仓-直销商城-会员渠道',
productName: '进口头层牛皮荔枝纹/天青色/XXXLL',
inAmount: 10232,
outAmount: 981232,
unit: '吨',
time: '1250-51-02 45:23:99',
}
];
const columnsRecord: ColumnType<any>[] = [
{
title: 'ID',
dataIndex: 'key',
key: 'key',
},
{
title: '调出/调入仓位',
dataIndex: 'inRepository',
key: 'inRepository',
render: (text: any, record: any) => <>
<p><Tag color="gold">调出仓位 </Tag>{record.outRepository}</p>
<p><Tag color="blue">调入仓位 </Tag>{record.inRepository}</p>
</>
},
{
title: '调出商品',
dataIndex: 'productName',
key: 'productName',
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit',
},
{
title: '调出库存',
key: 'outAmount',
dataIndex: 'outAmount',
render: (text: any, record: any) => <>
<p>调出库存:{record.outAmount}</p>
<p>调出前库存:{record.outAmount}</p>
</>
},
{
title: '调入库存',
key: 'inAmount',
dataIndex: 'inAmount',
render: (text: any, record: any) => <>
<p>调入库存:{record.inAmount}</p>
<p>调入后库存:{record.inAmount}</p>
</>
},
{
title: '调拨时间',
key: 'time',
dataIndex: 'time',
},
];
const dataMember = [
{
key: '1',
name: '渠道名称',
type: '渠道企业会员',
role: '渠道采购商',
class: '青铜会员',
},
{
key: '2',
name: '渠道名称',
type: '渠道企业会员',
role: '渠道采购商',
class: '铁皮会员',
},
]
const columnsMember: ColumnType<any>[] = [
{
title: 'ID',
dataIndex: 'key',
align: 'center',
key: 'key',
},
{
title: '会员名称',
dataIndex: 'name',
align: 'center',
key: 'name',
render: (text:any, record:any) => <span className="commonPickColor">{text}&nbsp;<EyeOutlined /></span>
},
{
title: '会员类型',
dataIndex: 'type',
align: 'center',
key: 'type',
},
{
title: '会员角色',
dataIndex: 'role',
align: 'center',
key: 'role',
},
{
title: '会员等级',
dataIndex: 'class',
align: 'center',
key: 'class',
},
]
const content = <>
<Descriptions colon={true} column={2}>
<Descriptions.Item label="当前库存"><span className={styles.amount}>12000</span></Descriptions.Item>
<Descriptions.Item label="已用库存"><span className={styles.amount}>8000</span></Descriptions.Item>
</Descriptions>
<br />
<br />
<Descriptions colon={true} column={1}>
<Descriptions.Item label="商品名称">进口头层黄牛皮荔枝纹/红色/XL</Descriptions.Item>
<Descriptions.Item label="库存扣减方式">按仓位随机扣减(默认)</Descriptions.Item>
</Descriptions>
</>
const dataChart = [
{ item: '当前库存', count: 12000, percent: 0.6 },
{ item: '已用库存', count: 8000, percent: 0.4 },
]
const colsChart = {
percent: {
formatter: (val:any) => {
val = val * 20000;
return val;
},
},
}
return (
<PageHeaderWrapper
title="进口头层黄牛皮荔枝纹/红色/XL"
onBack={() => history.goBack()}
backIcon={<ReutrnEle logoSrc='https://avatars1.githubusercontent.com/u/8186664?s=460&v=4' />}
>
<Space direction="vertical" style={{width:'100%'}}>
<Row gutter={[26,0]}>
<Col span={12}>
<Card headStyle={{borderBottom:'none'}} title="当前仓位库存(尺)" style={{height:'320px'}}>
<Row>
<Col span={12}>
<Chart height={180} data={dataChart} scale={colsChart} autoFit>
<Coordinate type="theta" radius={0.75} />
<Tooltip showTitle={false} />
<Legend visible={false} />
<Axis visible={false} />
<Interval
position="percent"
adjust="stack"
color={['item',['#669ede', '#f4f5f7']]}
style={{
lineWidth: 1,
stroke: '#fff',
}}
label={['count', {
content: (data: any) => {
return `${data.item}: ${data.percent * 100}%`;
},
}]}
/>
<Interaction type='element-single-selected' />
</Chart>
</Col>
<Col span={12}>{content}</Col>
</Row>
</Card>
</Col>
<Col span={12}>
<Card headStyle={{borderBottom:'none'}} title={<>当前仓位库存(尺)<Tag color="red">广州成品仓</Tag></>} style={{height:'320px'}}>
<Row>
<Col span={12}>
<Chart height={180} data={dataChart} scale={colsChart} autoFit>
<Coordinate type="theta" radius={0.75} />
<Tooltip showTitle={false} />
<Legend visible={false} />
<Axis visible={false} />
<Interval
position="percent"
adjust="stack"
color={['item',['#41cc9e', '#f4f5f7']]}
style={{
lineWidth: 1,
stroke: '#fff',
}}
label={['count', {
content: (data: any) => {
return `${data.item}: ${data.percent * 100}%`;
},
}]}
/>
<Interaction type='element-single-selected' />
</Chart>
</Col>
<Col span={12}>{content}</Col>
</Row>
</Card>
</Col>
</Row>
</Space>
<Space direction="vertical" style={{width:'100%'}}>
<Card headStyle={{borderBottom:'none'}} title="适用商城">
<Descriptions colon={false} column={4}>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
<Descriptions.Item label="LOGO">XXXXX商城</Descriptions.Item>
</Descriptions>
</Card>
</Space>
<Space direction="vertical" style={{width:'100%'}}>
<Card headStyle={{borderBottom:'none'}} title="适用会员">
<Row>
<Col span={3}>
<p>适用会员:</p>
</Col>
<Col span={21}>
<p>{memberType ? <Radio checked>指定会员</Radio> : <Radio checked>所有会员共享(默认)</Radio>}</p>
</Col>
</Row>
{memberType ? <Table dataSource={dataMember} columns={columnsMember} /> : ''}
</Card>
</Space>
<Space direction="vertical" style={{width:'100%'}}>
<Card headStyle={{borderBottom:'none'}} title="仓位库存调拨记录">
<Table columns={columnsRecord} dataSource={dataRecord} />
</Card>
</Space>
</PageHeaderWrapper>
)
}
export default ViewRepository
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment