web, satellite: allow registering business accounts to ask for contact from sales team
Full prefix: web/satellite, satellite/{console, analytics, satellitedb} - checkbox added to register view - business tab - user being saved with new column - add sales contact choice to Segment calls - ui fix added to employee count dropdown Change-Id: Ib976872463b88874ea9714db635d58c79cdbe3a1
This commit is contained in:
parent
2cf10a7bf4
commit
136af8e630
@ -79,14 +79,15 @@ const (
|
|||||||
|
|
||||||
// TrackCreateUserFields contains input data for tracking a create user event.
|
// TrackCreateUserFields contains input data for tracking a create user event.
|
||||||
type TrackCreateUserFields struct {
|
type TrackCreateUserFields struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
AnonymousID string
|
AnonymousID string
|
||||||
FullName string
|
FullName string
|
||||||
Email string
|
Email string
|
||||||
Type UserType
|
Type UserType
|
||||||
EmployeeCount string
|
EmployeeCount string
|
||||||
CompanyName string
|
CompanyName string
|
||||||
JobTitle string
|
JobTitle string
|
||||||
|
HaveSalesContact bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *Service) enqueueMessage(message segment.Message) {
|
func (service *Service) enqueueMessage(message segment.Message) {
|
||||||
@ -122,6 +123,7 @@ func (service *Service) TrackCreateUser(fields TrackCreateUserFields) {
|
|||||||
props.Set("company_size", fields.EmployeeCount)
|
props.Set("company_size", fields.EmployeeCount)
|
||||||
props.Set("company_name", fields.CompanyName)
|
props.Set("company_name", fields.CompanyName)
|
||||||
props.Set("job_title", fields.JobTitle)
|
props.Set("job_title", fields.JobTitle)
|
||||||
|
props.Set("have_sales_contact", fields.HaveSalesContact)
|
||||||
}
|
}
|
||||||
|
|
||||||
service.enqueueMessage(segment.Track{
|
service.enqueueMessage(segment.Track{
|
||||||
|
@ -112,18 +112,19 @@ func (a *Auth) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
var registerData struct {
|
var registerData struct {
|
||||||
FullName string `json:"fullName"`
|
FullName string `json:"fullName"`
|
||||||
ShortName string `json:"shortName"`
|
ShortName string `json:"shortName"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Partner string `json:"partner"`
|
Partner string `json:"partner"`
|
||||||
PartnerID string `json:"partnerId"`
|
PartnerID string `json:"partnerId"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
SecretInput string `json:"secret"`
|
SecretInput string `json:"secret"`
|
||||||
ReferrerUserID string `json:"referrerUserId"`
|
ReferrerUserID string `json:"referrerUserId"`
|
||||||
IsProfessional bool `json:"isProfessional"`
|
IsProfessional bool `json:"isProfessional"`
|
||||||
Position string `json:"position"`
|
Position string `json:"position"`
|
||||||
CompanyName string `json:"companyName"`
|
CompanyName string `json:"companyName"`
|
||||||
EmployeeCount string `json:"employeeCount"`
|
EmployeeCount string `json:"employeeCount"`
|
||||||
|
HaveSalesContact bool `json:"haveSalesContact"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewDecoder(r.Body).Decode(®isterData)
|
err = json.NewDecoder(r.Body).Decode(®isterData)
|
||||||
@ -149,15 +150,16 @@ func (a *Auth) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
user, err := a.service.CreateUser(ctx,
|
user, err := a.service.CreateUser(ctx,
|
||||||
console.CreateUser{
|
console.CreateUser{
|
||||||
FullName: registerData.FullName,
|
FullName: registerData.FullName,
|
||||||
ShortName: registerData.ShortName,
|
ShortName: registerData.ShortName,
|
||||||
Email: registerData.Email,
|
Email: registerData.Email,
|
||||||
PartnerID: registerData.PartnerID,
|
PartnerID: registerData.PartnerID,
|
||||||
Password: registerData.Password,
|
Password: registerData.Password,
|
||||||
IsProfessional: registerData.IsProfessional,
|
IsProfessional: registerData.IsProfessional,
|
||||||
Position: registerData.Position,
|
Position: registerData.Position,
|
||||||
CompanyName: registerData.CompanyName,
|
CompanyName: registerData.CompanyName,
|
||||||
EmployeeCount: registerData.EmployeeCount,
|
EmployeeCount: registerData.EmployeeCount,
|
||||||
|
HaveSalesContact: registerData.HaveSalesContact,
|
||||||
},
|
},
|
||||||
secret,
|
secret,
|
||||||
)
|
)
|
||||||
@ -178,6 +180,7 @@ func (a *Auth) Register(w http.ResponseWriter, r *http.Request) {
|
|||||||
trackCreateUserFields.EmployeeCount = user.EmployeeCount
|
trackCreateUserFields.EmployeeCount = user.EmployeeCount
|
||||||
trackCreateUserFields.CompanyName = user.CompanyName
|
trackCreateUserFields.CompanyName = user.CompanyName
|
||||||
trackCreateUserFields.JobTitle = user.Position
|
trackCreateUserFields.JobTitle = user.Position
|
||||||
|
trackCreateUserFields.HaveSalesContact = user.HaveSalesContact
|
||||||
}
|
}
|
||||||
a.analytics.TrackCreateUser(trackCreateUserFields)
|
a.analytics.TrackCreateUser(trackCreateUserFields)
|
||||||
|
|
||||||
@ -250,16 +253,17 @@ func (a *Auth) GetAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
var user struct {
|
var user struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id"`
|
||||||
FullName string `json:"fullName"`
|
FullName string `json:"fullName"`
|
||||||
ShortName string `json:"shortName"`
|
ShortName string `json:"shortName"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
PartnerID uuid.UUID `json:"partnerId"`
|
PartnerID uuid.UUID `json:"partnerId"`
|
||||||
ProjectLimit int `json:"projectLimit"`
|
ProjectLimit int `json:"projectLimit"`
|
||||||
IsProfessional bool `json:"isProfessional"`
|
IsProfessional bool `json:"isProfessional"`
|
||||||
Position string `json:"position"`
|
Position string `json:"position"`
|
||||||
CompanyName string `json:"companyName"`
|
CompanyName string `json:"companyName"`
|
||||||
EmployeeCount string `json:"employeeCount"`
|
EmployeeCount string `json:"employeeCount"`
|
||||||
|
HaveSalesContact bool `json:"haveSalesContact"`
|
||||||
}
|
}
|
||||||
|
|
||||||
auth, err := console.GetAuth(ctx)
|
auth, err := console.GetAuth(ctx)
|
||||||
@ -278,6 +282,7 @@ func (a *Auth) GetAccount(w http.ResponseWriter, r *http.Request) {
|
|||||||
user.CompanyName = auth.User.CompanyName
|
user.CompanyName = auth.User.CompanyName
|
||||||
user.Position = auth.User.Position
|
user.Position = auth.User.Position
|
||||||
user.EmployeeCount = auth.User.EmployeeCount
|
user.EmployeeCount = auth.User.EmployeeCount
|
||||||
|
user.HaveSalesContact = auth.User.HaveSalesContact
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
err = json.NewEncoder(w).Encode(&user)
|
err = json.NewEncoder(w).Encode(&user)
|
||||||
|
@ -561,17 +561,19 @@ func (s *Service) CreateUser(ctx context.Context, user CreateUser, tokenSecret R
|
|||||||
}
|
}
|
||||||
|
|
||||||
newUser := &User{
|
newUser := &User{
|
||||||
ID: userID,
|
ID: userID,
|
||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
FullName: user.FullName,
|
FullName: user.FullName,
|
||||||
ShortName: user.ShortName,
|
ShortName: user.ShortName,
|
||||||
PasswordHash: hash,
|
PasswordHash: hash,
|
||||||
Status: Inactive,
|
Status: Inactive,
|
||||||
IsProfessional: user.IsProfessional,
|
IsProfessional: user.IsProfessional,
|
||||||
Position: user.Position,
|
Position: user.Position,
|
||||||
CompanyName: user.CompanyName,
|
CompanyName: user.CompanyName,
|
||||||
EmployeeCount: user.EmployeeCount,
|
EmployeeCount: user.EmployeeCount,
|
||||||
|
HaveSalesContact: user.HaveSalesContact,
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.PartnerID != "" {
|
if user.PartnerID != "" {
|
||||||
newUser.PartnerID, err = uuid.FromString(user.PartnerID)
|
newUser.PartnerID, err = uuid.FromString(user.PartnerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -49,16 +49,17 @@ func (user *UserInfo) IsValid() error {
|
|||||||
|
|
||||||
// CreateUser struct holds info for User creation.
|
// CreateUser struct holds info for User creation.
|
||||||
type CreateUser struct {
|
type CreateUser struct {
|
||||||
FullName string `json:"fullName"`
|
FullName string `json:"fullName"`
|
||||||
ShortName string `json:"shortName"`
|
ShortName string `json:"shortName"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
PartnerID string `json:"partnerId"`
|
PartnerID string `json:"partnerId"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
IsProfessional bool `json:"isProfessional"`
|
IsProfessional bool `json:"isProfessional"`
|
||||||
Position string `json:"position"`
|
Position string `json:"position"`
|
||||||
CompanyName string `json:"companyName"`
|
CompanyName string `json:"companyName"`
|
||||||
WorkingOn string `json:"workingOn"`
|
WorkingOn string `json:"workingOn"`
|
||||||
EmployeeCount string `json:"employeeCount"`
|
EmployeeCount string `json:"employeeCount"`
|
||||||
|
HaveSalesContact bool `json:"haveSalesContact"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValid checks CreateUser validity and returns error describing whats wrong.
|
// IsValid checks CreateUser validity and returns error describing whats wrong.
|
||||||
@ -117,4 +118,6 @@ type User struct {
|
|||||||
CompanySize int `json:"companySize"`
|
CompanySize int `json:"companySize"`
|
||||||
WorkingOn string `json:"workingOn"`
|
WorkingOn string `json:"workingOn"`
|
||||||
EmployeeCount string `json:"employeeCount"`
|
EmployeeCount string `json:"employeeCount"`
|
||||||
|
|
||||||
|
HaveSalesContact bool `json:"haveSalesContact"`
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ func (users *users) Insert(ctx context.Context, user *console.User) (_ *console.
|
|||||||
optional.CompanyName = dbx.User_CompanyName(user.CompanyName)
|
optional.CompanyName = dbx.User_CompanyName(user.CompanyName)
|
||||||
optional.WorkingOn = dbx.User_WorkingOn(user.WorkingOn)
|
optional.WorkingOn = dbx.User_WorkingOn(user.WorkingOn)
|
||||||
optional.EmployeeCount = dbx.User_EmployeeCount(user.EmployeeCount)
|
optional.EmployeeCount = dbx.User_EmployeeCount(user.EmployeeCount)
|
||||||
|
optional.HaveSalesContact = dbx.User_HaveSalesContact(user.HaveSalesContact)
|
||||||
}
|
}
|
||||||
|
|
||||||
createdUser, err := users.db.Create_User(ctx,
|
createdUser, err := users.db.Create_User(ctx,
|
||||||
@ -150,14 +151,15 @@ func userFromDBX(ctx context.Context, user *dbx.User) (_ *console.User, err erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
result := console.User{
|
result := console.User{
|
||||||
ID: id,
|
ID: id,
|
||||||
FullName: user.FullName,
|
FullName: user.FullName,
|
||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
PasswordHash: user.PasswordHash,
|
PasswordHash: user.PasswordHash,
|
||||||
Status: console.UserStatus(user.Status),
|
Status: console.UserStatus(user.Status),
|
||||||
CreatedAt: user.CreatedAt,
|
CreatedAt: user.CreatedAt,
|
||||||
ProjectLimit: user.ProjectLimit,
|
ProjectLimit: user.ProjectLimit,
|
||||||
IsProfessional: user.IsProfessional,
|
IsProfessional: user.IsProfessional,
|
||||||
|
HaveSalesContact: user.HaveSalesContact,
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.PartnerId != nil {
|
if user.PartnerId != nil {
|
||||||
|
@ -205,7 +205,7 @@ export class AuthHttpApi {
|
|||||||
* @returns id of created user
|
* @returns id of created user
|
||||||
* @throws Error
|
* @throws Error
|
||||||
*/
|
*/
|
||||||
public async register(user: {fullName: string; shortName: string; email: string; partner: string; partnerId: string; password: string; isProfessional: boolean; position: string; companyName: string; employeeCount: string}, secret: string): Promise<string> {
|
public async register(user: {fullName: string; shortName: string; email: string; partner: string; partnerId: string; password: string; isProfessional: boolean; position: string; companyName: string; employeeCount: string; haveSalesContact: boolean }, secret: string): Promise<string> {
|
||||||
const path = `${this.ROOT_PATH}/register`;
|
const path = `${this.ROOT_PATH}/register`;
|
||||||
const body = {
|
const body = {
|
||||||
secret: secret,
|
secret: secret,
|
||||||
@ -219,8 +219,8 @@ export class AuthHttpApi {
|
|||||||
position: user.position,
|
position: user.position,
|
||||||
companyName: user.companyName,
|
companyName: user.companyName,
|
||||||
employeeCount: user.employeeCount,
|
employeeCount: user.employeeCount,
|
||||||
|
haveSalesContact: user.haveSalesContact,
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await this.http.post(path, JSON.stringify(body));
|
const response = await this.http.post(path, JSON.stringify(body));
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
switch (response.status) {
|
switch (response.status) {
|
||||||
|
@ -252,8 +252,8 @@ export default class HeaderlessInput extends Vue {
|
|||||||
&__options-wrapper {
|
&__options-wrapper {
|
||||||
border: 1px solid rgba(56, 75, 101, 0.4);
|
border: 1px solid rgba(56, 75, 101, 0.4);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: calc(100% - 4px);
|
width: calc(100% - 5px);
|
||||||
top: 86px;
|
top: 70px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
z-index: 21;
|
z-index: 21;
|
||||||
|
@ -38,6 +38,7 @@ export class User {
|
|||||||
public position: string = '',
|
public position: string = '',
|
||||||
public companyName: string = '',
|
public companyName: string = '',
|
||||||
public employeeCount: string = '',
|
public employeeCount: string = '',
|
||||||
|
public haveSalesContact: boolean = false,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public getFullName(): string {
|
public getFullName(): string {
|
||||||
|
@ -65,6 +65,7 @@ export default class RegisterArea extends Vue {
|
|||||||
private isTermsAcceptedError: boolean = false;
|
private isTermsAcceptedError: boolean = false;
|
||||||
private isLoading: boolean = false;
|
private isLoading: boolean = false;
|
||||||
private isProfessional: boolean = false;
|
private isProfessional: boolean = false;
|
||||||
|
private haveSalesContact: boolean = false;
|
||||||
|
|
||||||
private readonly auth: AuthHttpApi = new AuthHttpApi();
|
private readonly auth: AuthHttpApi = new AuthHttpApi();
|
||||||
|
|
||||||
@ -328,6 +329,8 @@ export default class RegisterArea extends Vue {
|
|||||||
*/
|
*/
|
||||||
private async createUser(): Promise<void> {
|
private async createUser(): Promise<void> {
|
||||||
this.user.isProfessional = this.isProfessional;
|
this.user.isProfessional = this.isProfessional;
|
||||||
|
this.user.haveSalesContact = this.haveSalesContact;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.userId = await this.auth.register(this.user, this.secret);
|
this.userId = await this.auth.register(this.user, this.secret);
|
||||||
LocalData.setUserId(this.userId);
|
LocalData.setUserId(this.userId);
|
||||||
|
@ -137,17 +137,28 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<AddCouponCodeInput v-if="couponCodeUIEnabled" />
|
<AddCouponCodeInput v-if="couponCodeUIEnabled" />
|
||||||
<div class="register-area__content-area__container__terms-area">
|
<div v-if="isProfessional" class="register-area__content-area__container__checkbox-area">
|
||||||
|
<label class="container">
|
||||||
|
<input type="checkbox" v-model="haveSalesContact">
|
||||||
|
<span class="checkmark"></span>
|
||||||
|
</label>
|
||||||
|
<label class="register-area__content-area__container__checkbox-area__msg-box" for="terms">
|
||||||
|
<p class="register-area__content-area__container__checkbox-area__msg-box__msg">
|
||||||
|
Please have the Sales Team contact me
|
||||||
|
</p>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="register-area__content-area__container__checkbox-area">
|
||||||
<label class="container">
|
<label class="container">
|
||||||
<input id="terms" type="checkbox" v-model="isTermsAccepted">
|
<input id="terms" type="checkbox" v-model="isTermsAccepted">
|
||||||
<span class="checkmark" :class="{'error': isTermsAcceptedError}"></span>
|
<span class="checkmark" :class="{'error': isTermsAcceptedError}"></span>
|
||||||
</label>
|
</label>
|
||||||
<label class="register-area__content-area__container__terms-area__msg-box" for="terms">
|
<label class="register-area__content-area__container__checkbox-area__msg-box" for="terms">
|
||||||
<p class="register-area__content-area__container__terms-area__msg-box__msg">
|
<p class="register-area__content-area__container__checkbox-area__msg-box__msg">
|
||||||
I agree to the
|
I agree to the
|
||||||
<a class="register-area__content-area__container__terms-area__msg-box__msg__link" href="https://storj.io/terms-of-service/" target="_blank" rel="noopener">Terms of Service</a>
|
<a class="register-area__content-area__container__checkbox-area__msg-box__msg__link" href="https://storj.io/terms-of-service/" target="_blank" rel="noopener">Terms of Service</a>
|
||||||
and
|
and
|
||||||
<a class="register-area__content-area__container__terms-area__msg-box__msg__link" href="https://storj.io/privacy-policy/" target="_blank" rel="noopener">Privacy Policy</a>
|
<a class="register-area__content-area__container__checkbox-area__msg-box__msg__link" href="https://storj.io/privacy-policy/" target="_blank" rel="noopener">Privacy Policy</a>
|
||||||
</p>
|
</p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -118,6 +118,8 @@ h1 {
|
|||||||
border-top-right-radius: 20px;
|
border-top-right-radius: 20px;
|
||||||
border-bottom-right-radius: 20px;
|
border-bottom-right-radius: 20px;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
|
position: relative;
|
||||||
|
right: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__personal,
|
&__personal,
|
||||||
@ -145,7 +147,7 @@ h1 {
|
|||||||
padding: 60px 80px;
|
padding: 60px 80px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
min-height: 675px;
|
min-height: 655px;
|
||||||
|
|
||||||
&__title-area {
|
&__title-area {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -169,7 +171,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__terms-area {
|
&__checkbox-area {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -181,6 +183,8 @@ h1 {
|
|||||||
color: #354049;
|
color: #354049;
|
||||||
|
|
||||||
&__msg {
|
&__msg {
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
|
||||||
&__link {
|
&__link {
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
@ -219,7 +223,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__container.professional-container {
|
&__container.professional-container {
|
||||||
min-height: 901px;
|
min-height: 991px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__footer {
|
&__footer {
|
||||||
@ -377,6 +381,16 @@ h1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 414px) {
|
||||||
|
|
||||||
|
.register-area {
|
||||||
|
|
||||||
|
&__logo-wrapper {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 414px) {
|
@media screen and (max-width: 414px) {
|
||||||
|
|
||||||
.register-area {
|
.register-area {
|
||||||
|
Loading…
Reference in New Issue
Block a user