diff --git a/src/components/specific/groups/group-card/GroupCard.scss b/src/components/specific/groups/group-card/GroupCard.scss new file mode 100644 index 000000000..1c4bce618 --- /dev/null +++ b/src/components/specific/groups/group-card/GroupCard.scss @@ -0,0 +1,54 @@ +@import "./GroupCard.vars.scss"; + +.group-card { + min-width: $card-width; + width: $card-width; + height: $card-height; + + .bimdata-card { + position: relative; + width: 100%; + height: 100%; + transition-duration: 0.35s; + + .group-card__top-stripe { + position: absolute; + z-index: 1; + top: 0; + width: $card-width; + height: 3px; + } + + .group-card__btn-menu { + position: absolute; + top: $spacing-unit/2; + right: $spacing-unit/2; + } + + .group-card__title { + margin-bottom: $spacing-unit; + } + + &:deep() { + .bimdata-card__content { + overflow: hidden; + height: $card-content-height; + padding: 0; + color: $color-primary; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: $spacing-unit; + + font-size: 1.2rem; + } + } + + &:hover { + cursor: pointer; + box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.3); + } + } +} diff --git a/src/components/specific/groups/group-card/GroupCard.vars.scss b/src/components/specific/groups/group-card/GroupCard.vars.scss new file mode 100644 index 000000000..bc2a1fc2b --- /dev/null +++ b/src/components/specific/groups/group-card/GroupCard.vars.scss @@ -0,0 +1,4 @@ +$card-width: 320px; +$card-height: 261px; +$card-content-height: $card-height; +$card-background: $color-tertiary-lightest; diff --git a/src/components/specific/groups/group-card/GroupCard.vue b/src/components/specific/groups/group-card/GroupCard.vue new file mode 100644 index 000000000..000396818 --- /dev/null +++ b/src/components/specific/groups/group-card/GroupCard.vue @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/specific/groups/group-card/group-card-action-menu/GroupCardActionMenu.scss b/src/components/specific/groups/group-card/group-card-action-menu/GroupCardActionMenu.scss new file mode 100644 index 000000000..b6582896e --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-action-menu/GroupCardActionMenu.scss @@ -0,0 +1,33 @@ +.group-card-action-menu { + height: 100%; + background-color: $color-white; + + &__loader { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + transform: scale(2); + } + + &__menu { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + height: 100%; + padding: $spacing-unit * 2; + + &__title { + position: absolute; + top: 0; + left: 0; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: $spacing-unit $spacing-unit * 2; + font-weight: bold; + } + } +} diff --git a/src/components/specific/groups/group-card/group-card-action-menu/GroupCardActionMenu.vue b/src/components/specific/groups/group-card/group-card-action-menu/GroupCardActionMenu.vue new file mode 100644 index 000000000..cf3debefb --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-action-menu/GroupCardActionMenu.vue @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ $t("GroupCardActionMenu.renameButtonText") }} + + + {{ $t("GroupCardActionMenu.changeColorButtonText") }} + + + {{ $t("GroupCardActionMenu.deleteButtonText") }} + + + + + + + + + + diff --git a/src/components/specific/groups/group-card/group-card-color-picker/GroupCardColorPicker.scss b/src/components/specific/groups/group-card/group-card-color-picker/GroupCardColorPicker.scss new file mode 100644 index 000000000..1af7899ae --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-color-picker/GroupCardColorPicker.scss @@ -0,0 +1,46 @@ +.group-card-color-picker { + display: flex; + height: 100%; + padding: $spacing-unit $spacing-unit * 2; + padding-right: $spacing-unit; + + &__grid { + $item-size: 26px; + + flex-grow: 1; + display: grid; + grid-template-columns: repeat(5, $item-size); + justify-content: space-between; + row-gap: $spacing-unit; + + &__item { + position: relative; + width: $item-size; + height: $item-size; + border-radius: 3px; + + &.selected { + &::before { + content: ""; + position: absolute; + top: -$spacing-unit/2; + left: -$spacing-unit/2; + width: 100%; + height: 100%; + border: $spacing-unit/2 solid rgba(0, 0, 0, 0.1); + border-radius: 3px; + } + } + } + } + + &__side { + width: 32px; + margin-left: $spacing-unit/2; + + &__btn-close { + position: relative; + top: -$spacing-unit/4; + } + } +} diff --git a/src/components/specific/groups/group-card/group-card-color-picker/GroupCardColorPicker.vue b/src/components/specific/groups/group-card/group-card-color-picker/GroupCardColorPicker.vue new file mode 100644 index 000000000..736c0e45d --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-color-picker/GroupCardColorPicker.vue @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + diff --git a/src/components/specific/groups/group-card/group-card-color-picker/colors.js b/src/components/specific/groups/group-card/group-card-color-picker/colors.js new file mode 100644 index 000000000..51852fe12 --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-color-picker/colors.js @@ -0,0 +1,32 @@ +export default [ + "#FFE4C4", + "#FFA500", + "#FF7F50", + "#FF4500", + "#800000", + "#F0E68C", + "#D2B48C", + "#CD853F", + "#A0522D", + "#A52A2A", + "#ADFF2F", + "#9ACD32", + "#808000", + "#008000", + "#006400", + "#E0FFFF", + "#87CEEB", + "#4682B4", + "#0000FF", + "#00008B", + "#DDA0DD", + "#FF69B4", + "#FF00FF", + "#800080", + "#4B0082", + "#F8F8FF", + "#C0C0C0", + "#A9A9A9", + "#808080", + "#000000" +]; diff --git a/src/components/specific/groups/group-card/group-card-delete-guard/GroupCardDeleteGuard.scss b/src/components/specific/groups/group-card/group-card-delete-guard/GroupCardDeleteGuard.scss new file mode 100644 index 000000000..89fafda4c --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-delete-guard/GroupCardDeleteGuard.scss @@ -0,0 +1,25 @@ +.group-card-delete-guard { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + height: 100%; + padding: $spacing-unit $spacing-unit * 2 $spacing-unit * 2; + + &__title { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + font-weight: bold; + } + + &__message { + width: 100%; + color: $color-tertiary-dark; + } + + &__btn-submit { + width: 100%; + } +} diff --git a/src/components/specific/groups/group-card/group-card-delete-guard/GroupCardDeleteGuard.vue b/src/components/specific/groups/group-card/group-card-delete-guard/GroupCardDeleteGuard.vue new file mode 100644 index 000000000..62e163f7c --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-delete-guard/GroupCardDeleteGuard.vue @@ -0,0 +1,73 @@ + + + + {{ $t("GroupCardDeleteGuard.title") }} + + + + + + {{ $t("GroupCardDeleteGuard.message", { name: group.name }) }} + + + {{ $t("GroupCardDeleteGuard.deleteButtonText") }} + + + + + + + diff --git a/src/components/specific/groups/group-card/group-card-update-form/GroupCardUpdateForm.scss b/src/components/specific/groups/group-card/group-card-update-form/GroupCardUpdateForm.scss new file mode 100644 index 000000000..74d231e01 --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-update-form/GroupCardUpdateForm.scss @@ -0,0 +1,21 @@ +.group-card-update-form { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + height: 100%; + padding: $spacing-unit $spacing-unit * 2 $spacing-unit * 2; + + &__title { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + font-weight: bold; + } + + &__input, + &__btn-submit { + width: 100%; + } +} diff --git a/src/components/specific/groups/group-card/group-card-update-form/GroupCardUpdateForm.vue b/src/components/specific/groups/group-card/group-card-update-form/GroupCardUpdateForm.vue new file mode 100644 index 000000000..a22d43546 --- /dev/null +++ b/src/components/specific/groups/group-card/group-card-update-form/GroupCardUpdateForm.vue @@ -0,0 +1,108 @@ + + + + {{ $t("GroupCardUpdateForm.title") }} + + + + + + + {{ $t("GroupCardUpdateForm.submitButtonText") }} + + + + + + + diff --git a/src/components/specific/users/user-avatar-list/UserAvatarList.scss b/src/components/specific/users/user-avatar-list/UserAvatarList.scss new file mode 100644 index 000000000..a4909db12 --- /dev/null +++ b/src/components/specific/users/user-avatar-list/UserAvatarList.scss @@ -0,0 +1,18 @@ +.user-avatar-list { + display: grid; + + &__item { + border: 1px solid $color-white; + } + + &__tail-item { + display: flex; + justify-content: center; + align-items: center; + border: 1px solid $color-white; + border-radius: 50%; + font-weight: bold; + background-color: $color-primary; + color: $color-tertiary-lightest; + } +} diff --git a/src/components/specific/users/user-avatar-list/UserAvatarList.vue b/src/components/specific/users/user-avatar-list/UserAvatarList.vue new file mode 100644 index 000000000..3b2683505 --- /dev/null +++ b/src/components/specific/users/user-avatar-list/UserAvatarList.vue @@ -0,0 +1,77 @@ + + + + + + {{ `+ ${users.length - length + 1}` }} + + + + + + + + diff --git a/src/components/specific/users/user-avatar/UserAvatar.scss b/src/components/specific/users/user-avatar/UserAvatar.scss new file mode 100644 index 000000000..93f6be82f --- /dev/null +++ b/src/components/specific/users/user-avatar/UserAvatar.scss @@ -0,0 +1,24 @@ +.user-avatar { + min-width: 32px; + min-height: 32px; + + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + + &--primary { + background-color: $color-primary; + color: $color-tertiary-lightest; + } + + &--secondary { + background-color: $color-secondary; + color: $color-primary; + } + + &--tertiary { + background-color: $color-tertiary-lightest; + color: $color-primary; + } +} diff --git a/src/components/specific/users/user-avatar/UserAvatar.vue b/src/components/specific/users/user-avatar/UserAvatar.vue new file mode 100644 index 000000000..90ffdee9c --- /dev/null +++ b/src/components/specific/users/user-avatar/UserAvatar.vue @@ -0,0 +1,48 @@ + + + + + + + + {{ initials }} + + + + + + + diff --git a/src/i18n/lang/en.js b/src/i18n/lang/en.js index a68b88991..ebc9933f3 100644 --- a/src/i18n/lang/en.js +++ b/src/i18n/lang/en.js @@ -181,6 +181,26 @@ export default { } }, + GroupCardActionMenu: { + renameButtonText: "Rename", + changeColorButtonText: "Change color", + deleteButtonText: "Delete" + }, + + GroupCardDeleteGuard: { + title: "Delete group", + message: + "You are about to (definitely) delete group {name}, are you sure ?", + deleteButtonText: "Delete" + }, + + GroupCardUpdateForm: { + title: "Rename group", + inputPlaceholder: "Name", + inputErrorMessage: "Invalid group name", + submitButtonText: "Rename" + }, + InvitationCard: { pendingMessage: "Invited - Pending.", resendLinkText: "Send invitation again ?" diff --git a/src/i18n/lang/fr.js b/src/i18n/lang/fr.js index 1d2c5051a..fae014e6f 100644 --- a/src/i18n/lang/fr.js +++ b/src/i18n/lang/fr.js @@ -180,6 +180,26 @@ export default { } }, + GroupCardActionMenu: { + renameButtonText: "Renommer", + changeColorButtonText: "Modifier la couleur", + deleteButtonText: "Supprimer" + }, + + GroupCardDeleteGuard: { + title: "Supprimer le groupe", + message: + "Êtes vous sûr de vouloir supprimer (définitivement) le groupe {name} ?", + deleteButtonText: "Supprimer" + }, + + GroupCardUpdateForm: { + title: "Renommer le groupe", + inputPlaceholder: "Nom", + inputErrorMessage: "Nom de groupe invalide", + submitButtonText: "Renommer" + }, + InvitationCard: { pendingMessage: "Invité - Sans réponse.", resendLinkText: "Renvoyer l'invitation ?" diff --git a/src/server/GroupService.js b/src/server/GroupService.js new file mode 100644 index 000000000..f3fec7eea --- /dev/null +++ b/src/server/GroupService.js @@ -0,0 +1,52 @@ +import apiClient from "./api-client"; + +class GroupService { + fetchProjectGroups(project) { + return [ + { + id: 1, + name: "My Group Name", + color: "#FF3D1E", + project, + members: [ + { + firstname: "Gaëlle", + lastname: "Leroux" + }, + { + firstname: "Gaëtan", + lastname: "Lagier" + }, + { + firstname: "Hugo", + lastname: "Duroux" + }, + { + firstname: "Nicolas", + lastname: "Richel" + }, + { + firstname: "François", + lastname: "Thierry" + } + ] + } + ]; + } + + createGroup(project, group) { + return group; + } + + updateGroup(project, group) { + return group; + } + + deleteGroup(project, group) { + return group; + } +} + +const service = new GroupService(); + +export default service; diff --git a/src/state/groups.js b/src/state/groups.js new file mode 100644 index 000000000..9e47bac28 --- /dev/null +++ b/src/state/groups.js @@ -0,0 +1,56 @@ +import { reactive, readonly, toRefs } from "vue"; +import GroupService from "@/server/GroupService"; + +const state = reactive({ + projectGroups: [], + currentGroup: null +}); + +const loadProjectGroups = async project => { + const groups = await GroupService.fetchProjectGroups(project); + state.projectGroups = groups; + return groups; +}; + +const createGroup = async (project, group) => { + const newGroup = await GroupService.createGroup(project, group); + state.projectGroups = [newGroup].concat(state.projectGroups); + return newGroup; +}; + +const updateGroup = async (project, group) => { + const newGroup = await GroupService.updateGroup(project, group); + softUpdateGroup(newGroup); + return newGroup; +}; + +const softUpdateGroup = group => { + // TODO: update state + return group; +}; + +const deleteGroup = async (project, group) => { + await GroupService.deleteGroup(project, group); + softDeleteGroup(group); + return group; +}; + +const softDeleteGroup = group => { + // TODO: update state + return group; +}; + +export function useGroups() { + const readOnlyState = readonly(state); + return { + // References + ...toRefs(readOnlyState), + // Methods + loadProjectGroups, + createGroup, + updateGroup, + softUpdateGroup, + deleteGroup, + softDeleteGroup + }; +} diff --git a/src/views/project-board/ProjectBoard.vue b/src/views/project-board/ProjectBoard.vue index 83600e3cf..ff2c5f927 100644 --- a/src/views/project-board/ProjectBoard.vue +++ b/src/views/project-board/ProjectBoard.vue @@ -10,8 +10,8 @@ height="32px" tabSize="100px" :tabs="tabs" - :selected="currentTab.id" - @tab-click="selectTab" + :selected="0" + @tab-click="changeView($event.id)" /> @@ -22,7 +22,7 @@ - + @@ -30,7 +30,7 @@