mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 09:14:27 +08:00
improve user registration page
This commit is contained in:
@@ -233,9 +233,8 @@ func (a *AuthorizationsApi) TwoFactorAuthorizeByRecoveryCodeHandler(c *core.Cont
|
|||||||
|
|
||||||
func (a *AuthorizationsApi) getAuthResponse(token string, need2FA bool, user *models.User) *models.AuthResponse {
|
func (a *AuthorizationsApi) getAuthResponse(token string, need2FA bool, user *models.User) *models.AuthResponse {
|
||||||
return &models.AuthResponse{
|
return &models.AuthResponse{
|
||||||
Token: token,
|
Token: token,
|
||||||
Need2FA: need2FA,
|
Need2FA: need2FA,
|
||||||
NeedVerifyEmail: false,
|
User: user.ToUserBasicInfo(),
|
||||||
User: user.ToUserBasicInfo(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package api
|
|||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
@@ -134,7 +136,7 @@ func (a *TransactionCategoriesApi) CategoryCreateHandler(c *core.Context) (inter
|
|||||||
// CategoryCreateBatchHandler saves some new transaction category by request parameters for current user
|
// CategoryCreateBatchHandler saves some new transaction category by request parameters for current user
|
||||||
func (a *TransactionCategoriesApi) CategoryCreateBatchHandler(c *core.Context) (interface{}, *errs.Error) {
|
func (a *TransactionCategoriesApi) CategoryCreateBatchHandler(c *core.Context) (interface{}, *errs.Error) {
|
||||||
var categoryCreateBatchReq models.TransactionCategoryCreateBatchRequest
|
var categoryCreateBatchReq models.TransactionCategoryCreateBatchRequest
|
||||||
err := c.ShouldBindJSON(&categoryCreateBatchReq)
|
err := c.ShouldBindBodyWith(&categoryCreateBatchReq, binding.JSON)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WarnfWithRequestId(c, "[transaction_categories.CategoryCreateBatchHandler] parse request failed, because %s", err.Error())
|
log.WarnfWithRequestId(c, "[transaction_categories.CategoryCreateBatchHandler] parse request failed, because %s", err.Error())
|
||||||
@@ -143,53 +145,12 @@ func (a *TransactionCategoriesApi) CategoryCreateBatchHandler(c *core.Context) (
|
|||||||
|
|
||||||
uid := c.GetCurrentUid()
|
uid := c.GetCurrentUid()
|
||||||
|
|
||||||
categoryTypeMaxOrderMap := make(map[models.TransactionCategoryType]int32)
|
categories, err := a.createBatchCategories(c, uid, &categoryCreateBatchReq)
|
||||||
categoriesMap := make(map[*models.TransactionCategory][]*models.TransactionCategory)
|
|
||||||
categoriesMap[nil] = make([]*models.TransactionCategory, len(categoryCreateBatchReq.Categories))
|
|
||||||
totalCount := 0
|
|
||||||
|
|
||||||
for i := 0; i < len(categoryCreateBatchReq.Categories); i++ {
|
|
||||||
categoryCreateReq := categoryCreateBatchReq.Categories[i]
|
|
||||||
var maxOrderId, exists = categoryTypeMaxOrderMap[categoryCreateReq.Type]
|
|
||||||
|
|
||||||
if !exists {
|
|
||||||
maxOrderId, err = a.categories.GetMaxDisplayOrder(c, uid, categoryCreateReq.Type)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.ErrorfWithRequestId(c, "[transaction_categories.CategoryCreateBatchHandler] failed to get max display order for user \"uid:%d\", because %s", uid, err.Error())
|
|
||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
category := a.createNewCategoryModel(uid, &models.TransactionCategoryCreateRequest{
|
|
||||||
Name: categoryCreateReq.Name,
|
|
||||||
Type: categoryCreateReq.Type,
|
|
||||||
Icon: categoryCreateReq.Icon,
|
|
||||||
Color: categoryCreateReq.Color,
|
|
||||||
}, maxOrderId+1)
|
|
||||||
|
|
||||||
categoriesMap[category] = make([]*models.TransactionCategory, len(categoryCreateReq.SubCategories))
|
|
||||||
|
|
||||||
for j := int32(0); j < int32(len(categoryCreateReq.SubCategories)); j++ {
|
|
||||||
subCategory := a.createNewCategoryModel(uid, categoryCreateReq.SubCategories[j], j+1)
|
|
||||||
categoriesMap[category][j] = subCategory
|
|
||||||
totalCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
categoriesMap[nil][i] = category
|
|
||||||
categoryTypeMaxOrderMap[categoryCreateReq.Type] = maxOrderId + 1
|
|
||||||
totalCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
categories, err := a.categories.CreateCategories(c, uid, categoriesMap)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorfWithRequestId(c, "[transaction_categories.CategoryCreateBatchHandler] failed to create categories for user \"uid:%d\", because %s", uid, err.Error())
|
|
||||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.InfofWithRequestId(c, "[transaction_categories.CategoryCreateBatchHandler] user \"uid:%d\" has created categoroies successfully", uid)
|
|
||||||
|
|
||||||
return a.getTransactionCategoryListByTypeResponse(categories, 0)
|
return a.getTransactionCategoryListByTypeResponse(categories, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,6 +286,58 @@ func (a *TransactionCategoriesApi) CategoryDeleteHandler(c *core.Context) (inter
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *TransactionCategoriesApi) createBatchCategories(c *core.Context, uid int64, categoryCreateBatchReq *models.TransactionCategoryCreateBatchRequest) ([]*models.TransactionCategory, error) {
|
||||||
|
var err error
|
||||||
|
categoryTypeMaxOrderMap := make(map[models.TransactionCategoryType]int32)
|
||||||
|
categoriesMap := make(map[*models.TransactionCategory][]*models.TransactionCategory)
|
||||||
|
categoriesMap[nil] = make([]*models.TransactionCategory, len(categoryCreateBatchReq.Categories))
|
||||||
|
totalCount := 0
|
||||||
|
|
||||||
|
for i := 0; i < len(categoryCreateBatchReq.Categories); i++ {
|
||||||
|
categoryCreateReq := categoryCreateBatchReq.Categories[i]
|
||||||
|
var maxOrderId, exists = categoryTypeMaxOrderMap[categoryCreateReq.Type]
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
maxOrderId, err = a.categories.GetMaxDisplayOrder(c, uid, categoryCreateReq.Type)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.ErrorfWithRequestId(c, "[transaction_categories.CategoryCreateBatchHandler] failed to get max display order for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
category := a.createNewCategoryModel(uid, &models.TransactionCategoryCreateRequest{
|
||||||
|
Name: categoryCreateReq.Name,
|
||||||
|
Type: categoryCreateReq.Type,
|
||||||
|
Icon: categoryCreateReq.Icon,
|
||||||
|
Color: categoryCreateReq.Color,
|
||||||
|
}, maxOrderId+1)
|
||||||
|
|
||||||
|
categoriesMap[category] = make([]*models.TransactionCategory, len(categoryCreateReq.SubCategories))
|
||||||
|
|
||||||
|
for j := int32(0); j < int32(len(categoryCreateReq.SubCategories)); j++ {
|
||||||
|
subCategory := a.createNewCategoryModel(uid, categoryCreateReq.SubCategories[j], j+1)
|
||||||
|
categoriesMap[category][j] = subCategory
|
||||||
|
totalCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
categoriesMap[nil][i] = category
|
||||||
|
categoryTypeMaxOrderMap[categoryCreateReq.Type] = maxOrderId + 1
|
||||||
|
totalCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
categories, err := a.categories.CreateCategories(c, uid, categoriesMap)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.ErrorfWithRequestId(c, "[transaction_categories.createBatchCategories] failed to create categories for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.InfofWithRequestId(c, "[transaction_categories.createBatchCategories] user \"uid:%d\" has created categories successfully", uid)
|
||||||
|
|
||||||
|
return categories, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *TransactionCategoriesApi) createNewCategoryModel(uid int64, categoryCreateReq *models.TransactionCategoryCreateRequest, order int32) *models.TransactionCategory {
|
func (a *TransactionCategoriesApi) createNewCategoryModel(uid int64, categoryCreateReq *models.TransactionCategoryCreateRequest, order int32) *models.TransactionCategory {
|
||||||
return &models.TransactionCategory{
|
return &models.TransactionCategory{
|
||||||
Uid: uid,
|
Uid: uid,
|
||||||
|
|||||||
+20
-5
@@ -4,6 +4,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/core"
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/log"
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
||||||
@@ -36,7 +38,7 @@ func (a *UsersApi) UserRegisterHandler(c *core.Context) (interface{}, *errs.Erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
var userRegisterReq models.UserRegisterRequest
|
var userRegisterReq models.UserRegisterRequest
|
||||||
err := c.ShouldBindJSON(&userRegisterReq)
|
err := c.ShouldBindBodyWith(&userRegisterReq, binding.JSON)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WarnfWithRequestId(c, "[users.UserRegisterHandler] parse request failed, because %s", err.Error())
|
log.WarnfWithRequestId(c, "[users.UserRegisterHandler] parse request failed, because %s", err.Error())
|
||||||
@@ -72,10 +74,23 @@ func (a *UsersApi) UserRegisterHandler(c *core.Context) (interface{}, *errs.Erro
|
|||||||
|
|
||||||
log.InfofWithRequestId(c, "[users.UserRegisterHandler] user \"%s\" has registered successfully, uid is %d", user.Username, user.Uid)
|
log.InfofWithRequestId(c, "[users.UserRegisterHandler] user \"%s\" has registered successfully, uid is %d", user.Username, user.Uid)
|
||||||
|
|
||||||
authResp := &models.AuthResponse{
|
presetCategoriesSaved := false
|
||||||
Need2FA: false,
|
|
||||||
NeedVerifyEmail: settings.Container.Current.EnableUserForceVerifyEmail,
|
if len(userRegisterReq.Categories) > 0 {
|
||||||
User: user.ToUserBasicInfo(),
|
_, err = TransactionCategories.createBatchCategories(c, user.Uid, &userRegisterReq.TransactionCategoryCreateBatchRequest)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
presetCategoriesSaved = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
authResp := &models.RegisterResponse{
|
||||||
|
AuthResponse: models.AuthResponse{
|
||||||
|
Need2FA: false,
|
||||||
|
User: user.ToUserBasicInfo(),
|
||||||
|
},
|
||||||
|
NeedVerifyEmail: settings.Container.Current.EnableUserForceVerifyEmail,
|
||||||
|
PresetCategoriesSaved: presetCategoriesSaved,
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.Container.Current.EnableUserVerifyEmail && settings.Container.Current.EnableSMTP {
|
if settings.Container.Current.EnableUserVerifyEmail && settings.Container.Current.EnableSMTP {
|
||||||
|
|||||||
@@ -2,8 +2,14 @@ package models
|
|||||||
|
|
||||||
// AuthResponse returns a view-object of user authorization
|
// AuthResponse returns a view-object of user authorization
|
||||||
type AuthResponse struct {
|
type AuthResponse struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
Need2FA bool `json:"need2FA"`
|
Need2FA bool `json:"need2FA"`
|
||||||
NeedVerifyEmail bool `json:"needVerifyEmail"`
|
User *UserBasicInfo `json:"user"`
|
||||||
User *UserBasicInfo `json:"user"`
|
}
|
||||||
|
|
||||||
|
// RegisterResponse returns a view-object of user register response
|
||||||
|
type RegisterResponse struct {
|
||||||
|
AuthResponse
|
||||||
|
NeedVerifyEmail bool `json:"needVerifyEmail"`
|
||||||
|
PresetCategoriesSaved bool `json:"presetCategoriesSaved"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ type UserRegisterRequest struct {
|
|||||||
Language string `json:"language" binding:"required,min=2,max=16"`
|
Language string `json:"language" binding:"required,min=2,max=16"`
|
||||||
DefaultCurrency string `json:"defaultCurrency" binding:"required,len=3,validCurrency"`
|
DefaultCurrency string `json:"defaultCurrency" binding:"required,len=3,validCurrency"`
|
||||||
FirstDayOfWeek WeekDay `json:"firstDayOfWeek" binding:"min=0,max=6"`
|
FirstDayOfWeek WeekDay `json:"firstDayOfWeek" binding:"min=0,max=6"`
|
||||||
|
TransactionCategoryCreateBatchRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserVerifyEmailRequest represents all parameters of user verify email request
|
// UserVerifyEmailRequest represents all parameters of user verify email request
|
||||||
|
|||||||
+3
-2
@@ -91,7 +91,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
register: ({ username, email, nickname, password, language, defaultCurrency, firstDayOfWeek }) => {
|
register: ({ username, email, nickname, password, language, defaultCurrency, firstDayOfWeek, categories }) => {
|
||||||
return axios.post('register.json', {
|
return axios.post('register.json', {
|
||||||
username,
|
username,
|
||||||
email,
|
email,
|
||||||
@@ -99,7 +99,8 @@ export default {
|
|||||||
password,
|
password,
|
||||||
language,
|
language,
|
||||||
defaultCurrency,
|
defaultCurrency,
|
||||||
firstDayOfWeek
|
firstDayOfWeek,
|
||||||
|
categories
|
||||||
}, {
|
}, {
|
||||||
timeout: api.requestVerifyEmailTimeout
|
timeout: api.requestVerifyEmailTimeout
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1056,8 +1056,11 @@ export default {
|
|||||||
'Use Preset Transaction Categories': 'Use Preset Transaction Categories',
|
'Use Preset Transaction Categories': 'Use Preset Transaction Categories',
|
||||||
'Preset Categories': 'Preset Categories',
|
'Preset Categories': 'Preset Categories',
|
||||||
'Set Whether You Use The Preset Transaction Categories': 'Set Whether You Use The Preset Transaction Categories',
|
'Set Whether You Use The Preset Transaction Categories': 'Set Whether You Use The Preset Transaction Categories',
|
||||||
|
'Complete': 'Complete',
|
||||||
|
'Registration Complete': 'Registration Complete',
|
||||||
'You have been successfully registered': 'You have been successfully registered',
|
'You have been successfully registered': 'You have been successfully registered',
|
||||||
'You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.': 'You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.',
|
'You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.': 'You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.',
|
||||||
|
'You have been successfully registered. Account activation link has been sent to your email address, please activate your account first.': 'You have been successfully registered. Account activation link has been sent to your email address, please activate your account first.',
|
||||||
'Unable to sign up': 'Unable to sign up',
|
'Unable to sign up': 'Unable to sign up',
|
||||||
'User registration is disabled': 'User registration is disabled',
|
'User registration is disabled': 'User registration is disabled',
|
||||||
'Unable to get user profile': 'Unable to get user profile',
|
'Unable to get user profile': 'Unable to get user profile',
|
||||||
|
|||||||
@@ -1056,8 +1056,11 @@ export default {
|
|||||||
'Use Preset Transaction Categories': '使用预设交易分类',
|
'Use Preset Transaction Categories': '使用预设交易分类',
|
||||||
'Preset Categories': '预设分类',
|
'Preset Categories': '预设分类',
|
||||||
'Set Whether You Use The Preset Transaction Categories': '设置是否使用预设交易分类',
|
'Set Whether You Use The Preset Transaction Categories': '设置是否使用预设交易分类',
|
||||||
|
'Complete': '完成',
|
||||||
|
'Registration Complete': '注册完成',
|
||||||
'You have been successfully registered': '注册成功',
|
'You have been successfully registered': '注册成功',
|
||||||
'You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.': '注册成功,但是添加预设分类时出错。您可以随时在设置页面中重新添加预设分类。',
|
'You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.': '您已经注册成功,但是添加预设分类时出错。您可以随时在设置页面中重新添加预设分类。',
|
||||||
|
'You have been successfully registered. Account activation link has been sent to your email address, please activate your account first.': '您已经注册成功。账号激活链接已经发送到您的邮箱地址,请先激活您的账号。',
|
||||||
'Unable to sign up': '无法注册',
|
'Unable to sign up': '无法注册',
|
||||||
'User registration is disabled': '用户注册已禁用',
|
'User registration is disabled': '用户注册已禁用',
|
||||||
'Unable to get user profile': '无法获取用户信息',
|
'Unable to get user profile': '无法获取用户信息',
|
||||||
|
|||||||
+3
-2
@@ -159,7 +159,7 @@ export const useRootStore = defineStore('root', {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
register({ user }) {
|
register({ user, presetCategories }) {
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -170,7 +170,8 @@ export const useRootStore = defineStore('root', {
|
|||||||
nickname: user.nickname,
|
nickname: user.nickname,
|
||||||
language: user.language,
|
language: user.language,
|
||||||
defaultCurrency: user.defaultCurrency,
|
defaultCurrency: user.defaultCurrency,
|
||||||
firstDayOfWeek: user.firstDayOfWeek
|
firstDayOfWeek: user.firstDayOfWeek,
|
||||||
|
categories: presetCategories
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
const data = response.data;
|
const data = response.data;
|
||||||
|
|
||||||
|
|||||||
@@ -20,18 +20,7 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" md="8" class="auth-card d-flex align-center justify-center pa-10">
|
<v-col cols="12" md="8" class="auth-card d-flex align-center justify-center pa-10">
|
||||||
<v-card variant="flat" class="mt-12 mt-sm-0 pt-sm-12 pt-md-0">
|
<v-card variant="flat" class="mt-12 mt-sm-0 pt-sm-12 pt-md-0">
|
||||||
<steps-bar min-width="700" :steps="[
|
<steps-bar min-width="700" :steps="allSteps" :current-step="currentStep" @step:change="switchToTab" />
|
||||||
{
|
|
||||||
'name': 'basicSetting',
|
|
||||||
'title': $t('User Information'),
|
|
||||||
'subTitle': $t('Basic Information')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'presetCategories',
|
|
||||||
'title': $t('Transaction Categories'),
|
|
||||||
'subTitle': $t('Preset Categories')
|
|
||||||
}
|
|
||||||
]" :current-step="currentStep" @step:change="switchToTab" />
|
|
||||||
|
|
||||||
<v-window class="mt-5 disable-tab-transition" style="max-width: 700px" v-model="currentStep">
|
<v-window class="mt-5 disable-tab-transition" style="max-width: 700px" v-model="currentStep">
|
||||||
<v-form>
|
<v-form>
|
||||||
@@ -47,7 +36,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
clearable
|
clearable
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Username')"
|
:label="$t('Username')"
|
||||||
:placeholder="$t('Your username')"
|
:placeholder="$t('Your username')"
|
||||||
v-model="user.username"
|
v-model="user.username"
|
||||||
@@ -59,7 +48,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
autocomplete="nickname"
|
autocomplete="nickname"
|
||||||
clearable
|
clearable
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Nickname')"
|
:label="$t('Nickname')"
|
||||||
:placeholder="$t('Your nickname')"
|
:placeholder="$t('Your nickname')"
|
||||||
v-model="user.nickname"
|
v-model="user.nickname"
|
||||||
@@ -72,7 +61,7 @@
|
|||||||
type="email"
|
type="email"
|
||||||
autocomplete="email"
|
autocomplete="email"
|
||||||
clearable
|
clearable
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('E-mail')"
|
:label="$t('E-mail')"
|
||||||
:placeholder="$t('Your email address')"
|
:placeholder="$t('Your email address')"
|
||||||
v-model="user.email"
|
v-model="user.email"
|
||||||
@@ -84,7 +73,7 @@
|
|||||||
<v-text-field
|
<v-text-field
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
clearable
|
clearable
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Password')"
|
:label="$t('Password')"
|
||||||
:placeholder="$t('Your password, at least 6 characters')"
|
:placeholder="$t('Your password, at least 6 characters')"
|
||||||
:type="isPasswordVisible ? 'text' : 'password'"
|
:type="isPasswordVisible ? 'text' : 'password'"
|
||||||
@@ -97,7 +86,7 @@
|
|||||||
<v-text-field
|
<v-text-field
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
clearable
|
clearable
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Confirmation Password')"
|
:label="$t('Confirmation Password')"
|
||||||
:placeholder="$t('Re-enter the password')"
|
:placeholder="$t('Re-enter the password')"
|
||||||
:type="isConfirmPasswordVisible ? 'text' : 'password'"
|
:type="isConfirmPasswordVisible ? 'text' : 'password'"
|
||||||
@@ -113,7 +102,7 @@
|
|||||||
<v-select
|
<v-select
|
||||||
item-title="displayName"
|
item-title="displayName"
|
||||||
item-value="code"
|
item-value="code"
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Language')"
|
:label="$t('Language')"
|
||||||
:placeholder="$t('Language')"
|
:placeholder="$t('Language')"
|
||||||
:items="allLanguages"
|
:items="allLanguages"
|
||||||
@@ -128,7 +117,7 @@
|
|||||||
item-title="displayName"
|
item-title="displayName"
|
||||||
item-value="code"
|
item-value="code"
|
||||||
auto-select-first
|
auto-select-first
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Default Currency')"
|
:label="$t('Default Currency')"
|
||||||
:placeholder="$t('Default Currency')"
|
:placeholder="$t('Default Currency')"
|
||||||
:items="allCurrencies"
|
:items="allCurrencies"
|
||||||
@@ -145,7 +134,7 @@
|
|||||||
<v-select
|
<v-select
|
||||||
item-title="displayName"
|
item-title="displayName"
|
||||||
item-value="type"
|
item-value="type"
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('First Day of Week')"
|
:label="$t('First Day of Week')"
|
||||||
:placeholder="$t('First Day of Week')"
|
:placeholder="$t('First Day of Week')"
|
||||||
:items="allWeekDays"
|
:items="allWeekDays"
|
||||||
@@ -162,7 +151,7 @@
|
|||||||
<v-row class="mb-5">
|
<v-row class="mb-5">
|
||||||
<v-col cols="12" sm="6">
|
<v-col cols="12" sm="6">
|
||||||
<v-switch inset
|
<v-switch inset
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:label="$t('Use Preset Transaction Categories')"
|
:label="$t('Use Preset Transaction Categories')"
|
||||||
v-model="usePresetCategories"/>
|
v-model="usePresetCategories"/>
|
||||||
</v-col>
|
</v-col>
|
||||||
@@ -170,7 +159,7 @@
|
|||||||
<v-menu location="bottom">
|
<v-menu location="bottom">
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<v-btn variant="text"
|
<v-btn variant="text"
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
v-bind="props">{{ currentLanguageName }}</v-btn>
|
v-bind="props">{{ currentLanguageName }}</v-btn>
|
||||||
</template>
|
</template>
|
||||||
<v-list>
|
<v-list>
|
||||||
@@ -186,7 +175,7 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<div class="overflow-y-auto px-3" :class="{ 'disabled': !usePresetCategories || submitting }" style="max-height: 323px">
|
<div class="overflow-y-auto px-3" :class="{ 'disabled': !usePresetCategories || submitting || navigateToHomePage }" style="max-height: 323px">
|
||||||
<v-row :key="categoryType" v-for="(categories, categoryType) in allPresetCategories">
|
<v-row :key="categoryType" v-for="(categories, categoryType) in allPresetCategories">
|
||||||
<v-col cols="12" md="12">
|
<v-col cols="12" md="12">
|
||||||
<h4 class="mb-3">{{ getCategoryTypeName(categoryType) }}</h4>
|
<h4 class="mb-3">{{ getCategoryTypeName(categoryType) }}</h4>
|
||||||
@@ -217,33 +206,41 @@
|
|||||||
</v-row>
|
</v-row>
|
||||||
</div>
|
</div>
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
|
|
||||||
|
<v-window-item value="finalResult" v-if="finalResultMessage">
|
||||||
|
<h5 class="text-h5 mb-1">{{ $t('Registration Complete') }}</h5>
|
||||||
|
<p class="my-5">{{ finalResultMessage }}</p>
|
||||||
|
</v-window-item>
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-window>
|
</v-window>
|
||||||
|
|
||||||
<div class="d-flex justify-sm-space-between gap-4 flex-wrap justify-center mt-5">
|
<div class="d-flex justify-sm-space-between gap-4 flex-wrap justify-center mt-5">
|
||||||
<v-btn :color="currentStep === 'basicSetting' ? 'default' : 'primary'"
|
<v-btn :color="(currentStep === 'basicSetting' || currentStep === 'finalResult') ? 'default' : 'primary'"
|
||||||
:disabled="currentStep === 'basicSetting' || submitting"
|
:disabled="currentStep === 'basicSetting' || currentStep === 'finalResult' || submitting || navigateToHomePage"
|
||||||
:prepend-icon="icons.previous"
|
:prepend-icon="icons.previous"
|
||||||
@click="switchToPreviousTab">{{ $t('Previous') }}</v-btn>
|
@click="switchToPreviousTab">{{ $t('Previous') }}</v-btn>
|
||||||
<v-btn :color="currentStep === 'presetCategories' ? 'secondary' : 'primary'"
|
<v-btn :color="(currentStep === 'presetCategories' || currentStep === 'finalResult') ? 'secondary' : 'primary'"
|
||||||
:disabled="currentStep === 'presetCategories' || submitting"
|
:disabled="currentStep === 'presetCategories' || currentStep === 'finalResult' || submitting || navigateToHomePage"
|
||||||
:append-icon="icons.next"
|
:append-icon="icons.next"
|
||||||
@click="switchToNextTab"
|
@click="switchToNextTab"
|
||||||
v-if="currentStep !== 'presetCategories'">{{ $t('Next') }}</v-btn>
|
v-if="currentStep === 'basicSetting'">{{ $t('Next') }}</v-btn>
|
||||||
<v-btn color="expense"
|
<v-btn color="expense"
|
||||||
:disabled="submitting"
|
:disabled="submitting || navigateToHomePage"
|
||||||
:append-icon="!submitting ? icons.submit : null"
|
:append-icon="!submitting ? icons.submit : null"
|
||||||
@click="submit"
|
@click="submit"
|
||||||
v-if="currentStep === 'presetCategories'">
|
v-if="currentStep === 'presetCategories'">
|
||||||
{{ $t('Submit') }}
|
{{ $t('Submit') }}
|
||||||
<v-progress-circular indeterminate size="24" class="ml-2" v-if="submitting"></v-progress-circular>
|
<v-progress-circular indeterminate size="24" class="ml-2" v-if="submitting"></v-progress-circular>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
<v-btn :append-icon="icons.next"
|
||||||
|
@click="navigateToLogin"
|
||||||
|
v-if="currentStep === 'finalResult'">{{ $t('Continue') }}</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<snack-bar ref="snackbar" />
|
<snack-bar ref="snackbar" @update:show="onSnackbarShowStateChanged" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -281,6 +278,8 @@ export default {
|
|||||||
isConfirmPasswordVisible: false,
|
isConfirmPasswordVisible: false,
|
||||||
submitting: false,
|
submitting: false,
|
||||||
usePresetCategories: false,
|
usePresetCategories: false,
|
||||||
|
finalResultMessage: null,
|
||||||
|
navigateToHomePage: false,
|
||||||
icons: {
|
icons: {
|
||||||
previous: mdiArrowLeft,
|
previous: mdiArrowLeft,
|
||||||
next: mdiArrowRight,
|
next: mdiArrowRight,
|
||||||
@@ -341,6 +340,30 @@ export default {
|
|||||||
|
|
||||||
return languageInfo.displayName;
|
return languageInfo.displayName;
|
||||||
},
|
},
|
||||||
|
allSteps() {
|
||||||
|
const allSteps = [
|
||||||
|
{
|
||||||
|
name: 'basicSetting',
|
||||||
|
title: this.$t('User Information'),
|
||||||
|
subTitle: this.$t('Basic Information')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'presetCategories',
|
||||||
|
title: this.$t('Transaction Categories'),
|
||||||
|
subTitle: this.$t('Preset Categories')
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
if (this.finalResultMessage) {
|
||||||
|
allSteps.push({
|
||||||
|
name: 'finalResult',
|
||||||
|
title: this.$t('Complete'),
|
||||||
|
subTitle: this.$t('Registration Complete')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return allSteps;
|
||||||
|
},
|
||||||
inputIsEmpty() {
|
inputIsEmpty() {
|
||||||
return !!this.inputEmptyProblemMessage;
|
return !!this.inputEmptyProblemMessage;
|
||||||
},
|
},
|
||||||
@@ -381,7 +404,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
switchToTab(tabName) {
|
switchToTab(tabName) {
|
||||||
if (this.submitting) {
|
if (this.submitting || this.currentStep === 'finalResult' || this.navigateToHomePage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,27 +437,33 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.navigateToHomePage = false;
|
||||||
self.submitting = true;
|
self.submitting = true;
|
||||||
|
|
||||||
let submitCategories = [];
|
let presetCategories = [];
|
||||||
|
|
||||||
if (self.usePresetCategories) {
|
if (self.usePresetCategories) {
|
||||||
submitCategories = categorizedArrayToPlainArray(self.allPresetCategories);
|
presetCategories = categorizedArrayToPlainArray(self.allPresetCategories);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.rootStore.register({
|
self.rootStore.register({
|
||||||
user: self.user
|
user: self.user,
|
||||||
|
presetCategories: presetCategories
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (!self.$user.isUserLogined()) {
|
if (!self.$user.isUserLogined()) {
|
||||||
self.submitting = false;
|
self.submitting = false;
|
||||||
|
|
||||||
if (self.usePresetCategories) {
|
if (self.usePresetCategories && !response.presetCategoriesSaved) {
|
||||||
self.$refs.snackbar.showMessage('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
self.finalResultMessage = self.$t('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
||||||
|
self.currentStep = 'finalResult';
|
||||||
|
} else if (response.needVerifyEmail) {
|
||||||
|
self.finalResultMessage = self.$t('You have been successfully registered. Account activation link has been sent to your email address, please activate your account first.');
|
||||||
|
self.currentStep = 'finalResult';
|
||||||
} else {
|
} else {
|
||||||
self.$refs.snackbar.showMessage('You have been successfully registered');
|
self.$refs.snackbar.showMessage('You have been successfully registered');
|
||||||
|
self.navigateToHomePage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.$router.replace('/');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,27 +476,15 @@ export default {
|
|||||||
self.exchangeRatesStore.getLatestExchangeRates({ silent: true, force: false });
|
self.exchangeRatesStore.getLatestExchangeRates({ silent: true, force: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self.usePresetCategories) {
|
self.submitting = false;
|
||||||
self.submitting = false;
|
|
||||||
|
|
||||||
|
if (self.usePresetCategories && !response.presetCategoriesSaved) {
|
||||||
|
self.$refs.snackbar.showMessage('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
||||||
|
} else {
|
||||||
self.$refs.snackbar.showMessage('You have been successfully registered');
|
self.$refs.snackbar.showMessage('You have been successfully registered');
|
||||||
self.$router.replace('/');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.transactionCategoriesStore.addCategories({
|
self.navigateToHomePage = true;
|
||||||
categories: submitCategories
|
|
||||||
}).then(() => {
|
|
||||||
self.submitting = false;
|
|
||||||
|
|
||||||
self.$refs.snackbar.showMessage('You have been successfully registered');
|
|
||||||
self.$router.replace('/');
|
|
||||||
}).catch(() => {
|
|
||||||
self.submitting = false;
|
|
||||||
|
|
||||||
self.$refs.snackbar.showMessage('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
|
||||||
self.$router.replace('/');
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
self.submitting = false;
|
self.submitting = false;
|
||||||
|
|
||||||
@@ -476,6 +493,14 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
navigateToLogin() {
|
||||||
|
this.$router.push('/');
|
||||||
|
},
|
||||||
|
onSnackbarShowStateChanged(newValue) {
|
||||||
|
if (!newValue && this.navigateToHomePage) {
|
||||||
|
this.$router.replace('/');
|
||||||
|
}
|
||||||
|
},
|
||||||
getCategoryTypeName(categoryType) {
|
getCategoryTypeName(categoryType) {
|
||||||
switch (categoryType) {
|
switch (categoryType) {
|
||||||
case categoryConstants.allCategoryTypes.Income.toString():
|
case categoryConstants.allCategoryTypes.Income.toString():
|
||||||
|
|||||||
@@ -295,21 +295,24 @@ export default {
|
|||||||
self.submitting = true;
|
self.submitting = true;
|
||||||
self.$showLoading(() => self.submitting);
|
self.$showLoading(() => self.submitting);
|
||||||
|
|
||||||
let submitCategories = [];
|
let presetCategories = [];
|
||||||
|
|
||||||
if (self.usePresetCategories) {
|
if (self.usePresetCategories) {
|
||||||
submitCategories = categorizedArrayToPlainArray(self.allPresetCategories);
|
presetCategories = categorizedArrayToPlainArray(self.allPresetCategories);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.rootStore.register({
|
self.rootStore.register({
|
||||||
user: self.user
|
user: self.user,
|
||||||
|
presetCategories: presetCategories
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
if (!self.$user.isUserLogined()) {
|
if (!self.$user.isUserLogined()) {
|
||||||
self.submitting = false;
|
self.submitting = false;
|
||||||
self.$hideLoading();
|
self.$hideLoading();
|
||||||
|
|
||||||
if (self.usePresetCategories) {
|
if (self.usePresetCategories && !response.presetCategoriesSaved) {
|
||||||
self.$toast('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
self.$toast('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.', 5000);
|
||||||
|
} else if (response.needVerifyEmail) {
|
||||||
|
self.$toast('You have been successfully registered. Account activation link has been sent to your email address, please activate your account first.', 5000);
|
||||||
} else {
|
} else {
|
||||||
self.$toast('You have been successfully registered');
|
self.$toast('You have been successfully registered');
|
||||||
}
|
}
|
||||||
@@ -327,30 +330,16 @@ export default {
|
|||||||
self.exchangeRatesStore.getLatestExchangeRates({ silent: true, force: false });
|
self.exchangeRatesStore.getLatestExchangeRates({ silent: true, force: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self.usePresetCategories) {
|
self.submitting = false;
|
||||||
self.submitting = false;
|
self.$hideLoading();
|
||||||
self.$hideLoading();
|
|
||||||
|
|
||||||
|
if (self.usePresetCategories && !response.presetCategoriesSaved) {
|
||||||
|
self.$toast('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
||||||
|
} else {
|
||||||
self.$toast('You have been successfully registered');
|
self.$toast('You have been successfully registered');
|
||||||
router.navigate('/');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.transactionCategoriesStore.addCategories({
|
router.navigate('/');
|
||||||
categories: submitCategories
|
|
||||||
}).then(() => {
|
|
||||||
self.submitting = false;
|
|
||||||
self.$hideLoading();
|
|
||||||
|
|
||||||
self.$toast('You have been successfully registered');
|
|
||||||
router.navigate('/');
|
|
||||||
}).catch(() => {
|
|
||||||
self.submitting = false;
|
|
||||||
self.$hideLoading();
|
|
||||||
|
|
||||||
self.$toast('You have been successfully registered, but something wrong with adding preset categories. You can re-add preset categories in settings page anytime.');
|
|
||||||
router.navigate('/');
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
self.submitting = false;
|
self.submitting = false;
|
||||||
self.$hideLoading();
|
self.$hideLoading();
|
||||||
|
|||||||
Reference in New Issue
Block a user