Skip to content

Commit

Permalink
Merge pull request #85 from traPtitech/feat/contest_team_new
Browse files Browse the repository at this point in the history
/contests/:contestId/teams/newページの作成
  • Loading branch information
mehm8128 authored Oct 5, 2023
2 parents 611ad24 + 23cf728 commit 1f67b3d
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/pages/ContestTeamEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ const deleteContestTeam = async () => {
:header-texts="[
{ title: 'Contests', url: '/contests' },
{ title: contest.name, url: `/contests/${contestId}` },
{
title: 'Teams',
url: `/contests/${contestId}`
},
{
title: contestTeam.name,
url: `/contests/${contestId}/teams/${contestTeamId}`
Expand Down
145 changes: 145 additions & 0 deletions src/pages/ContestTeamNew.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<script lang="ts" setup>
import ContentHeader from '/@/components/Layout/ContentHeader.vue'
import PageContainer from '/@/components/Layout/PageContainer.vue'
import BaseButton from '/@/components/UI/BaseButton.vue'
import apis from '/@/lib/apis'
import type { AddContestTeamRequest, ContestDetail, User } from '/@/lib/apis'
import { RouterLink, useRouter } from 'vue-router'
import useParam from '/@/use/param'
import MemberInput from '/@/components/UI/MemberInput.vue'
import FormTextArea from '/@/components/UI/FormTextArea.vue'
import FormInput from '/@/components/UI/FormInput.vue'
import { computed, ref } from 'vue'
import LabeledForm from '/@/components/Form/LabeledForm.vue'
import { isValidLength, isValidUrl } from '/@/use/validate'
import { useToast } from 'vue-toastification'
const router = useRouter()
const toast = useToast()
const contestId = useParam('contestId')
const contest: ContestDetail = (await apis.getContest(contestId.value)).data
const formValues = ref<Required<AddContestTeamRequest>>({
name: '',
result: '',
link: '',
description: ''
})
const members = ref<User[]>([])
const isSending = ref(false)
const canSubmit = computed(
() =>
!isSending.value &&
isValidLength(formValues.value.name, 1, 32) &&
isValidLength(formValues.value.result, 0, 32) &&
(formValues.value.link !== '' ? isValidUrl(formValues.value.link) : true) &&
isValidLength(formValues.value.description, 1, 256) &&
members.value.length > 0
)
const createContestTeam = async () => {
isSending.value = true
try {
const requestData: AddContestTeamRequest = {
...formValues.value,
result: formValues.value.result || undefined,
link: formValues.value.link || undefined
}
const res = (await apis.addContestTeam(contestId.value, requestData)).data
await apis.addContestTeamMembers(contestId.value, res.id, {
members: members.value.map(member => member.id)
})
toast.success('コンテストチ-ムを追加しました')
router.push(`/contests/${contestId.value}`)
} catch {
toast.error('コンテストチームの追加に失敗しました')
}
isSending.value = false
}
</script>

<template>
<page-container>
<div :class="$style.headerContainer">
<content-header
icon-name="mdi:trophy-outline"
:header-texts="[
{ title: 'Contests', url: '/contests' },
{ title: contest.name, url: `/contests/${contestId}` },
{
title: 'Teams',
url: `/contests/${contestId}`
},
{ title: 'New', url: `/contests/${contestId}/teams/new` }
]"
detail="コンテストチームを追加します。"
:class="$style.header"
/>
</div>
<form>
<labeled-form required label="チーム名" :class="$style.labeledForm">
<form-input v-model="formValues.name" :limit="32" />
</labeled-form>
<labeled-form label="結果" :class="$style.labeledForm">
<form-input v-model="formValues.result" :limit="32" />
</labeled-form>
<labeled-form label="リンク" :class="$style.labeledForm">
<form-input
v-model="formValues.link"
has-anchor
placeholder="https://"
/>
</labeled-form>
<labeled-form required label="メンバー" :class="$style.labeledForm">
<member-input v-model="members" />
</labeled-form>
<labeled-form required label="説明" :class="$style.labeledForm">
<form-text-area
v-model="formValues.description"
:limit="256"
:rows="3"
/>
</labeled-form>
</form>

<div :class="$style.buttonContainer">
<router-link :to="`/contests/${contestId}`" :class="$style.link">
<base-button type="secondary" icon="mdi:arrow-left">Back</base-button>
</router-link>
<base-button
:is-disabled="!canSubmit"
type="primary"
icon="mdi:plus"
@click="createContestTeam"
>
Create
</base-button>
</div>
</page-container>
</template>

<style lang="scss" module>
.headerContainer {
display: flex;
justify-content: space-between;
align-items: center;
}
.header {
margin: 4rem 0 2rem;
}
.labeledForm {
margin-bottom: 2rem;
}
.link {
text-decoration: none;
color: inherit;
}
.buttonContainer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 4rem;
}
</style>
6 changes: 6 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Contests = () => import('/@/pages/Contests.vue')
const Contest = () => import('/@/pages/Contest.vue')
const ContestNew = () => import('/@/pages/ContestNew.vue')
const ContestEdit = () => import('/@/pages/ContestEdit.vue')
const ContestTeamNew = () => import('/@/pages/ContestTeamNew.vue')
const ContestTeamEdit = () => import('/@/pages/ContestTeamEdit.vue')

const routes = [
Expand Down Expand Up @@ -61,6 +62,11 @@ const routes = [
name: 'ContestEdit',
component: ContestEdit
},
{
path: '/contests/:contestId/teams/new',
name: 'ContestTeamNew',
component: ContestTeamNew
},
{
path: '/contests/:contestId/teams/:teamId/edit',
name: 'ContestTeamEdit',
Expand Down

0 comments on commit 1f67b3d

Please sign in to comment.