Skip to content

Commit

Permalink
Merge pull request #34 from traPtitech/feat/landing-page
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-20 authored Dec 11, 2024
2 parents a492d78 + 8a4bb30 commit b298397
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 154 deletions.
244 changes: 244 additions & 0 deletions components/landing-page/landing-page.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
<script lang="ts" setup>
import type { QuestionnaireSummary } from './type';
defineProps<{
questionnaires: QuestionnaireSummary[];
questionnairesDraft: QuestionnaireSummary[];
questionnairesHasDraft: QuestionnaireSummary[];
questionnairesTargetingMe: QuestionnaireSummary[];
questionnairesAdministeredByMe: QuestionnaireSummary[];
questionnairesRespondedByMe: QuestionnaireSummary[];
}>();
const formatResponseDueDateTime = (questionnaire: QuestionnaireSummary) => {
const due = questionnaire.response_due_date_time;
if (due === undefined) return '期限なし';
const date = new Date(due);
return formatRelativeDate(date);
};
const checkIsDueOver = (questionnaire: QuestionnaireSummary) => {
const due = questionnaire.response_due_date_time;
if (due === undefined) return false;
const date = new Date(due);
return date.getTime() < Date.now();
};
</script>

<template>
<div class="landing-page-container">
<div class="title-logo">
<img src="~/assets/img/logo.svg" alt="anke-to" width="320" />
</div>

<div class="questionnaire-list-containers">
<div class="questionnaire-list-container questionnaires-draft">
<div class="questionnaire-list-container-title">
まだ投稿していないアンケート
</div>
<QuestionnaireList :questionnaires="questionnairesDraft">
<template #action="{ questionnaire }">
<a
class="questionnaire-card-action-link"
:href="`/questionnaires/${questionnaire.questionnaire_id}/edit`"
>
<Icon name="mdi:square-edit-outline" size="24px" />
<span>アンケートを編集</span>
</a>
</template>
</QuestionnaireList>
</div>

<div class="questionnaire-list-container questionnaires-targeting-me">
<div class="questionnaire-list-container-title">
回答の下書きがあるアンケート
</div>
<QuestionnaireList :questionnaires="questionnairesHasDraft">
<template #tip="{ questionnaire }">
<div class="questionnaire-card-tip">
<Icon name="mdi:alarm" size="20px" />
<span>
{{ formatResponseDueDateTime(questionnaire) }}
</span>
</div>
</template>
<template #action="{ questionnaire }">
<a
v-if="!checkIsDueOver(questionnaire)"
class="questionnaire-card-action-link"
>
<Icon name="mdi:text-box-edit-outline" size="24px" />
<span>回答を編集 (?)</span>
</a>
</template>
</QuestionnaireList>
</div>

<div class="questionnaire-list-container questionnaires-targeting-me">
<div class="questionnaire-list-container-title">
自分が対象になっているアンケート
</div>
<QuestionnaireList :questionnaires="questionnairesTargetingMe">
<template #tip="{ questionnaire }">
<div class="questionnaire-card-tip">
<Icon name="mdi:alarm" size="20px" />
<span>
{{ formatResponseDueDateTime(questionnaire) }}
</span>
</div>
</template>
<template #action="{ questionnaire }">
<a
v-if="!checkIsDueOver(questionnaire)"
class="questionnaire-card-action-link"
:href="`/questionnaires/${questionnaire.questionnaire_id}/responses/new`"
>
<Icon name="mdi:form-select" size="24px" />
<span>アンケートに回答</span>
</a>
</template>
</QuestionnaireList>
</div>

<div
class="questionnaire-list-container questionnaires-administrated-by-me"
>
<div class="questionnaire-list-container-title">
自分が管理しているアンケート
</div>
<QuestionnaireList :questionnaires="questionnairesAdministeredByMe">
<template #tip="{ questionnaire }">
<div class="questionnaire-card-tip">
<Icon name="mdi:alarm" size="20px" />
<span>
{{ formatResponseDueDateTime(questionnaire) }}
</span>
</div>
</template>
<template #action="{ questionnaire }">
<a
class="questionnaire-card-action-link"
:href="`/questionnaires/${questionnaire.questionnaire_id}/edit`"
>
<Icon name="mdi:square-edit-outline" size="24px" />
<span>アンケートを編集</span>
</a>
<a
class="questionnaire-card-action-link"
:href="`/questionnaires/${questionnaire.questionnaire_id}/result`"
>
<Icon name="mdi:forum-outline" size="24px" />
<span>結果を確認</span>
</a>
</template>
</QuestionnaireList>
</div>

<div class="questionnaire-list-container questionnaires-responded-by-me">
<div class="questionnaire-list-container-title">
自分が回答したアンケート
</div>
<QuestionnaireList :questionnaires="questionnairesRespondedByMe">
<template #tip="{ questionnaire }">
<div class="questionnaire-card-tip">
<Icon name="mdi:alarm" size="20px" />
<span>
{{ formatResponseDueDateTime(questionnaire) }}
</span>
</div>
</template>
<template #action="{ questionnaire }">
<a
v-if="!checkIsDueOver(questionnaire)"
class="questionnaire-card-action-link"
>
<Icon name="mdi:text-box-edit-outline" size="24px" />
<span>回答を編集(?)</span>
</a>
</template>
</QuestionnaireList>
</div>

<div class="questionnaire-list-container all-questionnaires">
<div class="questionnaire-list-container-title">
最近投稿されたアンケート
</div>
<QuestionnaireList :questionnaires="questionnaires">
<template #tip="{ questionnaire }">
<div class="questionnaire-card-tip">
<Icon name="mdi:alarm" size="20px" />
<span>
{{ formatResponseDueDateTime(questionnaire) }}
</span>
</div>
</template>
<template #action="{ questionnaire }">
<a
v-if="!checkIsDueOver(questionnaire)"
class="questionnaire-card-action-link"
:href="`/questionnaires/${questionnaire.questionnaire_id}/responses/new`"
>
<Icon name="mdi:form-select" size="24px" />
<span>アンケートに回答</span>
</a>
</template>
</QuestionnaireList>
</div>
</div>
</div>
</template>

<style lang="scss" scoped>
.landing-page-container {
max-width: 1200px;
margin: 0 auto;
}
.title-logo {
max-width: 320px;
margin: 60px auto 0 auto;
}
.questionnaire-list-containers {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 32px;
margin-top: 64px;
}
@media screen and (max-width: 1200px) {
.questionnaire-list-containers {
grid-template-columns: 1fr;
}
}
.questionnaire-list-container {
}
.questionnaire-list-container-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 16px;
}
.questionnaire-card-action-link {
font-weight: bold;
color: $color-primary;
background-color: mix(white, $color-primary, 92%);
padding: 8px 16px;
width: fit-content;
border-radius: var(--border-radius);
text-decoration: none;
display: flex;
align-items: center;
gap: 8px;
}
.questionnaire-card-tip {
display: inline-flex;
height: 24px;
align-items: center;
gap: 2px;
font-size: 14px;
}
</style>
94 changes: 94 additions & 0 deletions components/landing-page/questionnaire-list.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<script lang="ts" setup>
import type { QuestionnaireSummary } from './type';
defineProps<{
questionnaires: QuestionnaireSummary[];
}>();
</script>

<template>
<div>
<div
v-for="questionnaire in questionnaires"
:key="questionnaire.questionnaire_id"
class="questionnaire-card"
>
<div class="questionnaire-card-title-container">
<a
class="questionnaire-card-title"
:href="`/questionnaires/${questionnaire.questionnaire_id}`"
>
{{ questionnaire.title }}
</a>
<div class="questionnaire-card-tip-section">
<slot name="tip" v-bind="{ questionnaire }" />
</div>
</div>

<div class="questionnaire-card-description">
{{ questionnaire.description }}
</div>

<div class="questionnaire-card-action-section">
<slot name="action" v-bind="{ questionnaire }" />
</div>
</div>
</div>
</template>

<style lang="scss" scoped>
.questionnaire-card {
border: 1px solid var(--surface-d);
border-radius: var(--border-radius);
padding: 16px;
margin: 16px 0;
}
.questionnaire-card-title-container {
display: flex;
justify-content: space-between;
gap: 4px;
}
.questionnaire-card-title {
min-width: 0;
flex: 1;
font-weight: bold;
font-size: 18px;
color: $color-primary;
margin-bottom: 8px;
text-decoration: none;
overflow: hidden;
display: -webkit-box;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
max-height: 56px;
}
.questionnaire-card-title:hover {
text-decoration: underline;
}
.questionnaire-card-tip-section {
display: flex;
gap: 4px;
}
.questionnaire-card-description {
overflow: hidden;
display: -webkit-box;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
max-height: 72px;
}
.questionnaire-card-action-section {
display: flex;
justify-content: flex-end;
margin-top: 16px;
gap: 16px;
}
</style>
4 changes: 4 additions & 0 deletions components/landing-page/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { components } from '~/composables/type-fetch/anke-to/openapi';

export type QuestionnaireSummary =
components['schemas']['QuestionnaireSummary'];
Loading

0 comments on commit b298397

Please sign in to comment.