-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #246 from codex-team/join-route-handle
feat(pages): Join route handle
- Loading branch information
Showing
10 changed files
with
246 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { InvitationHash } from '@/domain/entities/NoteSettings'; | ||
import type { TeamMember } from '@/domain/entities/Team'; | ||
import { teamService } from '@/domain/index'; | ||
|
||
interface useTeamComposableState { | ||
/** | ||
* Function for adding user to note's team by invitation hash | ||
* @param hash - invitation hash of the certain note | ||
* @returns Team member or null | ||
*/ | ||
joinNoteTeamByHash: (hash: InvitationHash) => Promise<TeamMember | null>; | ||
} | ||
|
||
export default function useTeam(): useTeamComposableState { | ||
/** | ||
* Function for adding user to note's team by invitation hash | ||
* @param hash - invitation hash of the certain note | ||
* @returns Team member or null | ||
*/ | ||
async function joinNoteTeamByHash(hash: InvitationHash): Promise<TeamMember | null> { | ||
return await teamService.joinNoteTeamByHash(hash); | ||
} | ||
|
||
return { | ||
joinNoteTeamByHash, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { InvitationHash } from '@/domain/entities/NoteSettings'; | ||
import type { TeamMember } from '@/domain/entities/Team'; | ||
|
||
/** | ||
* Repository interface describes the methods that required by domain for its business logic implementation | ||
*/ | ||
export default interface TeamRepositoryInterface { | ||
/** | ||
* Function for adding user to note's team by invitation hash | ||
* @param hash - invitation hash of the certain note | ||
* @returns Team member or null | ||
*/ | ||
joinNoteTeamByHash: (hash: InvitationHash) => Promise<TeamMember | null>; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type TeamRepository from '@/domain/team.repository.interface'; | ||
import type { InvitationHash } from './entities/NoteSettings'; | ||
import type { TeamMember } from './entities/Team'; | ||
|
||
/** | ||
* Team service | ||
*/ | ||
export default class TeamService { | ||
/** | ||
* Team repository | ||
*/ | ||
private readonly teamRepository: TeamRepository; | ||
|
||
constructor(teamRepository: TeamRepository) { | ||
this.teamRepository = teamRepository; | ||
} | ||
|
||
/** | ||
* Function for adding user to note's team by invitation hash | ||
* @param hash - invitation hash of the certain note | ||
* @returns Team member or null | ||
*/ | ||
public async joinNoteTeamByHash(hash: InvitationHash): Promise<TeamMember | null> { | ||
return this.teamRepository.joinNoteTeamByHash(hash); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import type TeamRepositoryInterface from '@/domain/team.repository.interface'; | ||
import type NotesApiTransport from '@/infrastructure/transport/notes-api'; | ||
import type { InvitationHash } from '@/domain/entities/NoteSettings'; | ||
import type { TeamMember } from '@/domain/entities/Team'; | ||
|
||
/** | ||
* Team repository | ||
*/ | ||
export default class TeamRepository implements TeamRepositoryInterface { | ||
/** | ||
* Transport instance | ||
*/ | ||
private readonly transport: NotesApiTransport; | ||
/** | ||
* Note repository constructor | ||
* @param notesApiTransport - notes api transport instance | ||
*/ | ||
constructor(notesApiTransport: NotesApiTransport) { | ||
this.transport = notesApiTransport; | ||
} | ||
|
||
/** | ||
* Function for adding user to note's team by invitation hash | ||
* @param hash - invitation hash of the certain note | ||
* @returns Team member or null | ||
*/ | ||
public async joinNoteTeamByHash(hash: InvitationHash): Promise<TeamMember | null> { | ||
let res: TeamMember | null = null; | ||
|
||
res = await this.transport.post<TeamMember | null>({ endpoint: '/join/' + hash }); | ||
|
||
return res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<template> | ||
<div :class="$style['message']"> | ||
{{ message }} | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { useRouter } from 'vue-router'; | ||
import { ref, watch } from 'vue'; | ||
import useTeam from '@/application/services/useTeam'; | ||
import { useAppState } from '@/application/services/useAppState'; | ||
import useAuth from '@/application/services/useAuth'; | ||
import type { TeamMember } from '@/domain/entities/Team'; | ||
import { InvitationHash } from '@/domain/entities/NoteSettings'; | ||
import { useI18n } from 'vue-i18n'; | ||
const { user } = useAppState(); | ||
const { t } = useI18n(); | ||
const { showGoogleAuthPopup } = useAuth(); | ||
const { joinNoteTeamByHash } = useTeam(); | ||
const router = useRouter(); | ||
const props = defineProps<{ | ||
invitationHash: InvitationHash; | ||
}>(); | ||
/** | ||
* Message to be displayed as a heading of join page | ||
*/ | ||
const message = ref(t('join.title')); | ||
const teamMember = ref<TeamMember | null>(null); | ||
async function handleJoin(): Promise<void> { | ||
try { | ||
teamMember.value = await joinNoteTeamByHash(props.invitationHash); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
/** | ||
* Handle errors which are related to wrong invitation hash specified | ||
*/ | ||
if (error.message === 'FST_ERR_VALIDATION') { | ||
message.value = t('join.messages.validationError'); | ||
} | ||
/** | ||
* Handle error related to expired invitation link | ||
*/ | ||
if (error.message === 'Wrong invitation') { | ||
message.value = t('join.messages.linkExpired'); | ||
} | ||
/** | ||
* Handle errors related to unauthorized state | ||
*/ | ||
if (error.message === 'You must be authenticated to access this resource') { | ||
message.value = t('join.messages.unauthorized'); | ||
showGoogleAuthPopup(); | ||
} | ||
} | ||
} | ||
/** | ||
* Check if we got id of the note to redirect | ||
*/ | ||
if (teamMember.value?.noteId) { | ||
router.push(`/note/${teamMember.value?.noteId}`); | ||
/** | ||
* @todo implement success alert | ||
*/ | ||
} | ||
} | ||
/** | ||
* Watching authorization of the user | ||
*/ | ||
watch(user, async () => { | ||
await handleJoin(); | ||
}, { immediate: true }); | ||
</script> | ||
|
||
<style lang="postcss" module> | ||
.message { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
} | ||
</style> |