Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
quasar-web-base
Project
Project
Details
Activity
Releases
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
Nguyễn Hải Sơn
quasar-web-base
Commits
49a74b25
Commit
49a74b25
authored
May 10, 2021
by
Võ Quang Thành Đạt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
create customer page
parent
db1fd0e0
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
393 additions
and
270 deletions
+393
-270
configurations.example.ts
src/assets/configurations.example.ts
+4
-0
type.ts
src/assets/type.ts
+25
-0
AddNewCustomerDialog.ts
.../customer/add-new-customer-dialog/AddNewCustomerDialog.ts
+112
-53
index.vue
src/components/customer/add-new-customer-dialog/index.vue
+49
-59
index.ts
src/i18n/vi/index.ts
+8
-3
customer.ts
src/pages/khach-hang/customer.ts
+161
-122
index.vue
src/pages/khach-hang/index.vue
+31
-31
index.vue
src/pages/nghe-sy/index.vue
+1
-1
AddArtist.ts
src/pages/them-nghe-sy/AddArtist.ts
+2
-1
No files found.
src/assets/configurations.example.ts
View file @
49a74b25
...
...
@@ -51,4 +51,8 @@ export enum API_PATHS {
getDetailUnit
=
'artistOwner/detail'
,
updateUnit
=
'artistOwner/update'
,
addArtist
=
'artist/add'
,
listCustomers
=
'customer'
,
listCustomerLevel
=
'customerLevel'
,
addCustomer
=
'customer/add'
,
deleteCustomer
=
'customer/delete'
,
}
src/assets/type.ts
View file @
49a74b25
...
...
@@ -216,3 +216,28 @@ export type DetailUnit = {
fields
:
Array
<
FieldType
>
;
contracts
:
Array
<
Contract
>
;
};
export
type
CustomerType
=
{
id
:
number
;
code
:
string
;
userName
:
string
;
fullName
:
string
;
companyName
:
string
;
taxCode
:
string
;
email
:
string
;
status
:
number
;
phone
:
string
;
password
:
string
;
address
:
string
;
type
:
string
;
representative
:
string
;
position
:
string
;
level
:
string
;
};
export
type
CustomerLevelType
=
{
id
:
number
;
name
:
string
;
description
:
string
;
level
:
number
;
status
:
number
;
};
src/components/customer/add-new-customer-dialog/AddNewCustomerDialog.ts
View file @
49a74b25
import
{
defineComponent
}
from
'vue'
;
import
{
defineComponent
,
PropType
,
Ref
,
ref
,
watch
}
from
'vue'
;
import
{
i18n
}
from
'src/boot/i18n'
;
import
{
isEmail
}
from
'../../../boot/functions'
;
import
{
isMobilePhone
}
from
'../../../boot/functions'
;
import
{
CustomerLevelType
}
from
'src/assets/type'
;
export
default
defineComponent
({
props
:
{
...
...
@@ -9,27 +10,84 @@ export default defineComponent({
type
:
Boolean
,
required
:
true
,
},
ratingsOptions
:
{
type
:
Array
,
required
:
true
},
businessTypeOptions
:
{
type
:
Array
,
required
:
true
},
userName
:
{
type
:
String
,
required
:
true
},
customerName
:
{
type
:
String
,
required
:
true
},
businessName
:
{
type
:
String
,
required
:
true
},
taxCode
:
{
type
:
Number
,
required
:
true
},
email
:
{
type
:
String
,
required
:
true
},
ratings
:
{
type
:
String
,
required
:
true
},
address
:
{
type
:
String
,
required
:
true
},
businessType
:
{
type
:
String
,
required
:
true
},
representative
:
{
type
:
String
,
required
:
true
},
position
:
{
type
:
String
,
required
:
true
},
phone
:
{
type
:
String
,
required
:
true
},
status
:
{
type
:
Boolean
,
required
:
true
},
levelOptions
:
{
type
:
Array
as
PropType
<
CustomerLevelType
[]
>
,
required
:
true
,
},
},
setup
()
{
setup
(
props
,
context
)
{
watch
(
()
=>
props
.
showDialog
,
(
value
)
=>
{
if
(
value
)
{
void
resetData
();
}
}
);
const
code
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
userName
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
fullName
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
companyName
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
taxCode
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
email
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
status
:
Ref
<
number
|
null
>
=
ref
(
2
);
const
phone
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
password
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
address
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
type
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
representative
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
position
:
Ref
<
string
|
null
>
=
ref
(
null
);
const
level
:
Ref
<
CustomerLevelType
|
null
>
=
ref
(
null
);
const
confirmAddCustomer
=
()
=>
{
context
.
emit
(
'addNewCustomer'
,
{
code
:
code
.
value
,
userName
:
userName
.
value
,
fullName
:
fullName
.
value
,
companyName
:
companyName
.
value
,
taxCode
:
taxCode
.
value
,
email
:
email
.
value
,
status
:
status
.
value
,
phone
:
phone
.
value
,
password
:
password
.
value
,
address
:
address
.
value
,
type
:
type
.
value
,
representative
:
representative
.
value
,
position
:
position
.
value
,
level
:
level
.
value
,
});
};
const
resetData
=
()
=>
{
code
.
value
=
null
;
userName
.
value
=
null
;
fullName
.
value
=
null
;
companyName
.
value
=
null
;
taxCode
.
value
=
null
;
email
.
value
=
null
;
status
.
value
=
2
;
phone
.
value
=
null
;
password
.
value
=
null
;
address
.
value
=
null
;
type
.
value
=
null
;
representative
.
value
=
null
;
position
.
value
=
null
;
level
.
value
=
null
;
};
const
userNameRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requireUserName'
),
];
const
passwordRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requirePassword'
),
];
const
codeRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requireCode'
),
];
const
customerNameRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
...
...
@@ -41,18 +99,18 @@ export default defineComponent({
i18n
.
global
.
t
(
'customer.validateMessages.requireBusinessName'
),
];
const
taxCodeRules
=
[
(
val
?:
number
)
=>
val
!==
undefined
||
i18n
.
global
.
t
(
'customer.validateMessages.requireTaxCode'
),
];
(
val
?:
number
)
=>
val
!==
undefined
||
i18n
.
global
.
t
(
'customer.validateMessages.requireTaxCode'
),
];
const
phoneRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requirePhone'
),
(
val
:
string
)
=>
isMobilePhone
(
val
)
||
i18n
.
global
.
t
(
'customer.validateMessages.isPhone'
),
];
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requirePhone'
),
(
val
:
string
)
=>
isMobilePhone
(
val
)
||
i18n
.
global
.
t
(
'customer.validateMessages.isPhone'
),
];
const
emailRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
...
...
@@ -76,19 +134,21 @@ export default defineComponent({
i18n
.
global
.
t
(
'customer.validateMessages.requireRatings'
),
];
const
representativeRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requireRepresentative'
),
];
const
positionRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requiredPosition'
),
];
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requireRepresentative'
),
];
const
positionRules
=
[
(
val
?:
string
)
=>
(
val
&&
val
.
trim
().
length
)
||
i18n
.
global
.
t
(
'customer.validateMessages.requiredPosition'
),
];
return
{
userNameRules
,
customerNameRules
,
businessNameRules
,
passwordRules
,
codeRules
,
taxCodeRules
,
emailRules
,
ratingsRules
,
...
...
@@ -97,23 +157,22 @@ export default defineComponent({
representativeRules
,
positionRules
,
phoneRules
,
userName
,
fullName
,
companyName
,
taxCode
,
email
,
status
,
phone
,
password
,
address
,
type
,
representative
,
position
,
level
,
code
,
confirmAddCustomer
,
};
},
emits
:
[
'update:showDialog'
,
'click:CloseBtn'
,
'update:userName'
,
'update:customerName'
,
'update:businessName'
,
'update:taxCode'
,
'update:email'
,
'update:ratings'
,
'update:address'
,
'update:businessType'
,
'update:representative'
,
'update:position'
,
'update:phone'
,
'update:status'
,
'addNewCustomer'
,
],
emits
:
[
'update:showDialog'
,
'click:CloseBtn'
,
'addNewCustomer'
],
});
src/components/customer/add-new-customer-dialog/index.vue
View file @
49a74b25
...
...
@@ -5,7 +5,7 @@
@
update:model-value=
"$emit('update:showDialog', $event)"
>
<q-card
style=
"min-width: 900px"
bordered
>
<q-form
greedy
@
submit
.
prevent=
"
$emit('addNewCustomer')
"
>
<q-form
greedy
@
submit
.
prevent=
"
confirmAddCustomer
"
>
<q-card-section>
<q-item>
<q-item-section>
...
...
@@ -21,94 +21,82 @@
<div
class=
"row q-col-gutter-sm"
>
<div
class=
"col-6"
>
<q-input
:model-value=
"userName"
@
update:model-value=
"$emit('update:userName', $event)"
v-model=
"userName"
:label=
"$t('customer.dialogLabel.fieldLabels.userName')"
:rules=
"userNameRules"
hide-bottom-space
type=
"text"
class=
"q-my-sm"
outlined
clearable
></q-input>
<q-input
:model-value=
"customerName"
@
update:model-value=
"$emit('update:customerName', $event)"
v-model=
"password"
:label=
"$t('customer.dialogLabel.fieldLabels.password')"
:rules=
"passwordRules"
hide-bottom-space
type=
"password"
class=
"q-my-sm"
outlined
></q-input>
<q-input
v-model=
"code"
:label=
"$t('customer.dialogLabel.fieldLabels.code')"
:rules=
"codeRules"
hide-bottom-space
type=
"text"
class=
"q-my-sm"
outlined
></q-input>
<q-input
v-model=
"fullName"
:label=
"$t('customer.dialogLabel.fieldLabels.customerName')"
type=
"text"
class=
"q-my-sm"
outlined
:rules=
"customerNameRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value=
"businessName"
@
update:model-value=
"$emit('update:businessName', $event)"
v-model=
"companyName"
:label=
"$t('customer.dialogLabel.fieldLabels.businessName')"
type=
"text"
class=
"q-my-sm"
outlined
:rules=
"businessNameRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value=
"taxCode"
@
update:model-value=
"$emit('update:taxCode', $event)"
v-model=
"taxCode"
:label=
"$t('customer.dialogLabel.fieldLabels.taxCode')"
type=
"number"
class=
"q-my-sm"
outlined
:rules=
"taxCodeRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value=
"email"
@
update:model-value=
"$emit('update:email', $event)"
:label=
"$t('customer.dialogLabel.fieldLabels.email')"
v-model=
"address"
:label=
"$t('customer.dialogLabel.fieldLabels.address')"
type=
"text"
class=
"q-my-sm"
:rules=
"addressRules"
outlined
:rules=
"emailRules"
hide-bottom-space
clearable
></q-input>
<q-select
:model-value=
"ratings"
@
update:model-value=
"$emit('update:ratings', $event)"
:label=
"$t('customer.dialogLabel.fieldLabels.ratings')"
:options=
"ratingsOptions"
:rules=
"ratingsRules"
emit-value
map-options
option-value=
"id"
option-label=
"text"
type=
"text"
class=
"q-my-sm"
outlined
hide-bottom-space
clearable
></q-select>
</div>
<div
class=
"col-6"
>
<q-input
:model-value=
"address"
@
update:model-value=
"$emit('update:address', $event)"
:label=
"$t('customer.dialogLabel.fieldLabels.address')"
v-model=
"email"
:label=
"$t('customer.dialogLabel.fieldLabels.email')"
type=
"text"
class=
"q-my-sm"
:rules=
"addressRules"
outlined
:rules=
"emailRules"
hide-bottom-space
clearable
></q-input>
<q-select
:model-value=
"businessType"
@
update:model-value=
"$emit('update:businessType', $event)"
<q-input
v-model=
"type"
:label=
"$t('customer.dialogLabel.fieldLabels.businessType')"
:options=
"businessTypeOptions"
:rules=
"businessTypeRules"
emit-value
map-options
...
...
@@ -117,52 +105,54 @@
class=
"q-my-sm"
outlined
hide-bottom-space
></q-input>
<q-select
v-model=
"level"
:label=
"$t('customer.dialogLabel.fieldLabels.ratings')"
:options=
"levelOptions"
:rules=
"ratingsRules"
map-options
option-value=
"id"
option-label=
"name"
type=
"text"
class=
"q-my-sm"
outlined
clearable
hide-bottom-space
></q-select>
<q-input
:model-value=
"representative"
emit-value
@
update:model-value=
"$emit('update:representative', $event)"
v-model=
"representative"
:label=
"$t('customer.dialogLabel.fieldLabels.representative')"
class=
"q-my-sm"
type=
"text"
outlined
:rules=
"representativeRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value=
"position"
emit-value
@
update:model-value=
"$emit('update:position', $event)"
v-model=
"position"
:label=
"$t('customer.dialogLabel.fieldLabels.position')"
class=
"q-my-sm"
type=
"text"
outlined
:rules=
"positionRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value=
"phone"
emit-value
@
update:model-value=
"$emit('update:phone', $event)"
v-model=
"phone"
:label=
"$t('customer.dialogLabel.fieldLabels.phone')"
class=
"q-my-sm"
type=
"number"
:rules=
"phoneRules"
outlined
hide-bottom-space
clearable
></q-input>
<div
style=
"padding-top: 13px; padding-left: 12px"
>
<span
class=
"text-body1"
>
{{
$t
(
'customer.dialogLabel.fieldLabels.status'
)
}}
</span
><q-toggle
:model-value=
"status"
@
update:model-value=
"$emit('update:status', $event)"
/>
><q-toggle
:true-value=
"1"
:false-value=
"2"
v-model=
"status"
/>
</div>
</div>
</div>
...
...
src/i18n/vi/index.ts
View file @
49a74b25
...
...
@@ -317,6 +317,8 @@ export default {
fieldLabels
:
{
userName
:
'Tên đăng nhập *'
,
customerName
:
'Họ tên *'
,
password
:
'Mật khẩu *'
,
code
:
'Mã khách hàng *'
,
businessName
:
'Tên doanh nghiệp *'
,
taxCode
:
'Mã số thuế *'
,
email
:
'Email *'
,
...
...
@@ -332,6 +334,7 @@ export default {
toolTipMessage
:
{
updateCustomerInfo
:
'Cập nhật'
,
informationCustomer
:
'Thông tin'
,
deleteCustomer
:
'Xoá'
,
},
crudActions
:
{
save
:
'Lưu'
,
...
...
@@ -339,6 +342,8 @@ export default {
},
validateMessages
:
{
requireUserName
:
'Vui lòng nhập Tên đăng nhập'
,
requirePassword
:
'Vui lòng nhập Mật khẩu'
,
requireCode
:
'Vui lòng nhập Mã khách hàng'
,
requireCustomerName
:
'Vui lòng nhập Họ tên'
,
requireBusinessName
:
'Vui lòng nhập Tên Doanh nghiệp'
,
requireTaxCode
:
'Vui lòng nhập Mã số thuế'
,
...
...
@@ -355,13 +360,13 @@ export default {
confirmActionsTitle
:
{
confirmDeleteUserTitle
:
'Xác nhận'
,
confirmDeleteUserCancelBtnLabel
:
'Huỷ'
,
confirmDeleteUserContent
:
'Bạn có chắc muốn xoá
tài khoản
'
,
confirmDeleteUserContent
:
'Bạn có chắc muốn xoá
khách hàng này không ?
'
,
confirmResetPasswordContent
:
'Bạn có muốn reset mật khẩu của người dùng này không'
,
'Bạn có muốn reset mật khẩu của người dùng này không
?
'
,
},
actionMessages
:
{
addNewUserAccess
:
'Thêm tài khoản thành công'
,
deleteUserAccess
:
'Xoá
tài khoản
thành công'
,
deleteUserAccess
:
'Xoá
khách hàng
thành công'
,
updateUserAccess
:
'Cập nhật thông tin tài khoản thành công'
,
resetPasswordAccess
:
'Reset mật khẩu thành công'
,
},
...
...
src/pages/khach-hang/customer.ts
View file @
49a74b25
This diff is collapsed.
Click to expand it.
src/pages/khach-hang/index.vue
View file @
49a74b25
...
...
@@ -7,7 +7,7 @@
<q-space></q-space>
<div
class=
"col-2"
>
<q-input
v-model=
"
businessName
"
v-model=
"
companyNameSelected
"
dense
outlined
:label=
"$t('customer.tableColumnsCustomer.businessName')"
...
...
@@ -16,7 +16,7 @@
</div>
<div
class=
"col-2"
>
<q-input
v-model=
"taxCode"
v-model=
"taxCode
Selected
"
dense
outlined
:label=
"$t('customer.tableColumnsCustomer.taxCode')"
...
...
@@ -25,9 +25,9 @@
</div>
<div
class=
"col-2"
dense
outlined
>
<q-select
v-model=
"
ratings
"
:options=
"
ratings
Options"
option-label=
"
text
"
v-model=
"
levelSelected
"
:options=
"
level
Options"
option-label=
"
name
"
option-value=
"id"
dense
outlined
...
...
@@ -41,7 +41,7 @@
no-caps
:label=
"$t('crudActions.search')"
style=
"width: 100px"
@
click=
"
filterListCustomer
"
@
click=
"
getListCustomers
"
>
</q-btn>
</div>
...
...
@@ -65,13 +65,15 @@
separator=
"cell"
hide-pagination
>
<template
v-slot:body-cell-stt=
"item"
>
<q-td
style=
"padding: 0; height: 100%"
>
<div
align=
"center"
>
{{
item
.
rowIndex
+
1
}}
</div>
</q-td>
</
template
>
<
template
v-slot:body-cell-action=
"rowData"
>
<q-td
style=
"padding: 0"
class=
"flex flex-center"
>
<q-btn
flat
round
color=
"primary"
icon=
"mdi-information-outline"
>
<q-tooltip
:offset=
"[20, 10]"
>
{{
$t
(
'customer.toolTipMessage.informationCustomer'
)
}}
</q-tooltip>
</q-btn>
<q-btn
flat
round
...
...
@@ -83,18 +85,29 @@
$t
(
'customer.toolTipMessage.updateCustomerInfo'
)
}}
</q-tooltip>
</q-btn>
<q-btn
flat
round
color=
"primary"
icon=
"mdi-delete-outline"
@
click=
"confirmDeleteCustomer(rowData.row.id)"
>
<q-tooltip
:offset=
"[20, 10]"
>
{{
$t
(
'customer.toolTipMessage.deleteCustomer'
)
}}
</q-tooltip>
</q-btn>
</q-td>
</
template
>
<
template
v-slot:body-cell-status=
"rowData"
>
<q-td>
<div
align=
"center"
>
<q-chip
:color=
"rowData.value ? 'positive' : 'orange'"
:color=
"rowData.value
=== 1
? 'positive' : 'orange'"
text-color=
"white"
size=
"sm"
>
{{
rowData
.
value
rowData
.
value
===
1
?
$t
(
'customer.statusLabel.active'
)
:
$t
(
'customer.statusLabel.inactive'
)
}}
...
...
@@ -109,30 +122,17 @@
v-model:pageSize=
"pageSize"
:totalPage=
"totalPage"
@
update:pageSize=
"changePageSize"
@
update:currentPage=
"getListCustomer"
@
update:currentPage=
"getListCustomer
s
"
/>
<AddNewCustomerDialogComponent
v-model:show-dialog=
"showDialog"
v-model:user-name=
"userName"
v-model:customer-name=
"customerName"
v-model:business-name=
"businessName"
v-model:tax-code=
"taxCode"
v-model:email=
"email"
v-model:ratings=
"ratings"
v-model:address=
"address"
v-model:business-type=
"businessType"
v-model:representative=
"representative"
v-model:position=
"position"
v-model:phone=
"phone"
v-model:status=
"status"
:ratings-options=
"ratingsOptions"
:business-type-options=
"businessTypeOptions"
:level-options=
"levelOptions"
@
click:CloseBtn=
"showDialog = false"
@
addNewCustomer=
"add
New
Customer"
@
addNewCustomer=
"addCustomer"
></AddNewCustomerDialogComponent>
<UpdateNewCustomerDialogComponent
<
!-- <
UpdateNewCustomerDialogComponent
v-model:show-dialog-update="showDialogUpdate"
v-model:user-name="userName"
v-model:customer-name="customerName"
...
...
@@ -150,7 +150,7 @@
:business-type-options="businessTypeOptions"
@click:CloseBtn="showDialogUpdate = false"
@updateNewCustomer="updateCustomer"
></UpdateNewCustomerDialogComponent>
></UpdateNewCustomerDialogComponent>
-->
</div>
</div>
</div>
...
...
src/pages/nghe-sy/index.vue
View file @
49a74b25
...
...
@@ -104,7 +104,7 @@
flat
round
color=
"primary"
icon=
"mdi-delete"
icon=
"mdi-delete
-outline
"
@
click=
"confirmDeleteArtist(item.row.id)"
>
<q-tooltip
:offset=
"[20, 10]"
>
{{
...
...
src/pages/them-nghe-sy/AddArtist.ts
View file @
49a74b25
...
...
@@ -368,7 +368,8 @@ export default defineComponent({
avatar
:
avatar
.
value
,
artistCode
:
artistCode
.
value
,
artistName
:
artistName
.
value
,
birthday
:
birthday
.
value
,
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
birthday
:
birthday
.
value
+
'00:00:00'
,
sex
:
sex
.
value
,
address
:
address
.
value
,
phoneNumber
:
phoneNumber
.
value
,
...
...
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