+
+
+
+
+
+
Invalid password reset link
+
The link you followed doesn't seem like a valid password reset link.
-
-
-
- Provide your new password
-
-
- -
- Your password can't be too similar to your other personal
- information.
-
- - Your password must contain at least 8 characters.
- - Your password can't be a commonly used password.
-
- - Your password can't be entirely numeric.
-
-
-
-
-
-
- Submit
-
-
+
+
+
Provide your new password
+
+
-
+
-
-
diff --git a/components/account/signup/SignupAccount.vue b/components/account/signup/SignupAccount.vue
new file mode 100644
index 00000000..3156940d
--- /dev/null
+++ b/components/account/signup/SignupAccount.vue
@@ -0,0 +1,168 @@
+
+
+
+
+
Account
+
+
+
+
+
+
+ -
+ Your password can't be too similar to your other personal
+ information.
+
+ - Your password must contain at least 8 characters.
+ - Your password can't be a commonly used password.
+ - Your password can't be entirely numeric.
+
+
+
+
+
+
+
+
+
+ Back
+
+
+ Continue
+
+
+
diff --git a/components/account/signup/SignupAddress.vue b/components/account/signup/SignupAddress.vue
new file mode 100644
index 00000000..77638e68
--- /dev/null
+++ b/components/account/signup/SignupAddress.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
Address
+
+
+
+
+
+
+
+
+
+ I have read and agreed to the
+
+ Terms of Service
+
+ and the
+
+ Privacy Policy.
+
+
+
+
+
+
+ Back
+
+
+ Create Account
+
+
+
diff --git a/components/account/signup/SignupCustomerInformation.vue b/components/account/signup/SignupCustomerInformation.vue
new file mode 100644
index 00000000..9ac47be8
--- /dev/null
+++ b/components/account/signup/SignupCustomerInformation.vue
@@ -0,0 +1,134 @@
+
+
+
+
+
Customer Information
+
+
+
+
+
+
+
+
+
+ Back
+
+
+ Continue
+
+
+
diff --git a/components/account/signup/SignupForm.vue b/components/account/signup/SignupForm.vue
index d5b924c4..38444f08 100644
--- a/components/account/signup/SignupForm.vue
+++ b/components/account/signup/SignupForm.vue
@@ -1,421 +1,198 @@
-
-
- Create a rotki premium Account
-
-
-
-
- Important Note: Creating an
- account in rotki.com is only needed to purchase a
-
- premium subscription
-
- Rotki is a local application and the account you create when you use
- it is stored on your computer. This is not the same account as premium
- and credentials for one account don't work for the other. To use Rotki
- simply
-
- download
-
- and run it. Proceed only if you intend to purchase premium and unlock
- the premium features of the application.
-
-
-
Account
-
-
-
-
-
-
-
- -
- Your password can't be too similar to your other personal
- information.
-
- - Your password must contain at least 8 characters.
- - Your password can't be a commonly used password.
-
- - Your password can't be entirely numeric.
-
-
-
-
-
-
-
Customer Information
-
-
-
-
-
-
-
-
-
Address
-
-
-
-
-
-
-
-
-
+
+ :external-results="$externalResults"
+ @back="back()"
+ @finish="signup($event)"
+ />
+
+
+
+
-
-
-
-
+
+
+
+
+
diff --git a/components/account/signup/SignupIntroduction.vue b/components/account/signup/SignupIntroduction.vue
new file mode 100644
index 00000000..35fb1636
--- /dev/null
+++ b/components/account/signup/SignupIntroduction.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
Important Note
+
+ Creating an account in rotki.com is only needed to purchase a
+ premium subscription. Rotki is a local application and
+ the account you create when you use it is stored on your computer.
+
+
+ This is not the same account as premium and credentials for one account
+ don't work for the other. To use Rotki simply
+
+ download
+
+ and run it.
+
+
+ Proceed only if you intend to purchase premium and unlock the premium
+ features of the application.
+
+
+
+
+ Continue
+
+
+
diff --git a/components/common/ButtonLink.vue b/components/common/ButtonLink.vue
index dabad8bd..8dd206f6 100644
--- a/components/common/ButtonLink.vue
+++ b/components/common/ButtonLink.vue
@@ -30,6 +30,7 @@ const attrs = useAttrs();
>
diff --git a/components/footer/PageFooter.vue b/components/footer/PageFooter.vue
index 1947883d..fe709cfb 100644
--- a/components/footer/PageFooter.vue
+++ b/components/footer/PageFooter.vue
@@ -1,15 +1,27 @@
-
+
-
+
@@ -27,9 +39,9 @@ const year = new Date().getFullYear().toString();
-
+
{
-
+
-
+
{{ t('page_header.manage_premium') }}
diff --git a/layouts/default.vue b/layouts/default.vue
index faed4911..b3ed3dba 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -1,5 +1,36 @@
+
+
-
-
-
+
+
+
+
+
+
+
diff --git a/layouts/landing.vue b/layouts/landing.vue
new file mode 100644
index 00000000..6fbe4602
--- /dev/null
+++ b/layouts/landing.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 8aae30bb..a5d6c424 100644
--- a/package.json
+++ b/package.json
@@ -50,7 +50,7 @@
"@nuxt/devtools": "0.6.7",
"@nuxtjs/i18n": "8.0.0-beta.12",
"@rotki/eslint-config": "1.1.0",
- "@rotki/ui-library": "0.1.2",
+ "@rotki/ui-library": "0.2.0",
"@types/braintree-web": "3.75.23",
"@types/paypal-checkout-components": "4.0.5",
"@types/qrcode": "1.5.1",
diff --git a/pages/activate/[uid]/[token].vue b/pages/activate/[uid]/[token].vue
index 46b873b2..e3456659 100644
--- a/pages/activate/[uid]/[token].vue
+++ b/pages/activate/[uid]/[token].vue
@@ -22,7 +22,3 @@ useHead({
-
-
diff --git a/pages/activation.vue b/pages/activation.vue
index 2aa848d2..1d9c466c 100644
--- a/pages/activation.vue
+++ b/pages/activation.vue
@@ -18,7 +18,3 @@ useHead({
-
-
diff --git a/pages/index.vue b/pages/index.vue
index 34d2cbfb..e32f9cf4 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -23,6 +23,10 @@ useHead({
...commonAttrs(),
});
const { visible } = useOverflow();
+
+definePageMeta({
+ layout: 'landing',
+});
diff --git a/pages/login.vue b/pages/login.vue
index 4ed510fe..a6accacd 100644
--- a/pages/login.vue
+++ b/pages/login.vue
@@ -21,7 +21,3 @@ useHead({
-
-
diff --git a/pages/password/changed.vue b/pages/password/changed.vue
index e6923ec2..3149f9cb 100644
--- a/pages/password/changed.vue
+++ b/pages/password/changed.vue
@@ -22,7 +22,3 @@ useHead({
-
-
diff --git a/pages/password/recover.vue b/pages/password/recover.vue
index c8784f51..10b2b86c 100644
--- a/pages/password/recover.vue
+++ b/pages/password/recover.vue
@@ -21,7 +21,3 @@ useHead({
-
-
diff --git a/pages/password/reset/[uid]/[token].vue b/pages/password/reset/[uid]/[token].vue
index a328b462..66019d28 100644
--- a/pages/password/reset/[uid]/[token].vue
+++ b/pages/password/reset/[uid]/[token].vue
@@ -22,7 +22,3 @@ useHead({
-
-
diff --git a/pages/password/reset/index.vue b/pages/password/reset/index.vue
index af05786e..721f1570 100644
--- a/pages/password/reset/index.vue
+++ b/pages/password/reset/index.vue
@@ -22,7 +22,3 @@ useHead({
-
-
diff --git a/pages/password/send.vue b/pages/password/send.vue
index 97ee8af3..597e57f4 100644
--- a/pages/password/send.vue
+++ b/pages/password/send.vue
@@ -22,7 +22,3 @@ useHead({
-
-
diff --git a/pages/signup.vue b/pages/signup.vue
index 6e894ff8..54e2c87f 100644
--- a/pages/signup.vue
+++ b/pages/signup.vue
@@ -21,7 +21,3 @@ useHead({
-
-
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c19415df..cc0f3998 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -83,8 +83,8 @@ devDependencies:
specifier: 1.1.0
version: 1.1.0(eslint@8.45.0)(vue@3.3.4)
'@rotki/ui-library':
- specifier: 0.1.2
- version: 0.1.2(vue@3.3.4)
+ specifier: 0.2.0
+ version: 0.2.0(vue@3.3.4)
'@types/braintree-web':
specifier: 3.75.23
version: 3.75.23
@@ -2234,8 +2234,8 @@ packages:
- vue
dev: true
- /@rotki/ui-library@0.1.2(vue@3.3.4):
- resolution: {integrity: sha512-2gzD/kjuw13Pxpsjcf/8BzQkN36Yhg1FltrkVJNFABcpimkGkZZLgyIeDWw4V6BnLkQUCRhAYUfj1Jb6Sxjviw==}
+ /@rotki/ui-library@0.2.0(vue@3.3.4):
+ resolution: {integrity: sha512-j4wiRkbIaBTEX4yLT8v4FziPz/IlA564Hd6NCjJne3eAE6pLMw2v4fM5AelMotDw5rjoGRXh8vqXNpHK3W43Fw==}
engines: {pnpm: '>=8 <9'}
peerDependencies:
vue: '>=3.3.4'
diff --git a/tests/e2e/specs/pages/signup.spec.cy.ts b/tests/e2e/specs/pages/signup.spec.cy.ts
index 418b0188..11b559af 100644
--- a/tests/e2e/specs/pages/signup.spec.cy.ts
+++ b/tests/e2e/specs/pages/signup.spec.cy.ts
@@ -3,36 +3,65 @@ describe('Signup test', () => {
cy.visit('/signup').wait(3000);
});
- it('checks input fields and submit button!', () => {
+ it('show introduction page', () => {
+ cy.contains('Important Note');
+ cy.get('[data-cy=next-button]').click();
+ });
+
+ it('show account form', () => {
cy.get('input#username').first().as('usernameInput');
cy.get('input#email').first().as('emailInput');
cy.get('input#github').first().as('githubInput');
cy.get('input#password').first().as('passwordInput');
cy.get('input#password-confirmation').first().as('confirmPasswordInput');
+ cy.get('button[data-cy=next-button]').first().as('nextButton');
+
+ expect(cy.get('@usernameInput')).to.exist;
+ expect(cy.get('@emailInput')).to.exist;
+ expect(cy.get('@passwordInput')).to.exist;
+ expect(cy.get('@confirmPasswordInput')).to.exist;
+ expect(cy.get('@nextButton').should('be.disabled'));
+
+ cy.get('@usernameInput').type('username');
+ cy.get('@emailInput').type('email@gmail.com');
+ cy.get('@passwordInput').type('p455w0rD');
+ cy.get('@confirmPasswordInput').type('p455w0rD');
+ expect(cy.get('@nextButton').should('be.enabled'));
+ cy.get('@nextButton').click();
+ });
+
+ it('show customer information form', () => {
cy.get('input#first-name').first().as('firstNameInput');
cy.get('input#last-name').first().as('lastNameInput');
cy.get('input#company-name').first().as('companyNameInput');
cy.get('input#vat-id').first().as('vatIdInput');
+ cy.get('button[data-cy=next-button]').first().as('nextButton');
+
+ expect(cy.get('@firstNameInput')).to.exist;
+ expect(cy.get('@lastNameInput')).to.exist;
+ expect(cy.get('@companyNameInput')).to.exist;
+ expect(cy.get('@vatIdInput')).to.exist;
+ expect(cy.get('@nextButton').should('be.disabled'));
+
+ cy.get('@firstNameInput').type('First');
+ cy.get('@lastNameInput').type('Last');
+ cy.get('@nextButton').click();
+ });
+
+ it('show address form', () => {
cy.get('input#address-1').first().as('address1Input');
cy.get('input#address-2').first().as('address2Input');
cy.get('input#city').first().as('cityInput');
cy.get('input#postal').first().as('postalInput');
- cy.get('input#country').first().as('countryInput');
+ cy.get('#country input').first().as('countryInput');
cy.get('div#signup-captcha').first().as('captcha');
cy.get('input#tos').first().as('tosInput');
cy.get('button')
.contains('button', 'Create Account')
.first()
.as('submitButton');
+ cy.get('button[data-cy=submit-button]').first().as('submitButton');
- expect(cy.get('@usernameInput')).to.exist;
- expect(cy.get('@emailInput')).to.exist;
- expect(cy.get('@passwordInput')).to.exist;
- expect(cy.get('@confirmPasswordInput')).to.exist;
- expect(cy.get('@firstNameInput')).to.exist;
- expect(cy.get('@lastNameInput')).to.exist;
- expect(cy.get('@companyNameInput')).to.exist;
- expect(cy.get('@vatIdInput')).to.exist;
expect(cy.get('@address1Input')).to.exist;
expect(cy.get('@address2Input')).to.exist;
expect(cy.get('@cityInput')).to.exist;
@@ -40,26 +69,33 @@ describe('Signup test', () => {
expect(cy.get('@countryInput')).to.exist;
expect(cy.get('@captcha')).to.exist;
expect(cy.get('@tosInput')).to.exist;
- expect(cy.get('@submitButton')).to.exist;
+ expect(cy.get('@submitButton').should('be.disabled'));
+
+ cy.get('@address1Input').type('Address first line');
+ cy.get('@address2Input').type('Address second line');
+ cy.get('@cityInput').type('City');
+ cy.get('@postalInput').type('11703');
+ cy.get('@countryInput').click();
+ cy.get('#country').find('li').first().click();
+ cy.get('@tosInput').click();
});
it('checks signup postal input field for valid inputs!', () => {
cy.get('input#postal').first().as('postalInput');
cy.get('@postalInput').type('12345');
- cy.get('span#postal-error').should('not.exist');
+ cy.get('#postal .details .text-rui-error').should('not.exist');
cy.get('@postalInput').clear().type('ABC-40');
- cy.get('span#postal-error').should('not.exist');
+ cy.get('#postal .details .text-rui-error').should('not.exist');
cy.get('@postalInput').clear().type('ABC-40 224');
- cy.get('span#postal-error').should('not.exist');
-
+ cy.get('#postal .details .text-rui-error').should('not.exist');
cy.get('@postalInput').clear().type('12@345');
- cy.get('span#postal-error').first().as('postalError');
+ cy.get('#postal .details .text-rui-error').first().as('postalError');
expect(cy.get('@postalError')).to.exist;
cy.get('@postalInput').clear().type('12#345');
expect(cy.get('@postalError')).to.exist;
cy.get('@postalInput').clear().type('.');
expect(cy.get('@postalError')).to.exist;
cy.get('@postalInput').clear().type('105102');
- cy.get('span#postal-error').should('not.exist');
+ cy.get('#postal .details .text-rui-error').should('not.exist');
});
});
diff --git a/types/common.ts b/types/common.ts
index 718c81e5..ef04e2e9 100644
--- a/types/common.ts
+++ b/types/common.ts
@@ -16,3 +16,5 @@ export type ActionResult = {
export type BaseErrorObject = { $message: string | Ref };
export type PayEvent = { months: number; nonce: string };
+
+export type ValidationErrors = Record;
diff --git a/types/index.ts b/types/index.ts
index 09620fd2..08cd9b33 100644
--- a/types/index.ts
+++ b/types/index.ts
@@ -13,9 +13,9 @@ type ResultSuccess = {
export type Result = ResultError | ResultSuccess;
-export interface ApiResponse {
+export interface ApiResponse {
readonly result: T | null;
- readonly message: string;
+ readonly message: M;
}
const StringArray = z.array(z.string());
diff --git a/types/signup.ts b/types/signup.ts
index d799ac0a..195752ae 100644
--- a/types/signup.ts
+++ b/types/signup.ts
@@ -1,16 +1,27 @@
-export interface SignupPayload {
+export interface SignupAccountPayload {
readonly username: string;
readonly email: string;
readonly password: string;
readonly confirmPassword: string;
+ readonly githubUsername: string;
+}
+
+export interface SignupCustomerInformationPayload {
readonly firstName: string;
readonly lastName: string;
readonly companyName: string;
+ readonly vatId: string;
+}
+
+export interface SignupAddressPayload {
readonly address1: string;
readonly address2: string;
readonly city: string;
- readonly country: string;
readonly postcode: string;
- readonly githubUsername: string;
- readonly vatId: string;
+ readonly country: string;
}
+
+export interface SignupPayload
+ extends SignupAccountPayload,
+ SignupCustomerInformationPayload,
+ SignupAddressPayload {}
diff --git a/utils/validation.ts b/utils/validation.ts
new file mode 100644
index 00000000..4568da34
--- /dev/null
+++ b/utils/validation.ts
@@ -0,0 +1,12 @@
+import { type BaseValidation } from '@vuelidate/core';
+import { get } from '@vueuse/core';
+
+/**
+ * Converts an object of vuelidate's BaseValidation to an array of
+ * strings to be passed to the components error-messages
+ *
+ * @param validation BaseValidation
+ * @return string[]
+ */
+export const toMessages = (validation: BaseValidation): string[] =>
+ validation.$errors.map((e) => get(e.$message));