mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into 1823-Describe_Setup_on_Windows
This commit is contained in:
commit
2889d564a7
81
docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md
Normal file
81
docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md
Normal file
@ -0,0 +1,81 @@
|
||||
# Business Event Protocol
|
||||
|
||||
With the business event protocol the gradido application will capture and persist business information for future reports and statistics. The idea is to design and implement general functionality to capture and store business events. Each business event will be defined as a separate event type with its own business attributes. Each event type extends a basic event type to ensure a type safetiness with its mandatory and optional attributes.
|
||||
|
||||
## EventType - Enum
|
||||
|
||||
The different event types will be defined as Enum. The following list is a first draft and will grow with further event types in the future.
|
||||
|
||||
| EventType | Value | Description |
|
||||
| --------------------------- | ----- | ---------------------------------------------------------------------------------------------------- |
|
||||
| BasicEvent | 0 | the basic event is the root of all further extending event types |
|
||||
| VisitGradidoEvent | 10 | if a user visits a gradido page without login or register |
|
||||
| RegisterEvent | 20 | the user presses the register button |
|
||||
| RedeemRegisterEvent | 21 | the user presses the register button initiated by the redeem link |
|
||||
| InActiveAccountEvent | 22 | the systems create an inactive account during the register process |
|
||||
| SendConfirmEmailEvent | 23 | the system send a confirmation email to the user during the register process |
|
||||
| ConfirmEmailEvent | 24 | the user confirms his email during the register process |
|
||||
| RegisterEmailKlickTippEvent | 25 | the system registers the confirmed email at klicktipp |
|
||||
| LoginEvent | 30 | the user presses the login button |
|
||||
| RedeemLoginEvent | 31 | the user presses the login button initiated by the redeem link |
|
||||
| ActivateAccountEvent | 32 | the system activates the users account during the first login process |
|
||||
| PasswordChangeEvent | 33 | the user changes his password |
|
||||
| TxSendEvent | 40 | the user creates a transaction and sends it online |
|
||||
| TxSendRedeemEvent | 41 | the user creates a transaction and sends it per redeem link |
|
||||
| TxRepeateRedeemEvent | 42 | the user recreates a redeem link of a still open transaction |
|
||||
| TxCreationEvent | 50 | the user receives a creation transaction for his confirmed contribution |
|
||||
| TxReceiveEvent | 51 | the user receives a transaction from an other user and posts the amount on his account |
|
||||
| TxReceiveRedeemEvent | 52 | the user activates the redeem link and receives the transaction and posts the amount on his account |
|
||||
| ContribCreateEvent | 60 | the user enters his contribution and asks for confirmation |
|
||||
| ContribConfirmEvent | 61 | the user confirms a contribution of an other user (for future multi confirmation from several users) |
|
||||
| | | |
|
||||
|
||||
## EventProtocol - Entity
|
||||
|
||||
The business events will be stored in database in the new table `EventProtocol`. The tabel will have the following attributes:
|
||||
|
||||
| Attribute | Type | Description |
|
||||
| ------------- | --------- | ------------------------------------------------------------------------------------------------ |
|
||||
| id | int | technical unique key (from db sequence) |
|
||||
| type | enum | type of event |
|
||||
| createdAt | timestamp | timestamp the event occurs (not the time of writing) |
|
||||
| userID | string | the user ID, who invokes the event |
|
||||
| XuserID | string | the cross user ID, who is involved in the process like a tx-sender, contrib-receiver, ... |
|
||||
| XcommunityID | string | the cross community ID, which is involved in the process like a tx-sender, contrib-receiver, ... |
|
||||
| transactionID | int | the technical key of the transaction, which triggers the event |
|
||||
| contribID | int | the technical key of the contribution, which triggers the event |
|
||||
| amount | digital | the amount of gradido transferred by transaction, creation or redeem |
|
||||
|
||||
## Event Types
|
||||
|
||||
The following table lists for each event type the mandatory attributes, which have to be initialized at event occurence and to be written in the database event protocol table:
|
||||
|
||||
| EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount |
|
||||
| :-------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: |
|
||||
| BasicEvent | x | x | x | | | | | | |
|
||||
| VisitGradidoEvent | x | x | x | | | | | | |
|
||||
| RegisterEvent | x | x | x | x | | | | | |
|
||||
| RedeemRegisterEvent | x | x | x | x | | | | | |
|
||||
| InActiveAccountEvent | x | x | x | x | | | | | |
|
||||
| SendConfirmEmailEvent | x | x | x | x | | | | | |
|
||||
| ConfirmEmailEvent | x | x | x | x | | | | | |
|
||||
| RegisterEmailKlickTippEvent | x | x | x | x | | | | | |
|
||||
| LoginEvent | x | x | x | x | | | | | |
|
||||
| RedeemLoginEvent | x | x | x | x | | | | | |
|
||||
| ActivateAccountEvent | x | x | x | x | | | | | |
|
||||
| PasswordChangeEvent | x | x | x | x | | | | | |
|
||||
| TxSendEvent | x | x | x | x | x | x | x | | x |
|
||||
| TxSendRedeemEvent | x | x | x | x | x | x | x | | x |
|
||||
| TxRepeateRedeemEvent | x | x | x | x | x | x | x | | x |
|
||||
| TxCreationEvent | x | x | x | x | | | x | | x |
|
||||
| TxReceiveEvent | x | x | x | x | x | x | x | | x |
|
||||
| TxReceiveRedeemEvent | x | x | x | x | x | x | x | | x |
|
||||
| ContribCreateEvent | x | x | x | x | | | | x | |
|
||||
| ContribConfirmEvent | x | x | x | x | x | x | | x | |
|
||||
| | | | | | | | | | |
|
||||
|
||||
## Event creation
|
||||
|
||||
The business logic needs a *general event creation* service/methode, which accepts as input one of the predefined event type objects. An event object have to be initialized with its mandatory attributes before it can be given as input parameters for event creation. The service maps the event object attributes to the database entity and writes a new entry in the `EventProtocol `table.
|
||||
|
||||
At each specific location of the gradido business logic an event creation invocation has to be introduced manually, which matches the corresponding event type - see [EventType-Enum](#EventType-Enum) above.
|
||||
@ -0,0 +1,140 @@
|
||||
# Introduction of Gradido-ID
|
||||
|
||||
## Motivation
|
||||
|
||||
To introduce the Gradido-ID base on the requirement to identify an user account per technical key instead of using an email-address. Such a technical key ensures an exact identification of an user account without giving detailed information for possible missusage.
|
||||
|
||||
Additionally the Gradido-ID allows to administrade any user account data like changing the email address or define several email addresses without any side effects on the identification of the user account.
|
||||
|
||||
## Definition
|
||||
|
||||
The formalized definition of the Gradido-ID can be found in the document [BenutzerVerwaltung#Gradido-ID](../BusinessRequirements/BenutzerVerwaltung#Gradido-ID).
|
||||
|
||||
## Steps of Introduction
|
||||
|
||||
To Introduce the Gradido-ID there are several steps necessary. The first step is to define a proper database schema with additional columns and tables followed by data migration steps to add or initialize the new columns and tables by keeping valid data at all.
|
||||
|
||||
The second step is to decribe all concerning business logic processes, which have to be adapted by introducing the Gradido-ID.
|
||||
|
||||
### Database-Schema
|
||||
|
||||
#### Users-Table
|
||||
|
||||
The entity users has to be changed by adding the following columns.
|
||||
|
||||
| Column | Type | Description |
|
||||
| ------------------------ | ------ | -------------------------------------------------------------------------------------- |
|
||||
| gradidoID | String | technical unique key of the user as UUID (version 4) |
|
||||
| alias | String | a business unique key of the user |
|
||||
| passphraseEncryptionType | int | defines the type of encrypting the passphrase: 1 = email (default), 2 = gradidoID, ... |
|
||||
| emailID | int | technical foreign key to the new entity Contact |
|
||||
|
||||
##### Email vs emailID
|
||||
|
||||
The existing column `email`, will now be changed to the primary email contact, which will be stored as a contact entry in the new `UserContacts` table. It is necessary to decide if the content of the `email `will be changed to the foreign key `emailID `to the contact entry with the email address or if the email itself will be kept as a denormalized and duplicate value in the `users `table.
|
||||
|
||||
The preferred and proper solution will be to add a new column `Users.emailId `as foreign key to the `UsersContact `entry and delete the `Users.email` column after the migration of the email address in the `UsersContact `table.
|
||||
|
||||
#### new UserContacts-Table
|
||||
|
||||
A new entity `UserContacts `is introduced to store several contacts of different types like email, telephone or other kinds of contact addresses.
|
||||
|
||||
| Column | Type | Description |
|
||||
| --------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| id | int | the technical key of a contact entity |
|
||||
| type | int | Defines the type of contact entry as enum: Email, Phone, etc |
|
||||
| usersID | int | Defines the foreign key to the `Users` table |
|
||||
| email | String | defines the address of a contact entry of type Email |
|
||||
| phone | String | defines the address of a contact entry of type Phone |
|
||||
| contactChannels | String | define the contact channel as comma separated list for which this entry is confirmed by the user e.g. main contact (default), infomail, contracting, advertisings, ... |
|
||||
|
||||
### Database-Migration
|
||||
|
||||
After the adaption of the database schema and to keep valid consistent data, there must be several steps of data migration to initialize the new and changed columns and tables.
|
||||
|
||||
#### Initialize GradidoID
|
||||
|
||||
In a one-time migration create for each entry of the `Users `tabel an unique UUID (version4).
|
||||
|
||||
#### Primary Email Contact
|
||||
|
||||
In a one-time migration read for each entry of the `Users `table the `Users.id` and `Users.email` and create for it a new entry in the `UsersContact `table, by initializing the contact-values with:
|
||||
|
||||
* id = new technical key
|
||||
* type = Enum-Email
|
||||
* userID = `Users.id`
|
||||
* email = `Users.email`
|
||||
* phone = null
|
||||
* usedChannel = Enum-"main contact"
|
||||
|
||||
and update the `Users `entry with `Users.emailId = UsersContact.Id` and `Users.passphraseEncryptionType = 1`
|
||||
|
||||
After this one-time migration the column `Users.email` can be deleted.
|
||||
|
||||
### Adaption of BusinessLogic
|
||||
|
||||
The following logic or business processes has to be adapted for introducing the Gradido-ID
|
||||
|
||||
#### Read-Write Access of Users-Table especially Email
|
||||
|
||||
The ORM mapping has to be adapted to the changed and new database schema.
|
||||
|
||||
#### Registration Process
|
||||
|
||||
The logic of the registration process has to be adapted by
|
||||
|
||||
* initializing the `Users.userID` with a unique UUID
|
||||
* creating a new `UsersContact `entry with the given email address and *maincontact* as `usedChannel `
|
||||
* set `emailID `in the `Users `table as foreign key to the new `UsersContact `entry
|
||||
* set `Users.passphraseEncrpytionType = 2` and encrypt the passphrase with the `Users.userID` instead of the `UsersContact.email`
|
||||
|
||||
#### Login Process
|
||||
|
||||
The logic of the login process has to be adapted by
|
||||
|
||||
* search the users data by reading the `Users `and the `UsersContact` table with the email (or alias as soon as the user can maintain his profil with an alias) as input
|
||||
* depending on the `Users.passphraseEncryptionType` decrypt the stored password
|
||||
* = 1 : with the email
|
||||
* = 2 : with the userID
|
||||
|
||||
#### Password En/Decryption
|
||||
|
||||
The logic of the password en/decryption has to be adapted by encapsulate the logic to be controlled with an input parameter. The input parameter can be the email or the userID.
|
||||
|
||||
#### Change Password Process
|
||||
|
||||
The logic of change password has to be adapted by
|
||||
|
||||
* if the `Users.passphraseEncryptionType` = 1, then
|
||||
|
||||
* read the users email address from the `UsersContact `table
|
||||
* give the email address as input for the password decryption of the existing password
|
||||
* use the `Users.userID` as input for the password encryption fo the new password
|
||||
* change the `Users.passphraseEnrycptionType` to the new value =2
|
||||
* if the `Users.passphraseEncryptionType` = 2, then
|
||||
|
||||
* give the `Users.userID` as input for the password decryption of the existing password
|
||||
* use the `Users.userID` as input for the password encryption fo the new password
|
||||
|
||||
#### Search- and Access Logic
|
||||
|
||||
A new logic has to be introduced to search the user identity per different input values. That means searching the user data must be possible by
|
||||
|
||||
* searching per email (only with maincontact as contactchannel)
|
||||
* searching per userID
|
||||
* searching per alias
|
||||
|
||||
#### Identity-Mapping
|
||||
|
||||
A new mapping logic will be necessary to allow using unmigrated APIs like GDT-servers api. So it must be possible to give this identity-mapping logic the following input to get the respective output:
|
||||
|
||||
* email -> userID
|
||||
* email -> alias
|
||||
* userID -> email
|
||||
* userID -> alias
|
||||
* alias -> email
|
||||
* alias -> userID
|
||||
|
||||
#### GDT-Access
|
||||
|
||||
To use the GDT-servers api the used identifier for GDT has to be switch from email to userID.
|
||||
@ -50,6 +50,7 @@ module.exports = {
|
||||
'/time./',
|
||||
'/decay.types./',
|
||||
'settings.password.resend_subtitle',
|
||||
'settings.password.reset',
|
||||
'settings.password.reset-password.text',
|
||||
'settings.password.set',
|
||||
'settings.password.set-password.text',
|
||||
|
||||
@ -45,7 +45,6 @@
|
||||
"jest": "^26.6.3",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-environment-jsdom-sixteen": "^2.0.0",
|
||||
"particles-bg-vue": "1.2.3",
|
||||
"portal-vue": "^2.1.7",
|
||||
"prettier": "^2.2.1",
|
||||
"qrcanvas-vue": "2.1.1",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 25 KiB |
BIN
frontend/public/img/template/Foto_01_2400_small.jpg
Normal file
BIN
frontend/public/img/template/Foto_01_2400_small.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 791 KiB |
BIN
frontend/public/img/template/Foto_02_2400_small.jpg
Normal file
BIN
frontend/public/img/template/Foto_02_2400_small.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 504 KiB |
BIN
frontend/public/img/template/Foto_03_2400_small.jpg
Normal file
BIN
frontend/public/img/template/Foto_03_2400_small.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 353 KiB |
BIN
frontend/public/img/template/Foto_04_2400_small.jpg
Normal file
BIN
frontend/public/img/template/Foto_04_2400_small.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 350 KiB |
61
frontend/src/App.spec.js
Normal file
61
frontend/src/App.spec.js
Normal file
@ -0,0 +1,61 @@
|
||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import App from './App'
|
||||
|
||||
const localVue = global.localVue
|
||||
const mockStoreCommit = jest.fn()
|
||||
|
||||
const stubs = {
|
||||
RouterLink: RouterLinkStub,
|
||||
RouterView: true,
|
||||
}
|
||||
|
||||
describe('App', () => {
|
||||
const mocks = {
|
||||
$i18n: {
|
||||
locale: 'en',
|
||||
},
|
||||
$t: jest.fn((t) => t),
|
||||
$store: {
|
||||
commit: mockStoreCommit,
|
||||
state: {
|
||||
token: null,
|
||||
},
|
||||
},
|
||||
$route: {
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
let wrapper
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(App, { localVue, mocks, stubs })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders the App', () => {
|
||||
expect(wrapper.find('#app').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a component AuthLayout', () => {
|
||||
expect(wrapper.findComponent({ name: 'AuthLayout' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('route requires authorization', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$route.meta.requiresAuth = true
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a component DashboardLayout', () => {
|
||||
expect(wrapper.findComponent({ name: 'DashboardLayout' }).exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,47 +1,49 @@
|
||||
<template>
|
||||
<div id="app" class="font-sans text-gray-800">
|
||||
<div>
|
||||
<particles-bg v-if="$store.state.coinanimation" type="custom" :config="config" :bg="true" />
|
||||
<component :is="$route.meta.requiresAuth ? 'DashboardLayout' : 'AuthLayoutGDD'" />
|
||||
</div>
|
||||
<div id="app" class="h-100">
|
||||
<component :is="$route.meta.requiresAuth ? 'DashboardLayout' : 'AuthLayout'" />
|
||||
<div class="goldrand position-fixed w-100 fixed-bottom zindex1000"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ParticlesBg } from 'particles-bg-vue'
|
||||
import icon from './icon.js'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
|
||||
import AuthLayoutGDD from '@/layouts/AuthLayout_gdd.vue'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout.vue'
|
||||
import AuthLayout from '@/layouts/AuthLayout.vue'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
name: 'App',
|
||||
components: {
|
||||
ParticlesBg,
|
||||
DashboardLayout,
|
||||
AuthLayoutGDD,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
config: {
|
||||
num: [1, 7],
|
||||
rps: 15,
|
||||
radius: [5, 50],
|
||||
life: [6.5, 15],
|
||||
v: [1, 1],
|
||||
tha: [-40, 40],
|
||||
body: icon,
|
||||
alpha: [0.6, 0],
|
||||
scale: [0.1, 0.4],
|
||||
position: 'all',
|
||||
cross: 'dead',
|
||||
random: 2,
|
||||
},
|
||||
}
|
||||
AuthLayout,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
@font-face {
|
||||
font-family: 'WorkSans', sans-serif !important;
|
||||
src: url(./assets/scss/fonts/WorkSans-VariableFont_wght.ttf) format('truetype');
|
||||
}
|
||||
#app {
|
||||
min-width: 360px;
|
||||
font-size: 1rem;
|
||||
font-family: 'WorkSans', sans-serif !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
#app {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
.goldrand {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(197, 141, 56, 1) 6%,
|
||||
rgba(243, 205, 124, 1) 30%,
|
||||
rgba(219, 176, 86, 1) 54%,
|
||||
rgba(238, 192, 95, 1) 63%,
|
||||
rgba(204, 157, 61, 1) 88%
|
||||
);
|
||||
height: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Body
|
||||
|
||||
$body-bg: #f8f9fe !default;
|
||||
$body-bg: #fff !default;
|
||||
$body-color: $gray-700 !default;
|
||||
|
||||
@ -16,7 +16,9 @@ $custom-control-indicator-active-bg: $component-active-bg !default;
|
||||
$custom-control-indicator-active-border-color: $component-active-border-color !default;
|
||||
$custom-control-indicator-active-box-shadow: $custom-control-indicator-box-shadow !default;
|
||||
$custom-control-indicator-checked-color: $component-active-color !default;
|
||||
$custom-control-indicator-checked-bg: $component-active-bg !default;
|
||||
|
||||
// $custom-control-indicator-checked-bg: $component-active-bg !default;
|
||||
$custom-control-indicator-checked-bg: #047006 !default;
|
||||
$custom-control-indicator-checked-border-color: $component-active-border-color !default;
|
||||
$custom-control-indicator-checked-box-shadow: $custom-control-indicator-box-shadow !default;
|
||||
|
||||
@ -24,6 +26,8 @@ $custom-control-indicator-checked-box-shadow: $custom-control-indicator-box-shad
|
||||
$custom-control-indicator-checked-disabled-bg: theme-color("primary") !default;
|
||||
$custom-control-indicator-disabled-bg: $gray-200 !default;
|
||||
$custom-control-label-disabled-color: $gray-600 !default;
|
||||
$custom-checkbox-indicator-border-radius: $border-radius-sm !default;
|
||||
|
||||
// $custom-checkbox-indicator-border-radius: $border-radius-sm !default;
|
||||
$custom-checkbox-indicator-border-radius: 50px !default;
|
||||
|
||||
// $custom-checkbox-indicator-icon-checked: str-replace(url("data:image/svg+xml !default;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"), "#", "%23") !default;
|
||||
|
||||
@ -4,7 +4,7 @@ $grid-breakpoints: (
|
||||
xs: 0,
|
||||
sm: 576px,
|
||||
md: 768px,
|
||||
lg: 992px,
|
||||
lg: 1025px,
|
||||
xl: 1200px
|
||||
);
|
||||
|
||||
|
||||
@ -1,4 +1,13 @@
|
||||
// Body
|
||||
// Sections
|
||||
|
||||
$body-bg: #f8f9fe !default;
|
||||
$body-color: $gray-700 !default;
|
||||
// $section-colors: () !default;
|
||||
// $section-colors: map-merge(
|
||||
// (
|
||||
// "primary": $body-bg,
|
||||
// "secondary": $secondary,
|
||||
// "light": $gray-400,
|
||||
// "dark": $dark,
|
||||
// "darker": $darker
|
||||
// ),
|
||||
// $section-colors
|
||||
// );
|
||||
|
||||
BIN
frontend/src/assets/scss/fonts/WorkSans-VariableFont_wght.ttf
Normal file
BIN
frontend/src/assets/scss/fonts/WorkSans-VariableFont_wght.ttf
Normal file
Binary file not shown.
183
frontend/src/assets/scss/gradido-template.scss
Normal file
183
frontend/src/assets/scss/gradido-template.scss
Normal file
@ -0,0 +1,183 @@
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c-grey {
|
||||
color: #383838 !important;
|
||||
}
|
||||
|
||||
.c-blau {
|
||||
color: #0e79bc !important;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
a,
|
||||
.navbar-light .navbar-nav .nav-link {
|
||||
color: #047006;
|
||||
}
|
||||
|
||||
.navbar-light .navbar-nav .nav-link.active {
|
||||
color: rgb(35 121 188 / 90%);
|
||||
}
|
||||
|
||||
.text-gradido {
|
||||
color: rgb(249 205 105 / 100%);
|
||||
}
|
||||
|
||||
.gradient-gradido {
|
||||
background-image: linear-gradient(146deg, rgb(220 167 44) 50%, rgb(197 141 56 / 100%) 100%);
|
||||
}
|
||||
|
||||
/* Button */
|
||||
.btn {
|
||||
border-radius: 25px;
|
||||
padding-right: 50px;
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
.btn-gradido {
|
||||
background-image: linear-gradient(146deg, rgb(220 167 44) 50%, rgb(197 141 56 / 100%) 100%);
|
||||
background-size: auto;
|
||||
background-position: 0% 0%;
|
||||
background-repeat: repeat;
|
||||
border-style: none;
|
||||
box-shadow: 10px 10px 50px 10px rgb(56 56 56 / 31%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-gradido:hover {
|
||||
color: #212529;
|
||||
}
|
||||
|
||||
.btn-gradido:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.btn-outline-gradido {
|
||||
color: rgb(140 121 88);
|
||||
border: 1px solid #f5b805;
|
||||
}
|
||||
|
||||
.form-control,
|
||||
.custom-select {
|
||||
border-radius: 17px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.rounded-right {
|
||||
border-top-right-radius: 17px !important;
|
||||
border-bottom-right-radius: 17px !important;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: #d4edda;
|
||||
border-color: #c3e6cb;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
color: #721c24;
|
||||
background-color: #f8d7da;
|
||||
border-color: #f5c6cb;
|
||||
}
|
||||
|
||||
.b-toast-danger .toast .toast-header {
|
||||
color: #721c24;
|
||||
background-color: rgb(248 215 218 / 85%);
|
||||
border-bottom-color: rgb(245 198 203 / 85%);
|
||||
}
|
||||
|
||||
.b-toast-danger .toast .toast-body {
|
||||
background-color: rgb(252 237 238 / 85%);
|
||||
border-color: rgb(245 198 203 / 85%);
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.b-toast-success .toast .toast-header {
|
||||
color: #155724;
|
||||
background-color: rgb(212 237 218 / 58%);
|
||||
border-bottom-color: rgb(195 230 203 / 85%);
|
||||
}
|
||||
|
||||
.b-toast-success .toast .toast-body {
|
||||
color: #155724;
|
||||
background-color: rgb(212 237 218 / 85%);
|
||||
border-bottom-color: rgb(195 230 203 / 85%);
|
||||
}
|
||||
|
||||
// .btn-primary pim {
|
||||
.btn-primary {
|
||||
background-color: #5a7b02;
|
||||
border-color: #5e72e4;
|
||||
}
|
||||
|
||||
.gradido-font-large {
|
||||
font-size: large;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.font2em {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.zindex10 {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.zindex100 {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.zindex1000 {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.zindex10000 {
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.zindex100000 {
|
||||
z-index: 100000;
|
||||
}
|
||||
|
||||
.gradido-global-color-blue {
|
||||
color: #0e79bc;
|
||||
}
|
||||
|
||||
.gradido-global-color-accent {
|
||||
color: #047006;
|
||||
}
|
||||
|
||||
.gradido-global-color-gray {
|
||||
color: #858383;
|
||||
}
|
||||
|
||||
.gradido-custom-background {
|
||||
background-color: #ebebeba3 !important;
|
||||
border-radius: 25pt;
|
||||
}
|
||||
|
||||
.gradido-width-300 {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.gradido-width-96 {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
.gradido-no-border-radius {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.gradido-no-border {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.gradido-font-15rem {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
@ -51,165 +51,4 @@
|
||||
|
||||
// Bootstrap-vue (2.21.1) scss
|
||||
@import "~bootstrap-vue/src/index";
|
||||
|
||||
.alert-success {
|
||||
color: #155724;
|
||||
background-color: #d4edda;
|
||||
border-color: #c3e6cb;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
color: #721c24;
|
||||
background-color: #f8d7da;
|
||||
border-color: #f5c6cb;
|
||||
}
|
||||
|
||||
.b-toast-danger .toast .toast-header {
|
||||
color: #721c24;
|
||||
background-color: rgb(248 215 218 / 85%);
|
||||
border-bottom-color: rgb(245 198 203 / 85%);
|
||||
}
|
||||
|
||||
.b-toast-danger .toast .toast-body {
|
||||
background-color: rgb(252 237 238 / 85%);
|
||||
border-color: rgb(245 198 203 / 85%);
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.b-toast-success .toast .toast-header {
|
||||
color: #155724;
|
||||
background-color: rgb(212 237 218 / 58%);
|
||||
border-bottom-color: rgb(195 230 203 / 85%);
|
||||
}
|
||||
|
||||
.b-toast-success .toast .toast-body {
|
||||
color: #155724;
|
||||
background-color: rgb(212 237 218 / 85%);
|
||||
border-bottom-color: rgb(195 230 203 / 85%);
|
||||
}
|
||||
|
||||
// .btn-primary pim {
|
||||
.btn-primary {
|
||||
background-color: #5a7b02;
|
||||
border-color: #5e72e4;
|
||||
}
|
||||
|
||||
.gradido-font-large {
|
||||
font-size: large;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
a,
|
||||
.copyright {
|
||||
color: #5a7b02;
|
||||
}
|
||||
|
||||
.font12em {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.font2em {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.gradido-global-color-text {
|
||||
color: #3d443b;
|
||||
}
|
||||
|
||||
.gradido-global-color-accent {
|
||||
color: #047006;
|
||||
}
|
||||
|
||||
.gradido-global-color-6e0a9c9e {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.gradido-global-color-2d0fb154 {
|
||||
color: #047006;
|
||||
}
|
||||
|
||||
.gradido-global-color-16efe88c {
|
||||
color: #7ebc55;
|
||||
}
|
||||
|
||||
.gradido-global-color-1939326 {
|
||||
color: #f6fff6;
|
||||
}
|
||||
|
||||
.gradido-global-color-9d79fc1 {
|
||||
color: #047006;
|
||||
}
|
||||
|
||||
.gradido-global-color-6347f4d {
|
||||
color: #5a7b02;
|
||||
}
|
||||
|
||||
.gradido-global-color-4fbc19a {
|
||||
color: #014034;
|
||||
}
|
||||
|
||||
.gradido-global-color-d341874 {
|
||||
color: #b6d939;
|
||||
}
|
||||
|
||||
.gradido-global-color-619d338 {
|
||||
color: #8ebfb1;
|
||||
}
|
||||
|
||||
.gradido-global-color-44819a9 {
|
||||
color: #026873;
|
||||
}
|
||||
|
||||
.gradido-global-color-gray {
|
||||
color: #858383;
|
||||
}
|
||||
|
||||
.gradido-custom-background {
|
||||
background-color: #ebebeba3 !important;
|
||||
}
|
||||
|
||||
.gradido-shadow-inset {
|
||||
box-shadow: inset 0.3em rgba(241 187 187 / 100%);
|
||||
}
|
||||
|
||||
.gradido-max-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gradido-width-300 {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.gradido-absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.gradido-width-95-absolute {
|
||||
width: 95%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.gradido-width-96-absolute {
|
||||
width: 96%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.gradido-no-border-radius {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.gradido-no-border {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.gradido-background-f1 {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.gradido-background-white {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.gradido-font-15rem {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
@import "gradido-template";
|
||||
|
||||
29
frontend/src/components/Auth/Carousel.vue
Normal file
29
frontend/src/components/Auth/Carousel.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-carousel :interval="3000">
|
||||
<b-carousel-slide img-src="/img/template/Foto_01_2400_small.jpg"></b-carousel-slide>
|
||||
<b-carousel-slide img-src="/img/template/Foto_02_2400_small.jpg"></b-carousel-slide>
|
||||
<b-carousel-slide img-src="/img/template/Foto_03_2400_small.jpg"></b-carousel-slide>
|
||||
<b-carousel-slide img-src="/img/template/Foto_04_2400_small.jpg"></b-carousel-slide>
|
||||
</b-carousel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AuthCarousel',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.carousel {
|
||||
position: relative;
|
||||
height: 110%;
|
||||
top: -16px;
|
||||
}
|
||||
|
||||
.carousel-inner {
|
||||
height: 100%;
|
||||
border-radius: 0% 49% 49% 0% / 0% 51% 49% 0%;
|
||||
}
|
||||
</style>
|
||||
53
frontend/src/components/Auth/Footer.vue
Normal file
53
frontend/src/components/Auth/Footer.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<footer class="footer bg-transparent">
|
||||
<b-row class="mt-lg-7 mt-md-6 mt-4">
|
||||
<b-col class="col-12 col-md-12 col-lg-6">
|
||||
<div
|
||||
class="d-flex justify-content-center justify-content-md-center justify-content-lg-start ml-3"
|
||||
>
|
||||
<b-nav class="nav-footer">
|
||||
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/impressum/`" target="_blank">
|
||||
{{ $t('footer.imprint') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/datenschutz/`" target="_blank">
|
||||
{{ $t('footer.privacy_policy') }}
|
||||
</b-nav-item>
|
||||
</b-nav>
|
||||
</div>
|
||||
</b-col>
|
||||
<b-col class="col-12 col-md-12 col-lg-6 mt-4 mb-4 mt-lg-0 mb-lg-0">
|
||||
<div class="text-center ml-3 ml-lg-0 text-lg-right">
|
||||
{{ $t('followUs') }}
|
||||
<b-icon-facebook class="ml-3 mr-3" font-scale="1"></b-icon-facebook>
|
||||
<b-icon-twitter class="mr-3" font-scale="1"></b-icon-twitter>
|
||||
<b-icon-youtube class="mr-3" font-scale="1"></b-icon-youtube>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
class="bi bi-telegram"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.287 5.906c-.778.324-2.334.994-4.666 2.01-.378.15-.577.298-.595.442-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294.26.006.549-.1.868-.32 2.179-1.471 3.304-2.214 3.374-2.23.05-.012.12-.026.166.016.047.041.042.12.037.141-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8.154 8.154 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629.093.06.183.125.27.187.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.426 1.426 0 0 0-.013-.315.337.337 0 0 0-.114-.217.526.526 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AuthFooter',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.bi-telegram {
|
||||
margin-top: -5px;
|
||||
}
|
||||
</style>
|
||||
124
frontend/src/components/Auth/MobileStart.vue
Normal file
124
frontend/src/components/Auth/MobileStart.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div
|
||||
class="mobil-start-box position-fixed h-100 d-inline d-sm-inline d-md-inline d-lg-none zindex1000"
|
||||
>
|
||||
<div class="position-absolute h1 text-white zindex1000 w-100 text-center mt-8">
|
||||
{{ $t('auth.left.gratitude') }}
|
||||
</div>
|
||||
<div class="position-absolute h2 text-white zindex1000 w-100 text-center mt-9">
|
||||
{{ $t('auth.left.newCurrency') }}
|
||||
</div>
|
||||
<img
|
||||
src="img/template/Blaetter.png"
|
||||
class="sheet-img position-absolute d-block d-lg-none zindex1000"
|
||||
/>
|
||||
<b-img
|
||||
id="img0"
|
||||
class="position-absolute zindex1000"
|
||||
src="img/template/logo-header.png"
|
||||
alt="start background image"
|
||||
></b-img>
|
||||
<b-img
|
||||
fluid
|
||||
id="img1"
|
||||
class="position-absolute h-100 w-100 overflow-hidden zindex100"
|
||||
src="img/template/gold_03.png"
|
||||
alt="start background image"
|
||||
></b-img>
|
||||
<b-img
|
||||
id="img2"
|
||||
class="position-absolute zindex100"
|
||||
src="img/template/gradido_background_header.png"
|
||||
alt="start background image"
|
||||
></b-img>
|
||||
<b-img
|
||||
id="img3"
|
||||
class="position-relative zindex10"
|
||||
src="img/template/Foto_01.jpg"
|
||||
alt="start background image"
|
||||
></b-img>
|
||||
<div class="mobil-start-box-text position-fixed w-100 text-center zindex1000">
|
||||
<b-button variant="gradido" to="/register" @click="$emit('is-mobile-start', false)">
|
||||
{{ $t('signup') }}
|
||||
</b-button>
|
||||
<div class="mt-3 h3 text-white">
|
||||
{{ $t('auth.left.hasAccount') }}
|
||||
<b-link
|
||||
to="/login"
|
||||
class="text-gradido gradido-global-color-blue"
|
||||
@click="$emit('is-mobile-start', false)"
|
||||
>
|
||||
{{ $t('auth.left.hereLogin') }}
|
||||
</b-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AuthMobileStart',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.mobil-start-box-text {
|
||||
bottom: 65px;
|
||||
}
|
||||
|
||||
/* logo */
|
||||
.mobil-start-box #img0 {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
/* background logo */
|
||||
.mobil-start-box #img2 {
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
/* background maske */
|
||||
@media screen and (max-width: 1024px) {
|
||||
.mobil-start-box #img3 {
|
||||
width: 100%;
|
||||
top: -100px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 991px) {
|
||||
.mobil-start-box #img3 {
|
||||
width: 100%;
|
||||
top: -148px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 740px) {
|
||||
.mobil-start-box #img3 {
|
||||
width: 115%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
.mobil-start-box #img3 {
|
||||
width: 115%;
|
||||
top: 66px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.mobil-start-box #img3 {
|
||||
width: 160%;
|
||||
left: -71px;
|
||||
top: 35px;
|
||||
min-width: 360px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 310px) {
|
||||
.mobil-start-box #img3 {
|
||||
width: 145%;
|
||||
left: -94px;
|
||||
top: 24px;
|
||||
min-width: 360px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
73
frontend/src/components/Auth/Navbar.vue
Normal file
73
frontend/src/components/Auth/Navbar.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div class="auth-header position-sticky">
|
||||
<b-navbar toggleable="lg" class="pr-4">
|
||||
<b-navbar-brand>
|
||||
<b-img
|
||||
class="imgLogo position-absolute ml--3 mt--3 p-2 zindex1000"
|
||||
:src="logo"
|
||||
width="200"
|
||||
alt="..."
|
||||
/>
|
||||
<b-img
|
||||
class="imgLogoBack mt--3 ml--3"
|
||||
src="img/template/gradido_background_header.png"
|
||||
width="230"
|
||||
alt="start background image"
|
||||
></b-img>
|
||||
</b-navbar-brand>
|
||||
<b-img class="sheet-img position-absolute d-block d-lg-none zindex1000" :src="sheet"></b-img>
|
||||
<b-navbar-toggle target="nav-collapse" class="zindex1000"></b-navbar-toggle>
|
||||
|
||||
<b-collapse id="nav-collapse" is-nav class="mt-5 mt-lg-0">
|
||||
<b-navbar-nav class="ml-auto" right>
|
||||
<b-nav-item href="https://gradido.net/de/" target="_blank">
|
||||
{{ $t('auth.navbar.aboutGradido') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/register" class="authNavbar ml-lg-5">{{ $t('signup') }}</b-nav-item>
|
||||
<span class="d-none d-lg-block mt-1">{{ $t('math.pipe') }}</span>
|
||||
<b-nav-item to="/login" class="authNavbar">{{ $t('signin') }}</b-nav-item>
|
||||
</b-navbar-nav>
|
||||
</b-collapse>
|
||||
</b-navbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AuthNavbar',
|
||||
data() {
|
||||
return {
|
||||
logo: 'img/brand/green.png',
|
||||
sheet: 'img/template/Blaetter.png',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.authNavbar > .nav-link {
|
||||
color: #383838 !important;
|
||||
}
|
||||
|
||||
.authNavbar > .router-link-exact-active {
|
||||
color: #0e79bc !important;
|
||||
}
|
||||
|
||||
.auth-header {
|
||||
font-family: 'Open Sans', sans-serif !important;
|
||||
}
|
||||
|
||||
.sheet-img {
|
||||
top: -11px;
|
||||
right: 7%;
|
||||
max-width: 64%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.sheet-img {
|
||||
top: -15px;
|
||||
right: 0%;
|
||||
max-width: 61%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
17
frontend/src/components/Auth/NavbarSmall.vue
Normal file
17
frontend/src/components/Auth/NavbarSmall.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div class="navbar-small">
|
||||
<b-navbar>
|
||||
<b-navbar-nav>
|
||||
<b-nav-item to="/register" class="authNavbar">{{ $t('signup') }}</b-nav-item>
|
||||
<span class="mt-1">{{ $t('math.pipe') }}</span>
|
||||
<b-nav-item to="/login" class="authNavbar">{{ $t('signin') }}</b-nav-item>
|
||||
</b-navbar-nav>
|
||||
</b-navbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NavbarSmall',
|
||||
}
|
||||
</script>
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="collapse-links-list">
|
||||
<div class="d-flex">
|
||||
<div class="gradido-max-width">
|
||||
<div class="w-100">
|
||||
<hr />
|
||||
<div>
|
||||
<transaction-link
|
||||
|
||||
@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils'
|
||||
import TransactionForm from './TransactionForm'
|
||||
import flushPromises from 'flush-promises'
|
||||
import { SEND_TYPES } from '@/pages/Send.vue'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout.vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
|
||||
75
frontend/src/components/LanguageSwitch2.vue
Normal file
75
frontend/src/components/LanguageSwitch2.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="language-switch">
|
||||
<span
|
||||
v-for="(lang, index) in locales"
|
||||
@click.prevent="saveLocale(lang.code)"
|
||||
:key="lang.code"
|
||||
class="pointer pr-3"
|
||||
:class="$store.state.language === lang.code ? 'c-blau' : 'c-grey'"
|
||||
>
|
||||
{{ lang.name }}
|
||||
<span class="ml-3">{{ locales.length - 1 > index ? $t('math.pipe') : '' }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import locales from '@/locales/'
|
||||
import { updateUserInfos } from '@/graphql/mutations'
|
||||
|
||||
export default {
|
||||
name: 'LanguageSwitch',
|
||||
data() {
|
||||
return {
|
||||
locales: locales,
|
||||
currentLanguage: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setLocale(locale) {
|
||||
this.$store.commit('language', locale)
|
||||
this.currentLanguage = this.getLocaleObject(locale)
|
||||
},
|
||||
async saveLocale(locale) {
|
||||
if (this.$i18n.locale === locale) return
|
||||
this.setLocale(locale)
|
||||
if (this.$store.state.email) {
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: updateUserInfos,
|
||||
variables: {
|
||||
locale: locale,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
// toast success message
|
||||
})
|
||||
.catch(() => {
|
||||
// toast error message
|
||||
})
|
||||
}
|
||||
},
|
||||
getLocaleObject(code) {
|
||||
return this.locales.find((l) => l.code === code)
|
||||
},
|
||||
getNavigatorLanguage() {
|
||||
const lang = navigator.language
|
||||
if (lang) return lang.split('-')[0]
|
||||
return lang
|
||||
},
|
||||
setCurrentLanguage() {
|
||||
let locale = this.$store.state.language || this.getNavigatorLanguage() || 'en'
|
||||
let object = this.getLocaleObject(locale)
|
||||
if (!object) {
|
||||
locale = 'en'
|
||||
object = this.getLocaleObject(locale)
|
||||
}
|
||||
this.setLocale(locale)
|
||||
this.currentLanguage = object
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.setCurrentLanguage()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="component-navbar gradido-background-white">
|
||||
<div class="component-navbar">
|
||||
<b-navbar toggleable="lg" type="light" variant="faded">
|
||||
<div class="navbar-brand">
|
||||
<b-navbar-nav @click="$emit('set-visible', false)">
|
||||
|
||||
@ -3,12 +3,12 @@
|
||||
<div class="list-group">
|
||||
<div class="list-group-item gdt-transaction-list-item" v-b-toggle="collapseId">
|
||||
<!-- icon -->
|
||||
<div class="text-right gradido-absolute">
|
||||
<div class="text-right position-absolute">
|
||||
<b-icon :icon="getLinesByType.icon" :class="getLinesByType.iconclasses"></b-icon>
|
||||
</div>
|
||||
|
||||
<!-- collaps Button -->
|
||||
<div class="text-right gradido-width-96-absolute">
|
||||
<div class="text-right gradido-width-96 position-absolute">
|
||||
<b-icon
|
||||
:icon="getCollapseState(id) ? 'caret-up-square' : 'caret-down-square'"
|
||||
:class="getCollapseState(id) ? 'text-black' : 'text-muted'"
|
||||
|
||||
79
frontend/src/layouts/AuthLayout.spec.js
Normal file
79
frontend/src/layouts/AuthLayout.spec.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import AuthLayout from './AuthLayout'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('AuthLayout', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
$i18n: {
|
||||
locale: 'en',
|
||||
},
|
||||
$t: jest.fn((t) => t),
|
||||
$store: {
|
||||
state: {},
|
||||
commit: jest.fn(),
|
||||
},
|
||||
$route: {
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const stubs = {
|
||||
RouterLink: RouterLinkStub,
|
||||
RouterView: true,
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(AuthLayout, { localVue, mocks, stubs })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
describe('Mobile Version Start', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.vm.mobileStart = true
|
||||
})
|
||||
|
||||
it('has Component AuthMobileStart', () => {
|
||||
expect(wrapper.findComponent({ name: 'AuthMobileStart' }).exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Desktop Version Start', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.vm.mobileStart = false
|
||||
})
|
||||
|
||||
it('has Component AuthNavbar', () => {
|
||||
expect(wrapper.findComponent({ name: 'AuthNavbar' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has Component AuthCarousel', () => {
|
||||
expect(wrapper.findComponent({ name: 'AuthCarousel' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has Component AuthFooter', () => {
|
||||
expect(wrapper.findComponent({ name: 'AuthFooter' }).exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has no sidebar', () => {
|
||||
expect(wrapper.find('nav#sidenav-main').exists()).not.toBeTruthy()
|
||||
})
|
||||
|
||||
it('has LanguageSwitch', () => {
|
||||
expect(wrapper.findComponent({ name: 'LanguageSwitch' }).exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
test('test size in setTextSize ', () => {
|
||||
wrapper.vm.setTextSize('85')
|
||||
expect(wrapper.vm.$refs.pageFontSize.style.fontSize).toBe('85rem')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
178
frontend/src/layouts/AuthLayout.vue
Normal file
178
frontend/src/layouts/AuthLayout.vue
Normal file
@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="auth-template">
|
||||
<mobile-start
|
||||
v-if="mobileStart"
|
||||
class="d-inline d-lg-none zindex10000"
|
||||
@is-mobile-start="setMobileStart"
|
||||
/>
|
||||
<div class="h-100 align-middle">
|
||||
<navbar class="zindex10" />
|
||||
|
||||
<div class="left-content-box position-fixed d-none d-lg-block">
|
||||
<div class="bg-img-box position-absolute w-100">
|
||||
<carousel class="carousel" />
|
||||
</div>
|
||||
<div class="bg-txt-box position-relative d-none d-lg-block text-center align-self-center">
|
||||
<div class="h0 text-white">{{ $t('auth.left.gratitude') }}</div>
|
||||
<div class="h1 text-white">{{ $t('auth.left.newCurrency') }}</div>
|
||||
<div class="h2 text-white">{{ $t('auth.left.oneAnotherNature') }}</div>
|
||||
<b-button variant="gradido">{{ $t('auth.left.learnMore') }}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
<b-row class="justify-content-md-center">
|
||||
<b-col sm="12" md="8" offset-lg="6" lg="6" class="zindex1000">
|
||||
<div class="right-content-box ml-3 ml-sm-4 mr-3 mr-sm-4">
|
||||
<b-row class="d-none d-md-block d-lg-none">
|
||||
<b-col class="mb--4 d-flex justify-content-end">
|
||||
<navbar-small />
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="mt-5 pl-2 pl-md-0 pl-lg-0">
|
||||
<b-col cols="9">
|
||||
<div class="h1 mb--2">{{ $t('welcome') }}</div>
|
||||
<div class="h1 mb-0">{{ $t('WelcomeBy', { name: communityName }) }}</div>
|
||||
<div class="mb-0">{{ $t('1000thanks') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="3" class="text-right d-none d-sm-none d-md-inline">
|
||||
<b-avatar src="img/brand/gradido_coin●.png" size="6rem"></b-avatar>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-card no-body ref="pageFontSize" class="border-0 mt-4 gradido-custom-background">
|
||||
<b-row class="p-4">
|
||||
<b-col cols="10">
|
||||
<language-switch class="ml-3" />
|
||||
</b-col>
|
||||
<b-col cols="2" class="text-right">
|
||||
<div id="popover-target-1" class="pointer">
|
||||
<b-img src="img/svg/type.svg" width="19" class="svgType"></b-img>
|
||||
</div>
|
||||
<b-popover
|
||||
target="popover-target-1"
|
||||
triggers="click"
|
||||
placement="top"
|
||||
variant="dark"
|
||||
>
|
||||
<div class="text-light">
|
||||
<span class="pointer" @click="setTextSize(0.85)">{{ $t('85') }}</span>
|
||||
{{ $t('math.pipe') }}
|
||||
<span class="pointer" @click="setTextSize(1)">{{ $t('100') }}</span>
|
||||
{{ $t('math.pipe') }}
|
||||
<span class="pointer" @click="setTextSize(1.25)">{{ $t('125') }}</span>
|
||||
</div>
|
||||
</b-popover>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="d-inline d-sm-inline d-md-none d-lg-none mb-3">
|
||||
<b-col class="text-center">
|
||||
<b-avatar src="img/brand/gradido_coin●.png" size="6rem"></b-avatar>
|
||||
<b-row>
|
||||
<b-col class="zindex1000 d-flex justify-content-center">
|
||||
<navbar-small />
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-card-body class="">
|
||||
<router-view></router-view>
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
</div>
|
||||
<auth-footer v-if="!$route.meta.hideFooter" class="pr-5"></auth-footer>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- <auth-layout-gdd />-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MobileStart from '@/components/Auth/MobileStart.vue'
|
||||
import Navbar from '@/components/Auth/Navbar.vue'
|
||||
import NavbarSmall from '@/components/Auth/NavbarSmall.vue'
|
||||
import Carousel from '@/components/Auth/Carousel.vue'
|
||||
import LanguageSwitch from '@/components/LanguageSwitch2'
|
||||
import AuthFooter from '@/components/Auth/Footer.vue'
|
||||
import CONFIG from '@/config'
|
||||
|
||||
export default {
|
||||
name: 'AuthLayout',
|
||||
components: {
|
||||
MobileStart,
|
||||
Navbar,
|
||||
NavbarSmall,
|
||||
Carousel,
|
||||
LanguageSwitch,
|
||||
AuthFooter,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
mobileStart: true,
|
||||
communityName: CONFIG.COMMUNITY_NAME,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setMobileStart(boolean) {
|
||||
this.mobileStart = boolean
|
||||
},
|
||||
setTextSize(size) {
|
||||
this.$refs.pageFontSize.style.fontSize = size + 'rem'
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* left */
|
||||
.left-content-box {
|
||||
width: 40%;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
.bg-img-box {
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
/* right */
|
||||
.right-content-box {
|
||||
max-width: 640px;
|
||||
}
|
||||
.page-font-size {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.auth-template {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.bg-txt-box {
|
||||
margin-top: 317px;
|
||||
text-shadow: 2px 2px 8px #000000;
|
||||
max-width: 733px;
|
||||
}
|
||||
.bg-txt-box > .h0 {
|
||||
font-size: 4em;
|
||||
text-shadow: -2px -2px -8px #e4a907;
|
||||
}
|
||||
|
||||
.bg-txt-box .h1,
|
||||
.bg-txt-box .h2 {
|
||||
font-size: 1.5em;
|
||||
text-shadow: -2px -2px -8px #e4a907;
|
||||
}
|
||||
|
||||
.bg-img {
|
||||
border-radius: 0% 50% 70% 0% / 50% 70% 70% 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.svgType:hover {
|
||||
filter: invert(38%) sepia(18%) saturate(5307%) hue-rotate(179deg) brightness(89%) contrast(89%);
|
||||
}
|
||||
@media screen and (min-width: 2000px) {
|
||||
.right-content-box {
|
||||
max-width: 60%;
|
||||
font-size: xx-large;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,67 +0,0 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import AuthLayoutGdd from './AuthLayout_gdd'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('AuthLayoutGdd', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
$i18n: {
|
||||
locale: 'en',
|
||||
},
|
||||
$t: jest.fn((t) => t),
|
||||
$route: {
|
||||
meta: {
|
||||
hideFooter: false,
|
||||
},
|
||||
path: '/',
|
||||
},
|
||||
$store: {
|
||||
state: {},
|
||||
commit: jest.fn(),
|
||||
},
|
||||
}
|
||||
|
||||
const stubs = {
|
||||
// RouterLink: RouterLinkStub,
|
||||
RouterView: true,
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(AuthLayoutGdd, { localVue, mocks, stubs })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has no sidebar', () => {
|
||||
expect(wrapper.find('nav#sidenav-main').exists()).not.toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a main content div', () => {
|
||||
expect(wrapper.find('div.main-content').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a footer inside the main content', () => {
|
||||
expect(wrapper.find('div.main-content').find('footer.footer').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has LanguageSwitch', () => {
|
||||
expect(wrapper.findComponent({ name: 'LanguageSwitch' }).exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('check LanguageSwitch on register page', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$route.path = '/register'
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has not LanguageSwitch', () => {
|
||||
expect(wrapper.findComponent({ name: 'LanguageSwitch' }).exists()).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="main-content mt-4">
|
||||
<router-view></router-view>
|
||||
<language-switch v-if="$route.path !== '/register'" class="text-center mb-5 mt-5" />
|
||||
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ContentFooter from '@/components/ContentFooter.vue'
|
||||
import LanguageSwitch from '@/components/LanguageSwitch.vue'
|
||||
export default {
|
||||
components: {
|
||||
ContentFooter,
|
||||
LanguageSwitch,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -1,6 +1,6 @@
|
||||
import { mount, RouterLinkStub } from '@vue/test-utils'
|
||||
import flushPromises from 'flush-promises'
|
||||
import DashboardLayoutGdd from './DashboardLayout_gdd'
|
||||
import DashboardLayout from './DashboardLayout'
|
||||
|
||||
import { toastErrorSpy } from '@test/testSetup'
|
||||
|
||||
@ -19,7 +19,7 @@ const apolloMock = jest.fn().mockResolvedValue({
|
||||
},
|
||||
})
|
||||
|
||||
describe('DashboardLayoutGdd', () => {
|
||||
describe('DashboardLayout', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
@ -61,7 +61,7 @@ describe('DashboardLayoutGdd', () => {
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(DashboardLayoutGdd, { localVue, mocks, stubs })
|
||||
return mount(DashboardLayout, { localVue, mocks, stubs })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
@ -15,7 +15,7 @@
|
||||
<sidebar class="main-sidebar" :elopageUri="elopageUri" @admin="admin" @logout="logout" />
|
||||
</div>
|
||||
|
||||
<div class="main-page gradido-max-width" @click="visible = false">
|
||||
<div class="main-page w-100" @click="visible = false">
|
||||
<div class="main-content">
|
||||
<fade-transition :duration="200" origin="center top" mode="out-in">
|
||||
<router-view
|
||||
@ -45,6 +45,7 @@ import { FadeTransition } from 'vue2-transitions'
|
||||
import CONFIG from '@/config'
|
||||
|
||||
export default {
|
||||
name: 'DashboardLayout',
|
||||
components: {
|
||||
Navbar,
|
||||
Sidebar,
|
||||
@ -1,5 +1,22 @@
|
||||
{
|
||||
"100": "100%",
|
||||
"1000thanks": "1000 Dank, weil du bei uns bist!",
|
||||
"125": "125%",
|
||||
"85": "85%",
|
||||
"advanced-calculation": "Vorausberechnung",
|
||||
"auth": {
|
||||
"left": {
|
||||
"gratitude": "Dankbarkeit",
|
||||
"hasAccount": "Du hast schon einen Account?",
|
||||
"hereLogin": "Hier Anmelden",
|
||||
"learnMore": "Erfahre mehr …",
|
||||
"newCurrency": "Die neue Währung",
|
||||
"oneAnotherNature": "FÜR EINANDER, FÜR ALLE, FÜR DIE NATUR"
|
||||
},
|
||||
"navbar": {
|
||||
"aboutGradido": "Über Gradido"
|
||||
}
|
||||
},
|
||||
"back": "Zurück",
|
||||
"community": {
|
||||
"choose-another-community": "Eine andere Gemeinschaft auswählen",
|
||||
@ -40,6 +57,7 @@
|
||||
"unknown-error": "Unbekanter Fehler: ",
|
||||
"user-already-exists": "Ein Benutzer mit diesen Daten existiert bereits."
|
||||
},
|
||||
"followUs": "folge uns:",
|
||||
"footer": {
|
||||
"app_version": "App version {version}",
|
||||
"copyright": {
|
||||
@ -164,10 +182,6 @@
|
||||
"support": "Support",
|
||||
"transactions": "Transaktionen"
|
||||
},
|
||||
"publisher": {
|
||||
"infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!",
|
||||
"publisherId": "Publisher-Id:"
|
||||
},
|
||||
"qrCode": "QR Code",
|
||||
"send_gdd": "GDD versenden",
|
||||
"send_per_link": "GDD versenden per Link",
|
||||
@ -208,24 +222,28 @@
|
||||
"subtitle": "Wenn du dein Passwort vergessen hast, kannst du es hier zurücksetzen."
|
||||
}
|
||||
},
|
||||
"signin": "Anmelden",
|
||||
"signup": "Registrieren",
|
||||
"site": {
|
||||
"forgotPassword": {
|
||||
"heading": "Bitte gib deine E-Mail an mit der du bei Gradido angemeldet bist."
|
||||
},
|
||||
"login": {
|
||||
"community": "Tausend Dank, weil du bei uns bist!",
|
||||
"heading": "Gradido",
|
||||
"new_wallet": "Neues Konto erstellen",
|
||||
"signin": "Anmelden"
|
||||
"heading": "Melde dich mit deinen Zugangsdaten an. Bewahre sie stets sicher auf!",
|
||||
"saveLogin": "Anmeldung speichern"
|
||||
},
|
||||
"resetPassword": {
|
||||
"heading": "Trage bitte dein Passwort ein und wiederhole es."
|
||||
},
|
||||
"signup": {
|
||||
"agree": "Ich stimme der <a href='https://gradido.net/de/datenschutz/' target='_blank' >Datenschutzerklärung</a> zu.",
|
||||
"dont_match": "Die Passwörter stimmen nicht überein.",
|
||||
"heading": "Registriere dich indem du alle Daten vollständig und in die richtigen Felder eingibst.",
|
||||
"lowercase": "Ein Kleinbuchstabe erforderlich.",
|
||||
"minimum": "Mindestens 8 Zeichen.",
|
||||
"no-whitespace": "Keine Leerzeichen und Tabulatoren",
|
||||
"one_number": "Zahl erforderlich.",
|
||||
"special-char": "Sonderzeichen erforderlich (z.B. _ oder ä)",
|
||||
"subtitle": "Werde Teil der Gemeinschaft!",
|
||||
"title": "Erstelle dein Gradido-Konto",
|
||||
"uppercase": "Großbuchstabe erforderlich."
|
||||
},
|
||||
"thx": {
|
||||
@ -261,5 +279,7 @@
|
||||
"transaction-link": {
|
||||
"send_you": "sendet dir"
|
||||
},
|
||||
"via_link": "über einen Link"
|
||||
"via_link": "über einen Link",
|
||||
"welcome": "Willkommen",
|
||||
"WelcomeBy": "bei {name}"
|
||||
}
|
||||
|
||||
@ -1,5 +1,22 @@
|
||||
{
|
||||
"100": "100%",
|
||||
"1000thanks": "1000 thanks for being with us!",
|
||||
"125": "125%",
|
||||
"85": "85%",
|
||||
"advanced-calculation": "Advanced calculation",
|
||||
"auth": {
|
||||
"left": {
|
||||
"gratitude": "Gratitude",
|
||||
"hasAccount": "You already have an account?",
|
||||
"hereLogin": "Log in here",
|
||||
"learnMore": "Learn more …",
|
||||
"newCurrency": "The new currency",
|
||||
"oneAnotherNature": "FOR ONE ANOTHER, FOR ALL, FOR NATURE"
|
||||
},
|
||||
"navbar": {
|
||||
"aboutGradido": "About Gradido"
|
||||
}
|
||||
},
|
||||
"back": "Back",
|
||||
"community": {
|
||||
"choose-another-community": "Choose another community",
|
||||
@ -40,6 +57,7 @@
|
||||
"unknown-error": "Unknown error: ",
|
||||
"user-already-exists": "A user with this data already exists."
|
||||
},
|
||||
"followUs": "follow us:",
|
||||
"footer": {
|
||||
"app_version": "App version {version}",
|
||||
"copyright": {
|
||||
@ -164,10 +182,6 @@
|
||||
"support": "Support",
|
||||
"transactions": "Transactions"
|
||||
},
|
||||
"publisher": {
|
||||
"infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!",
|
||||
"publisherId": "PublisherID:"
|
||||
},
|
||||
"qrCode": "QR Code",
|
||||
"send_gdd": "GDD send",
|
||||
"send_per_link": "GDD send via link",
|
||||
@ -208,24 +222,28 @@
|
||||
"subtitle": "If you have forgotten your password, you can reset it here."
|
||||
}
|
||||
},
|
||||
"signin": "Sign in",
|
||||
"signup": "Sign up",
|
||||
"site": {
|
||||
"forgotPassword": {
|
||||
"heading": "Please enter the email address by which you're registered here."
|
||||
},
|
||||
"login": {
|
||||
"community": "A thousand thanks for being with us!",
|
||||
"heading": "Gradido",
|
||||
"new_wallet": "Create new account",
|
||||
"signin": "Sign in"
|
||||
"heading": "Log in with your access data. Keep them safe!",
|
||||
"saveLogin": "Save login"
|
||||
},
|
||||
"resetPassword": {
|
||||
"heading": "Please enter your password and repeat it."
|
||||
},
|
||||
"signup": {
|
||||
"agree": "I agree to the <a href='https://gradido.net/en/datenschutz/' target='_blank' > privacy policy</a>.",
|
||||
"dont_match": "Passwords don't match.",
|
||||
"heading": "Register by entering all data completely and in the correct fields.",
|
||||
"lowercase": "One lowercase letter required.",
|
||||
"minimum": "8 characters minimum.",
|
||||
"no-whitespace": "No white spaces and tabs",
|
||||
"one_number": "One number required.",
|
||||
"special-char": "One special character required (e.g. _ or ä)",
|
||||
"subtitle": "Become a part of the community!",
|
||||
"title": "Create your Gradido account",
|
||||
"uppercase": "One uppercase letter required."
|
||||
},
|
||||
"thx": {
|
||||
@ -261,5 +279,7 @@
|
||||
"transaction-link": {
|
||||
"send_you": "wants to send you"
|
||||
},
|
||||
"via_link": "via Link"
|
||||
"via_link": "via Link",
|
||||
"welcome": "Welcome",
|
||||
"WelcomeBy": "by {name}"
|
||||
}
|
||||
|
||||
@ -50,14 +50,6 @@ describe('ForgotPassword', () => {
|
||||
expect(wrapper.find('div.forgot-password').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has a title', () => {
|
||||
expect(wrapper.find('h1').text()).toEqual('settings.password.reset')
|
||||
})
|
||||
|
||||
it('has a subtitle', () => {
|
||||
expect(wrapper.find('p.text-lead').text()).toEqual('settings.password.subtitle')
|
||||
})
|
||||
|
||||
describe('back button', () => {
|
||||
it('has a "back" button', () => {
|
||||
expect(wrapper.findComponent(RouterLinkStub).text()).toEqual('back')
|
||||
@ -129,8 +121,6 @@ describe('ForgotPassword', () => {
|
||||
})
|
||||
|
||||
it.skip('click redirects to "/login"', async () => {
|
||||
// wrapper.find('.test-message-button').trigger('click')
|
||||
// await wrapper.vm.$nextTick()
|
||||
expect(mockRouterPush).toBeCalledWith('/login')
|
||||
})
|
||||
|
||||
@ -162,23 +152,9 @@ describe('ForgotPassword', () => {
|
||||
it('button link redirects to "/login"', () => {
|
||||
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
|
||||
})
|
||||
|
||||
it.skip('click redirects to "/login"', () => {
|
||||
// expect(mockRouterPush).toBeCalledWith('/login')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('comingFrom login', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(createMockObject('resetPassword'))
|
||||
})
|
||||
|
||||
it('has another subtitle', () => {
|
||||
expect(wrapper.find('p.text-lead').text()).toEqual('settings.password.resend_subtitle')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,21 +1,9 @@
|
||||
<template>
|
||||
<div class="forgot-password">
|
||||
<div class="header p-4">
|
||||
<b-container class="container">
|
||||
<div class="header-body text-center mb-7">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<h1>{{ $t('settings.password.reset') }}</h1>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
|
||||
<p class="text-lead">{{ $t(subtitle) }}</p>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</b-container>
|
||||
</div>
|
||||
<b-container v-if="enterData" class="mt--8 p-1">
|
||||
<b-container v-if="enterData">
|
||||
<div class="pb-5">{{ $t('site.forgotPassword.heading') }}</div>
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="6" md="8">
|
||||
<b-col>
|
||||
<b-card no-body class="border-0 gradido-custom-background">
|
||||
<b-card-body class="p-4">
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
@ -36,24 +24,17 @@
|
||||
<router-link to="/login" class="mt-3">{{ $t('back') }}</router-link>
|
||||
</div>
|
||||
</b-container>
|
||||
<b-container v-else class="mt--8 p-1">
|
||||
<b-container v-else>
|
||||
<message
|
||||
v-if="success"
|
||||
:headline="$t('site.thx.title')"
|
||||
:subtitle="$t('site.thx.email')"
|
||||
:buttonText="$t('login')"
|
||||
linkTo="/login"
|
||||
/>
|
||||
<message
|
||||
v-else
|
||||
:headline="$t('site.thx.errorTitle')"
|
||||
:subtitle="$t('error.email-already-sent')"
|
||||
:headline="success ? $t('site.thx.title') : $t('site.thx.errorTitle')"
|
||||
:subtitle="success ? $t('site.thx.email') : $t('error.email-already-sent')"
|
||||
:buttonText="$t('login')"
|
||||
linkTo="/login"
|
||||
/>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { forgotPassword } from '@/graphql/mutations'
|
||||
import InputEmail from '@/components/Inputs/InputEmail'
|
||||
|
||||
@ -62,42 +62,12 @@ describe('Login', () => {
|
||||
expect(wrapper.find('div.login-form').exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('Login header', () => {
|
||||
it('has a welcome message', () => {
|
||||
expect(wrapper.find('div.header').text()).toBe('site.login.heading site.login.community')
|
||||
})
|
||||
})
|
||||
|
||||
it('has a Community name', () => {
|
||||
expect(wrapper.find('.test-communitydata b').text()).toBe('Gradido Entwicklung')
|
||||
})
|
||||
|
||||
it('has a Community description', () => {
|
||||
expect(wrapper.find('.test-communitydata p').text()).toBe(
|
||||
'Die lokale Entwicklungsumgebung von Gradido.',
|
||||
)
|
||||
})
|
||||
|
||||
describe('links', () => {
|
||||
it('has a link "Forgot Password"', () => {
|
||||
expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toEqual(
|
||||
'settings.password.forgot_pwd',
|
||||
)
|
||||
})
|
||||
|
||||
it('links to /forgot-password when clicking "Forgot Password"', () => {
|
||||
expect(wrapper.findAllComponents(RouterLinkStub).at(0).props().to).toBe('/forgot-password')
|
||||
})
|
||||
|
||||
it('has a link "Create new account"', () => {
|
||||
expect(wrapper.findAllComponents(RouterLinkStub).at(1).text()).toEqual(
|
||||
'site.login.new_wallet',
|
||||
)
|
||||
})
|
||||
|
||||
it('links to /register when clicking "Create new account"', () => {
|
||||
expect(wrapper.findAllComponents(RouterLinkStub).at(1).props().to).toBe('/register')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Login form', () => {
|
||||
|
||||
@ -1,63 +1,45 @@
|
||||
<template>
|
||||
<div class="login-form">
|
||||
<!-- Header -->
|
||||
<div class="p-3">
|
||||
<b-container>
|
||||
<div class="text-center mb-7 header">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<h1>{{ $t('site.login.heading') }}</h1>
|
||||
<p class="text-lead">{{ $t('site.login.community') }}</p>
|
||||
<b-container v-if="enterData">
|
||||
<div class="pb-5">{{ $t('site.login.heading') }}</div>
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
<b-form @submit.stop.prevent="handleSubmit(onSubmit)">
|
||||
<b-row>
|
||||
<b-col sm="12" md="12" lg="6"><input-email v-model="form.email"></input-email></b-col>
|
||||
<b-col sm="12" md="12" lg="6">
|
||||
<input-password
|
||||
:label="$t('form.password')"
|
||||
:placeholder="$t('form.password')"
|
||||
:name="$t('form.password')"
|
||||
v-model="form.password"
|
||||
></input-password>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</b-container>
|
||||
</div>
|
||||
<b-container v-if="enterData" class="mt--8 p-1">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="5" md="7">
|
||||
<b-card no-body class="border-0 mb-0 gradido-custom-background">
|
||||
<b-card-body class="p-4">
|
||||
<div class="text-center text-muted mb-4 test-communitydata">
|
||||
<b>{{ CONFIG.COMMUNITY_NAME }}</b>
|
||||
<p class="text-lead">
|
||||
{{ CONFIG.COMMUNITY_DESCRIPTION }}
|
||||
</p>
|
||||
{{ $t('login') }}
|
||||
</div>
|
||||
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
<b-form @submit.stop.prevent="handleSubmit(onSubmit)">
|
||||
<input-email v-model="form.email"></input-email>
|
||||
<input-password
|
||||
:label="$t('form.password')"
|
||||
:placeholder="$t('form.password')"
|
||||
:name="$t('form.password')"
|
||||
v-model="form.password"
|
||||
></input-password>
|
||||
<div class="text-center mt-4">
|
||||
<b-button type="submit" variant="primary">{{ $t('login') }}</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
<b-row class="mt-3">
|
||||
<b-col cols="6" class="text-center text-sm-left col-12 col-sm-6 pb-5">
|
||||
<b-row>
|
||||
<b-col class="d-flex justify-content-start">
|
||||
<b-form-checkbox
|
||||
class="mt-3"
|
||||
v-model="status"
|
||||
name="checkbox-1"
|
||||
value="saved"
|
||||
unchecked-value="not_saved"
|
||||
>
|
||||
{{ $t('site.login.saveLogin') }}
|
||||
</b-form-checkbox>
|
||||
</b-col>
|
||||
<b-col class="d-flex justify-content-end">
|
||||
<router-link to="/forgot-password" class="mt-3">
|
||||
{{ $t('settings.password.forgot_pwd') }}
|
||||
</router-link>
|
||||
</b-col>
|
||||
<b-col cols="6" class="text-center text-sm-right col-12 col-sm-6">
|
||||
<router-link to="/register" class="mt-3">
|
||||
{{ $t('site.login.new_wallet') }}
|
||||
</router-link>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div class="mt-5">
|
||||
<b-button type="submit" variant="gradido">{{ $t('login') }}</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-container>
|
||||
<b-container v-else class="mt--8 p-1">
|
||||
<b-container v-else>
|
||||
<message
|
||||
:headline="$t('site.thx.errorTitle')"
|
||||
:subtitle="errorSubtitle"
|
||||
@ -73,7 +55,6 @@ import InputPassword from '@/components/Inputs/InputPassword'
|
||||
import InputEmail from '@/components/Inputs/InputEmail'
|
||||
import Message from '@/components/Message/Message'
|
||||
import { login } from '@/graphql/queries'
|
||||
import CONFIG from '@/config'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
@ -89,11 +70,11 @@ export default {
|
||||
password: '',
|
||||
},
|
||||
passwordVisible: false,
|
||||
status: false,
|
||||
showPageMessage: false,
|
||||
errorReason: null,
|
||||
errorSubtitle: '',
|
||||
errorLinkTo: '',
|
||||
CONFIG,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -135,10 +116,8 @@ export default {
|
||||
this.errorLinkTo = '/reset-password/login'
|
||||
this.toastError(this.$t('error.no-account'))
|
||||
} else if (error.message.includes('No user with this credentials')) {
|
||||
// don't show any error on the page! against boots
|
||||
this.toastError(this.$t('error.no-user'))
|
||||
} else {
|
||||
// don't show any error on the page! against boots
|
||||
this.toastError(this.$t('error.unknown-error') + error.message)
|
||||
}
|
||||
loader.hide()
|
||||
|
||||
@ -31,7 +31,6 @@ describe('Register', () => {
|
||||
state: {
|
||||
email: 'peter@lustig.de',
|
||||
language: 'en',
|
||||
publisherId: 12345,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -53,45 +52,6 @@ describe('Register', () => {
|
||||
expect(wrapper.find('div#registerform').exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('Register header', () => {
|
||||
it('has a welcome message', () => {
|
||||
expect(wrapper.find('div.header').text()).toBe('site.signup.title site.signup.subtitle')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Community data already loaded', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
mocks.$store.state.community = {
|
||||
name: 'Gradido Entwicklung',
|
||||
url: 'http://localhost/',
|
||||
registerUrl: 'http://localhost/register',
|
||||
description: 'Die lokale Entwicklungsumgebung von Gradido.',
|
||||
}
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a Community name', () => {
|
||||
expect(wrapper.find('.test-communitydata b').text()).toBe('Gradido Entwicklung')
|
||||
})
|
||||
|
||||
it('has a Community description', () => {
|
||||
expect(wrapper.find('.test-communitydata p').text()).toBe(
|
||||
'Die lokale Entwicklungsumgebung von Gradido.',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('links', () => {
|
||||
it('has a link "Back"', () => {
|
||||
expect(wrapper.find('.test-button-back').text()).toEqual('back')
|
||||
})
|
||||
|
||||
it('links to /login when clicking "Back"', () => {
|
||||
expect(wrapper.find('.test-button-back').props().to).toBe('/login')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Register form', () => {
|
||||
it('has a register form', () => {
|
||||
expect(wrapper.find('form').exists()).toBe(true)
|
||||
@ -121,11 +81,6 @@ describe('Register', () => {
|
||||
expect(wrapper.find('#registerCheckbox').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has PublisherId input fields', () => {
|
||||
wrapper.find('.publisherCollaps').trigger('click')
|
||||
expect(wrapper.find('#publisherid').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has disabled submit button when not completely filled', () => {
|
||||
expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled')
|
||||
})
|
||||
@ -155,26 +110,11 @@ describe('Register', () => {
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
describe('link Choose another community', () => {
|
||||
it('has a link "Choose another community"', () => {
|
||||
expect(wrapper.find('.test-button-another-community').text()).toEqual(
|
||||
'community.choose-another-community',
|
||||
)
|
||||
})
|
||||
|
||||
it('links to /select-community when clicking "Choose another community"', () => {
|
||||
expect(wrapper.find('.test-button-another-community').props().to).toBe('/select-community')
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
describe('API calls when form is missing input', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('#registerFirstname').setValue('Max')
|
||||
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||
wrapper.find('.language-switch-select').findAll('option').at(1).setSelected()
|
||||
wrapper.find('#publisherid').setValue('12345')
|
||||
})
|
||||
it('has disabled submit button when missing input checked box', () => {
|
||||
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
||||
@ -187,34 +127,15 @@ describe('Register', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('API calls when completely filled and missing publisherid', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('#registerFirstname').setValue('Max')
|
||||
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
||||
wrapper.find('.language-switch-select').findAll('option').at(1).setSelected()
|
||||
wrapper.find('#registerCheckbox').setChecked()
|
||||
})
|
||||
it('has enabled submit button when completely filled', async () => {
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe(undefined)
|
||||
})
|
||||
})
|
||||
|
||||
describe('API calls when completely filled', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('#registerFirstname').setValue('Max')
|
||||
wrapper.find('#registerLastname').setValue('Mustermann')
|
||||
wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net')
|
||||
wrapper.find('.language-switch-select').findAll('option').at(1).setSelected()
|
||||
wrapper.find('#publisherid').setValue('12345')
|
||||
wrapper.find('#registerCheckbox').setChecked()
|
||||
})
|
||||
|
||||
it('commits publisherId to store', () => {
|
||||
expect(mockStoreCommit).toBeCalledWith('publisherId', 12345)
|
||||
})
|
||||
|
||||
it('has enabled submit button when completely filled', async () => {
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe(undefined)
|
||||
@ -285,7 +206,6 @@ describe('Register', () => {
|
||||
firstName: 'Max',
|
||||
lastName: 'Mustermann',
|
||||
language: 'en',
|
||||
publisherId: 12345,
|
||||
},
|
||||
}),
|
||||
)
|
||||
@ -335,7 +255,6 @@ describe('Register', () => {
|
||||
firstName: 'Max',
|
||||
lastName: 'Mustermann',
|
||||
language: 'en',
|
||||
publisherId: 12345,
|
||||
redeemCode: 'some-code',
|
||||
},
|
||||
}),
|
||||
|
||||
@ -1,183 +1,104 @@
|
||||
<template>
|
||||
<div id="registerform">
|
||||
<!-- Header -->
|
||||
<div class="header p-4">
|
||||
<b-container class="container">
|
||||
<div class="header-body text-center mb-7">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<h1>{{ $t('site.signup.title') }}</h1>
|
||||
<p class="text-lead">{{ $t('site.signup.subtitle') }}</p>
|
||||
<b-container v-if="enterData">
|
||||
<div class="pb-5">
|
||||
{{ $t('site.signup.heading') }}
|
||||
</div>
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<b-row>
|
||||
<b-col sm="12" md="6">
|
||||
<validation-provider
|
||||
:name="$t('form.firstname')"
|
||||
:rules="{ required: true, min: 3 }"
|
||||
v-slot="validationContext"
|
||||
>
|
||||
<b-form-group
|
||||
class="mb-3"
|
||||
:label="$t('form.firstname')"
|
||||
label-for="registerFirstname"
|
||||
>
|
||||
<b-form-input
|
||||
id="registerFirstname"
|
||||
:name="$t('form.firstname')"
|
||||
v-model="form.firstname"
|
||||
:placeholder="$t('form.firstname')"
|
||||
:state="getValidationState(validationContext)"
|
||||
aria-describedby="registerFirstnameLiveFeedback"
|
||||
></b-form-input>
|
||||
|
||||
<b-form-invalid-feedback id="registerFirstnameLiveFeedback">
|
||||
{{ validationContext.errors[0] }}
|
||||
</b-form-invalid-feedback>
|
||||
</b-form-group>
|
||||
</validation-provider>
|
||||
</b-col>
|
||||
<b-col sm="12" md="6">
|
||||
<validation-provider
|
||||
:name="$t('form.lastname')"
|
||||
:rules="{ required: true, min: 2 }"
|
||||
v-slot="validationContext"
|
||||
>
|
||||
<b-form-group
|
||||
class="mb-3"
|
||||
:label="$t('form.lastname')"
|
||||
label-for="registerLastname"
|
||||
>
|
||||
<b-form-input
|
||||
id="registerLastname"
|
||||
:name="$t('form.lastname')"
|
||||
v-model="form.lastname"
|
||||
:placeholder="$t('form.lastname')"
|
||||
:state="getValidationState(validationContext)"
|
||||
aria-describedby="registerLastnameLiveFeedback"
|
||||
></b-form-input>
|
||||
|
||||
<b-form-invalid-feedback id="registerLastnameLiveFeedback">
|
||||
{{ validationContext.errors[0] }}
|
||||
</b-form-invalid-feedback>
|
||||
</b-form-group>
|
||||
</validation-provider>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col sm="12" md="6"><input-email v-model="form.email"></input-email></b-col>
|
||||
<b-col sm="12" md="6">
|
||||
<label>{{ $t('language') }}</label>
|
||||
<language-switch-select @update-language="updateLanguage" />
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</b-container>
|
||||
</div>
|
||||
|
||||
<!-- Page content -->
|
||||
<b-container v-if="enterData" class="mt--8 p-1">
|
||||
<!-- Table -->
|
||||
<b-row class="mt-4 mb-4">
|
||||
<b-col class="mb-4 mb-md-0">
|
||||
<b-form-checkbox
|
||||
id="registerCheckbox"
|
||||
v-model="form.agree"
|
||||
:name="$t('site.signup.agree')"
|
||||
>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
|
||||
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
|
||||
</b-form-checkbox>
|
||||
</b-col>
|
||||
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="6" md="8">
|
||||
<b-card no-body class="border-0 gradido-custom-background">
|
||||
<b-card-body class="p-4">
|
||||
<div class="text-center text-muted mb-4 test-communitydata">
|
||||
<b>{{ CONFIG.COMMUNITY_NAME }}</b>
|
||||
<p class="text-lead">
|
||||
{{ CONFIG.COMMUNITY_DESCRIPTION }}
|
||||
</p>
|
||||
<div>{{ $t('signup') }}</div>
|
||||
</div>
|
||||
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<validation-provider
|
||||
:name="$t('form.firstname')"
|
||||
:rules="{ required: true, min: 3 }"
|
||||
v-slot="validationContext"
|
||||
>
|
||||
<b-form-group
|
||||
class="mb-3"
|
||||
:label="$t('form.firstname')"
|
||||
label-for="registerFirstname"
|
||||
>
|
||||
<b-form-input
|
||||
id="registerFirstname"
|
||||
:name="$t('form.firstname')"
|
||||
v-model="form.firstname"
|
||||
:placeholder="$t('form.firstname')"
|
||||
:state="getValidationState(validationContext)"
|
||||
aria-describedby="registerFirstnameLiveFeedback"
|
||||
></b-form-input>
|
||||
|
||||
<b-form-invalid-feedback id="registerFirstnameLiveFeedback">
|
||||
{{ validationContext.errors[0] }}
|
||||
</b-form-invalid-feedback>
|
||||
</b-form-group>
|
||||
</validation-provider>
|
||||
|
||||
<validation-provider
|
||||
:name="$t('form.lastname')"
|
||||
:rules="{ required: true, min: 2 }"
|
||||
v-slot="validationContext"
|
||||
>
|
||||
<b-form-group
|
||||
class="mb-3"
|
||||
:label="$t('form.lastname')"
|
||||
label-for="registerLastname"
|
||||
>
|
||||
<b-form-input
|
||||
id="registerLastname"
|
||||
:name="$t('form.lastname')"
|
||||
v-model="form.lastname"
|
||||
:placeholder="$t('form.lastname')"
|
||||
:state="getValidationState(validationContext)"
|
||||
aria-describedby="registerLastnameLiveFeedback"
|
||||
></b-form-input>
|
||||
|
||||
<b-form-invalid-feedback id="registerLastnameLiveFeedback">
|
||||
{{ validationContext.errors[0] }}
|
||||
</b-form-invalid-feedback>
|
||||
</b-form-group>
|
||||
</validation-provider>
|
||||
|
||||
<input-email v-model="form.email"></input-email>
|
||||
|
||||
<hr />
|
||||
|
||||
<b-row>
|
||||
<b-col cols="12">
|
||||
{{ $t('language') }}
|
||||
<language-switch-select @update-language="updateLanguage" />
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row class="my-4">
|
||||
<b-col cols="12">
|
||||
<b-form-checkbox
|
||||
id="registerCheckbox"
|
||||
v-model="form.agree"
|
||||
:name="$t('site.signup.agree')"
|
||||
>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
|
||||
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
|
||||
</b-form-checkbox>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row v-b-toggle:my-collapse class="text-muted shadow-sm p-3 publisherCollaps">
|
||||
<b-col>{{ $t('publisher.publisherId') }} {{ $store.state.publisherId }}</b-col>
|
||||
<b-col class="text-right">
|
||||
<b-icon icon="chevron-down" aria-hidden="true"></b-icon>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-collapse id="my-collapse" class="">
|
||||
<b-input-group class="shadow-sm p-2 bg-white rounded">
|
||||
<b-input-group-prepend is-text>
|
||||
<b-icon icon="person-fill"></b-icon>
|
||||
</b-input-group-prepend>
|
||||
<b-form-input
|
||||
id="publisherid"
|
||||
type="text"
|
||||
placeholder="Publisher ID"
|
||||
v-model="publisherId"
|
||||
@input="commitStorePublisherId(publisherId)"
|
||||
></b-form-input>
|
||||
</b-input-group>
|
||||
<div
|
||||
v-b-toggle:my-collapse
|
||||
class="text-center mt-1 shadow-lg p-3 mb-5 rounded"
|
||||
>
|
||||
{{ $t('publisher.infoText') }}
|
||||
<div class="text-center">
|
||||
<b-icon icon="chevron-up" aria-hidden="true"></b-icon>
|
||||
</div>
|
||||
</div>
|
||||
</b-collapse>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<div class="text-center mt-5">
|
||||
<div class="text-center">
|
||||
<router-link class="test-button-back" to="/login">
|
||||
<b-button variant="outline-secondary" class="mr-4">
|
||||
{{ $t('back') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
<b-button
|
||||
:disabled="disabled"
|
||||
type="submit"
|
||||
:variant="disabled ? 'outline-light' : 'primary'"
|
||||
>
|
||||
{{ $t('signup') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-col class="d-flex justify-content-end">
|
||||
<b-button
|
||||
type="submit"
|
||||
:disabled="disabled"
|
||||
:variant="disabled ? 'outline-gradido' : 'gradido'"
|
||||
>
|
||||
{{ $t('signup') }}
|
||||
</b-button>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-container>
|
||||
<b-container v-else class="mt--8 p-1">
|
||||
<b-container v-else>
|
||||
<message :headline="$t('site.thx.title')" :subtitle="$t('site.thx.register')" />
|
||||
</b-container>
|
||||
<!--
|
||||
<div class="text-center pt-4">
|
||||
<router-link class="test-button-another-community" to="/select-community">
|
||||
<b-button variant="outline-secondary">
|
||||
{{ $t('community.choose-another-community') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { createUser } from '@/graphql/mutations'
|
||||
import CONFIG from '@/config'
|
||||
@ -236,7 +157,6 @@ export default {
|
||||
this.showPageMessage = true
|
||||
})
|
||||
.catch((error) => {
|
||||
// don't show any error on the page! against boots
|
||||
let errorMessage
|
||||
switch (error.message) {
|
||||
case 'GraphQL error: User already exists.':
|
||||
|
||||
@ -79,36 +79,6 @@ describe('ResetPassword', () => {
|
||||
expect(wrapper.find('div.resetpwd-form').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('Register header', () => {
|
||||
describe('from reset', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$route.path.mock = 'reset-password'
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a welcome message', async () => {
|
||||
expect(wrapper.find('div.header').text()).toContain('settings.password.reset')
|
||||
expect(wrapper.find('div.header').text()).toContain(
|
||||
'settings.password.reset-password.text',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('from checkEmail', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$route.path.mock = 'checkEmail'
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a welcome message', async () => {
|
||||
expect(wrapper.find('div.header').text()).toContain('settings.password.set')
|
||||
expect(wrapper.find('div.header').text()).toContain(
|
||||
'settings.password.set-password.text',
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('links', () => {
|
||||
it('has a link "Back"', async () => {
|
||||
expect(wrapper.findAllComponents(RouterLinkStub).at(0).text()).toEqual('back')
|
||||
|
||||
@ -1,51 +1,26 @@
|
||||
<template>
|
||||
<div class="resetpwd-form">
|
||||
<b-container>
|
||||
<div class="header p-4" ref="header">
|
||||
<div class="header-body text-center mb-7">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
|
||||
<h1>{{ $t(displaySetup.title) }}</h1>
|
||||
<div class="pb-4">
|
||||
<span>
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
|
||||
{{ $t(displaySetup.text) }}
|
||||
</span>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div class="pb-5">{{ $t('site.resetPassword.heading') }}</div>
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<input-password-confirmation v-model="form" />
|
||||
<div class="text-center">
|
||||
<b-button type="submit" variant="primary" class="mt-4">
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
|
||||
{{ $t(displaySetup.button) }}
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</b-container>
|
||||
<b-container class="mt--8 p-1">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col lg="6" md="8">
|
||||
<b-card no-body class="border-0 gradido-custom-background">
|
||||
<b-card-body class="p-4">
|
||||
<validation-observer ref="observer" v-slot="{ handleSubmit }">
|
||||
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
|
||||
<input-password-confirmation v-model="form" />
|
||||
<div class="text-center">
|
||||
<b-button type="submit" variant="primary" class="mt-4">
|
||||
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
|
||||
{{ $t(displaySetup.button) }}
|
||||
</b-button>
|
||||
</div>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row v-if="displaySetup.linkTo">
|
||||
<b-col class="text-center py-lg-4">
|
||||
<router-link :to="displaySetup.linkTo" class="mt-3">{{ $t('back') }}</router-link>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-form>
|
||||
</validation-observer>
|
||||
|
||||
<b-row v-if="displaySetup.linkTo">
|
||||
<b-col class="text-center py-lg-4">
|
||||
<router-link :to="displaySetup.linkTo" class="mt-3">{{ $t('back') }}</router-link>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import InputPasswordConfirmation from '@/components/Inputs/InputPasswordConfirmation'
|
||||
import { setPassword } from '@/graphql/mutations'
|
||||
|
||||
@ -3,7 +3,7 @@ import Send, { SEND_TYPES } from './Send'
|
||||
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
|
||||
import { TRANSACTION_STEPS } from '@/components/GddSend.vue'
|
||||
import { sendCoins, createTransactionLink } from '@/graphql/mutations.js'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
|
||||
import DashboardLayout from '@/layouts/DashboardLayout.vue'
|
||||
import flushPromises from 'flush-promises'
|
||||
|
||||
const apolloMutationMock = jest.fn()
|
||||
|
||||
@ -40,7 +40,7 @@ const textFields = {
|
||||
register: {
|
||||
headline: 'site.thx.title',
|
||||
subtitle: 'site.thx.register',
|
||||
button: 'site.login.signin',
|
||||
button: 'signin',
|
||||
// linkTo: '/login',
|
||||
},
|
||||
checkEmail: {
|
||||
|
||||
@ -5214,7 +5214,7 @@ core-js-compat@^3.8.1:
|
||||
browserslist "^4.16.3"
|
||||
semver "7.0.0"
|
||||
|
||||
core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.5:
|
||||
core-js@^2.4.0, core-js@^2.6.5:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||
@ -5543,14 +5543,6 @@ cyclist@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
|
||||
|
||||
d@1, d@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
|
||||
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
|
||||
dependencies:
|
||||
es5-ext "^0.10.50"
|
||||
type "^1.0.1"
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
@ -6236,68 +6228,11 @@ es-to-primitive@^1.2.1:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14:
|
||||
version "0.10.53"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
|
||||
integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
|
||||
dependencies:
|
||||
es6-iterator "~2.0.3"
|
||||
es6-symbol "~3.1.3"
|
||||
next-tick "~1.0.0"
|
||||
|
||||
es6-iterator@~2.0.1, es6-iterator@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
||||
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.35"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-map@^0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
|
||||
integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
es6-iterator "~2.0.1"
|
||||
es6-set "~0.1.5"
|
||||
es6-symbol "~3.1.1"
|
||||
event-emitter "~0.3.5"
|
||||
|
||||
es6-promise@^4.1.1:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-set@~0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
|
||||
integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
es6-iterator "~2.0.1"
|
||||
es6-symbol "3.1.1"
|
||||
event-emitter "~0.3.5"
|
||||
|
||||
es6-symbol@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
|
||||
integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
|
||||
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
|
||||
dependencies:
|
||||
d "^1.0.1"
|
||||
ext "^1.1.2"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
@ -6692,14 +6627,6 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
event-emitter@~0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
||||
integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
event-pubsub@4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e"
|
||||
@ -6877,13 +6804,6 @@ express@^4.16.3, express@^4.17.1:
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
ext@^1.1.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
|
||||
integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==
|
||||
dependencies:
|
||||
type "^2.0.0"
|
||||
|
||||
extend-shallow@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
|
||||
@ -10617,11 +10537,6 @@ neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2:
|
||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||
|
||||
next-tick@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
@ -11254,15 +11169,6 @@ parseurl@~1.3.2, parseurl@~1.3.3:
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
|
||||
|
||||
particles-bg-vue@1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/particles-bg-vue/-/particles-bg-vue-1.2.3.tgz#5cfb944da1074ee6e61b773bfef0512ef6ddc2c2"
|
||||
integrity sha512-VT72LfMYkqT4IRHNqvlbAtgTaDOgtjtJApXiqK13K/aUc28jhQuI9JN5tpPpMkRPIG4OpfmnWhSfE2hjZetmuw==
|
||||
dependencies:
|
||||
proton-engine "^4.1.3"
|
||||
raf-manager "^0.3.0"
|
||||
vue "^2.2.6"
|
||||
|
||||
pascalcase@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
|
||||
@ -11984,11 +11890,6 @@ proto-list@~1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
|
||||
integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
|
||||
|
||||
proton-engine@^4.1.3:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/proton-engine/-/proton-engine-4.2.1.tgz#db938e4f673ddbd91ac70628b0733283a4571ef7"
|
||||
integrity sha512-c72hgcnwMyyvUoy7Jq/HX3HQZnAo5MUNvFbyZHiWZrwcERX9+lYzM9YyT0iueXVAJpt+r8nrPan9F3HTXj7IsA==
|
||||
|
||||
proxy-addr@~2.0.5:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
|
||||
@ -12133,14 +12034,6 @@ quick-lru@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
|
||||
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
|
||||
|
||||
raf-manager@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/raf-manager/-/raf-manager-0.3.0.tgz#ec9a659e8a50534e4d64200b7a39ce9905f10e9c"
|
||||
integrity sha512-qLpVgVlUmwtlY35zoyCQwLWMOpLkVtiItPd/RxouHAh80XZjoh84CF5pFBVyIIUWXubypSJi1OBJS4jM7onOng==
|
||||
dependencies:
|
||||
core-js "^2.5.7"
|
||||
es6-map "^0.1.5"
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
@ -14111,16 +14004,6 @@ type-is@~1.6.17, type-is@~1.6.18:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
type@^1.0.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
|
||||
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
|
||||
|
||||
type@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/type/-/type-2.3.0.tgz#ada7c045f07ead08abf9e2edd29be1a0c0661132"
|
||||
integrity sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==
|
||||
|
||||
typedarray-to-buffer@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||
@ -14604,7 +14487,7 @@ vue2-transitions@^0.2.3:
|
||||
resolved "https://registry.yarnpkg.com/vue2-transitions/-/vue2-transitions-0.2.3.tgz#69c9d75b1db05f231b80980c03459d68490ba27d"
|
||||
integrity sha512-Ou5x74AOQbM8JjZV8pIssFFqavvj53QzrEEUr5QnElUYb1ZizPwaUJo0ZqmLPqjwPae7ON4SG8U2cSTI4tHKLg==
|
||||
|
||||
vue@2.6.12, vue@^2.2.6, vue@^2.6.11:
|
||||
vue@2.6.12, vue@^2.6.11:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
|
||||
integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user