added header, footer, eslint/prettier, and typedoc
This commit is contained in:
165
components/DropDown.vue
Normal file
165
components/DropDown.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<script setup lang="ts">
|
||||
import type { DropDownProperty } from "#imports";
|
||||
|
||||
const property = defineProps<DropDownProperty>();
|
||||
|
||||
const isOpen = ref<boolean>(false);
|
||||
const showInMobile = ref<boolean>(property.showInMobile);
|
||||
const { viewPortType } = useWindowDimensions();
|
||||
|
||||
const listAlignment = ref<typeof DropDownAlignment | number>(
|
||||
property.alignment | DropDownAlignment.Left
|
||||
);
|
||||
|
||||
const alignmentClass = computed(() => ({
|
||||
"left-aligned-list": listAlignment.value === DropDownAlignment.Left,
|
||||
"right-aligned-list": listAlignment.value === DropDownAlignment.Right,
|
||||
}));
|
||||
|
||||
const handleMouseHoverEvent = (event: Event) => {
|
||||
const eventType = event.type;
|
||||
if (property.mode !== DropDownMode.onMouseHover) return;
|
||||
if (eventType === "mouseover") {
|
||||
isOpen.value = true;
|
||||
} else if (eventType === "mouseleave") {
|
||||
isOpen.value = false;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
const handleClickEvent = () => {
|
||||
if (property.mode !== DropDownMode.onClick) return;
|
||||
isOpen.value = !isOpen.value;
|
||||
return;
|
||||
};
|
||||
|
||||
const handleFocusOutEvent = () => {
|
||||
if (property.mode !== DropDownMode.onClick) return;
|
||||
isOpen.value = false;
|
||||
return;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="dropdown-menu"
|
||||
:class="alignmentClass"
|
||||
v-on="{
|
||||
mouseover: handleMouseHoverEvent,
|
||||
mouseleave: handleMouseHoverEvent,
|
||||
}"
|
||||
v-if="
|
||||
(showInMobile === true && viewPortType !== ViewPortType.DESKTOP) ||
|
||||
(showInMobile === false && viewPortType !== ViewPortType.MOBILE)
|
||||
"
|
||||
>
|
||||
<button
|
||||
class="dropdown-label"
|
||||
v-on="{
|
||||
click: handleClickEvent,
|
||||
focusout: handleFocusOutEvent,
|
||||
}"
|
||||
>
|
||||
{{ property.label }}
|
||||
</button>
|
||||
<Transition name="dropdown-fade">
|
||||
<div class="dropdown-item-list" v-if="isOpen">
|
||||
<ul>
|
||||
<li
|
||||
v-for="entry in property.entries"
|
||||
:key="property.entries.indexOf(entry)"
|
||||
>
|
||||
<NuxtLink :to="entry.link">{{ entry.text }}</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.dropdown-fade-enter-active,
|
||||
.dropdown-fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-fade-enter-from,
|
||||
.dropdown-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
display: inline-block;
|
||||
width: fit-content;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-label {
|
||||
background: none;
|
||||
width: fit-content;
|
||||
padding: 1rem 2rem;
|
||||
border: transparent solid 3px;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
color: var(--neptune1);
|
||||
}
|
||||
|
||||
.dropdown-label:hover {
|
||||
cursor: pointer;
|
||||
color: var(--andromeda);
|
||||
border-top: currentColor solid 3px;
|
||||
transition: 0.2s linear;
|
||||
}
|
||||
|
||||
.left-aligned-list {
|
||||
text-align: left;
|
||||
& .dropdown-item-list {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.right-aligned-list {
|
||||
text-align: right;
|
||||
& .dropdown-item-list {
|
||||
right: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item-list {
|
||||
display: block;
|
||||
background: var(--neptune1);
|
||||
color: var(--starlight);
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: auto;
|
||||
min-width: 100%;
|
||||
width: fit-content;
|
||||
text-wrap: nowrap;
|
||||
& ul {
|
||||
list-style: none;
|
||||
padding: 0 0.25rem;
|
||||
}
|
||||
& ul li {
|
||||
margin: 0.5rem 0;
|
||||
transition: 0.2s linear;
|
||||
}
|
||||
& ul li:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
& ul li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
& ul li a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
color: currentColor;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
& ul li:hover a {
|
||||
text-decoration: currentColor underline dashed;
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,7 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
Component: newslist
|
||||
</div>
|
||||
<div>Component: newslist</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,9 +1,274 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import LogoSVG from "public/sera-logo-no-text.svg";
|
||||
import SiteInfo from "assets/siteinfo.json";
|
||||
|
||||
const showTwitterIcon = ref<boolean>(false);
|
||||
|
||||
const getTimeRequest = await useFetch("/api/getTime");
|
||||
const time: Date = new Date(getTimeRequest.data.value as number);
|
||||
|
||||
const timeGenerated: string = time.toLocaleString("ja-JP-u-ca-japanese", {
|
||||
dateStyle: "medium",
|
||||
timeStyle: "short",
|
||||
});
|
||||
|
||||
const showThePast = (event: Event) => {
|
||||
const eventType = event.type;
|
||||
if (eventType === "mouseover") {
|
||||
showTwitterIcon.value = true;
|
||||
} else if (eventType === "mouseleave") {
|
||||
showTwitterIcon.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
Component: TheFooter
|
||||
</div>
|
||||
<footer>
|
||||
<div class="footer-wrapper">
|
||||
<div class="logo">
|
||||
<LogoSVG />
|
||||
</div>
|
||||
<div class="top-column">
|
||||
<div class="summary">
|
||||
<h3>{{ SiteInfo.clubNameLong }}</h3>
|
||||
<p>
|
||||
宇宙分野に興味ある学生が<wbr />集い、<wbr />宇宙理工学に<wbr />関する知識を<wbr />身に付けると共に、<wbr />
|
||||
宇宙分野に関連する<wbr />各種競技会へ<wbr />参加して<wbr />人間力と実践力を<wbr />養うことを目的に<wbr />活動しています。
|
||||
</p>
|
||||
<NuxtLink to="/about/sera"
|
||||
>About {{ SiteInfo.clubNameAbbreviation }}</NuxtLink
|
||||
>
|
||||
</div>
|
||||
<div class="links">
|
||||
<ul>
|
||||
<li>
|
||||
<NuxtLink to="/"> Home </NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/news"> News </NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/projects"> Projects </NuxtLink>
|
||||
<ul>
|
||||
<li>
|
||||
<NuxtLink to="/projects/rocket">
|
||||
Rocket
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/projects/cansat">
|
||||
CanSat
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/projects/kosen-x">
|
||||
CubeSat Kosen-x
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/projects/edu-robot">
|
||||
Edu-Robot
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/about/sera">
|
||||
About {{ SiteInfo.clubNameAbbreviation }}
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sns-list">
|
||||
<h3>
|
||||
{{ SiteInfo.clubNameAbbreviation
|
||||
}}<wbr />を<wbr />フォロー<wbr />する
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<NuxtLink
|
||||
to="https://twitter.com/SERA_NITGC"
|
||||
target="_blank"
|
||||
v-on="{
|
||||
mouseover: showThePast,
|
||||
mouseleave: showThePast,
|
||||
}"
|
||||
>
|
||||
<Transition name="show-the-past">
|
||||
<Icon
|
||||
name="simple-icons:x"
|
||||
v-show="!showTwitterIcon"
|
||||
/>
|
||||
</Transition>
|
||||
<Transition name="show-the-past">
|
||||
<Icon
|
||||
name="simple-icons:twitter"
|
||||
v-show="showTwitterIcon"
|
||||
/>
|
||||
</Transition>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink
|
||||
to="https://www.instagram.com/sera_nitgc_official"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon name="simple-icons:instagram" />
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-column">
|
||||
<p>最終更新: {{ timeGenerated }}</p>
|
||||
<p>
|
||||
このHPは{{
|
||||
SiteInfo.clubNameAbbreviation
|
||||
}}の学生が開発・運営しています
|
||||
</p>
|
||||
<p>
|
||||
© {{ SiteInfo.copyrightYear }} NIT-GC
|
||||
{{ SiteInfo.clubNameAbbreviation }} All Rights Reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.show-the-past-enter-active,
|
||||
.show-the-past-leave-active {
|
||||
transition: opacity 30s cubic-bezier(1, 0, 1, 0.75);
|
||||
}
|
||||
|
||||
.show-the-past-enter-from,
|
||||
.show-the-past-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
background: var(--ocean-blue);
|
||||
color: var(--sunlight);
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.footer-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: auto auto auto;
|
||||
max-width: 1400px;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding: 2rem 0;
|
||||
& h3 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
& p {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
& a {
|
||||
text-decoration: none;
|
||||
color: var(--sunlight);
|
||||
}
|
||||
& a:hover {
|
||||
text-decoration: currentColor underline dashed;
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: fit-content;
|
||||
& svg {
|
||||
width: auto;
|
||||
height: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
.top-column {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 5fr 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: var(--sunlight) solid 3px;
|
||||
}
|
||||
|
||||
.links ul {
|
||||
list-style: none;
|
||||
font-weight: 600;
|
||||
& li {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
& > li:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
& > li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sns-list h3 {
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.sns-list ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
li {
|
||||
margin-right: 0.5rem;
|
||||
a span {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
li:first-child {
|
||||
a {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
a span {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
li:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
li:hover {
|
||||
transform: scale(120%);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-column {
|
||||
display: flex;
|
||||
margin: 1rem auto;
|
||||
& > * {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Phone Style */
|
||||
@media screen and (max-width: 640px) {
|
||||
.top-column {
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: auto auto auto;
|
||||
}
|
||||
.summary {
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.sns-list {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
.bottom-column {
|
||||
display: block;
|
||||
& > * {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,44 +1,101 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import LogoSVG from "public/sera-logo-no-text.svg";
|
||||
import type { DropDownEntry } from "~/utils/dropDown";
|
||||
|
||||
const exploreDropDownEntries: Array<DropDownEntry> = [
|
||||
{ text: "Home", link: "/" },
|
||||
{ text: "Projects", link: "/projects" },
|
||||
{ text: "CanSat", link: "/projects/cansat" },
|
||||
{ text: "Edu-Robot", link: "/projects/edu-robot" },
|
||||
{ text: "CubeSat Kosen-X", link: "/projects/kosen-x" },
|
||||
{ text: "Rocket", link: "/projects/rocket" },
|
||||
{ text: "About", link: "/about" },
|
||||
];
|
||||
|
||||
const mediaDropDownEntries: Array<DropDownEntry> = [
|
||||
{ text: "News", link: "/news" },
|
||||
{ text: "Gallery", link: "/about/gallery" },
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
<NuxtLink to="/news">
|
||||
News
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/projects">
|
||||
Projects
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li>Link</li>
|
||||
<li>Contact</li>
|
||||
<li>
|
||||
<NuxtLink to="/about">
|
||||
About SERA
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
<NuxtLink to="/">
|
||||
<img ref="/sera-logo-no-text.svg">
|
||||
</NuxtLink>
|
||||
<ul>
|
||||
<li>
|
||||
<NuxtLink to="/">For non-member</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<NuxtLink to="/">Info</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<header>
|
||||
<div class="navigation-menu">
|
||||
<div id="header-left">
|
||||
<DropDown
|
||||
label="Explore"
|
||||
:mode="DropDownMode.onClick"
|
||||
:alignment="DropDownAlignment.Left"
|
||||
:entries="exploreDropDownEntries"
|
||||
:show-in-mobile="false"
|
||||
/>
|
||||
</div>
|
||||
<div id="logo-link">
|
||||
<NuxtLink to="/">
|
||||
<LogoSVG role="img" id="logo-img" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div id="header-right">
|
||||
<DropDown
|
||||
label="Media"
|
||||
:mode="DropDownMode.onClick"
|
||||
:alignment="DropDownAlignment.Right"
|
||||
:entries="mediaDropDownEntries"
|
||||
:show-in-mobile="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
div {
|
||||
display: grid;
|
||||
grid-row: 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
.navigation-menu {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
line-height: 1.8;
|
||||
padding: 1.25rem 3rem;
|
||||
height: 64px;
|
||||
background: var(--deep-space);
|
||||
}
|
||||
|
||||
#header-left,
|
||||
#header-right {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#header-left {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#header-right {
|
||||
flex-direction: row-reverse;
|
||||
& ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
justify-items: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
#logo-link {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
& a {
|
||||
width: fit-content;
|
||||
background: var(--moonlight);
|
||||
padding: 0.5rem;
|
||||
margin-top: -0.5rem;
|
||||
border-radius: 3rem;
|
||||
filter: drop-shadow(0 0 0.5rem var(--moonlight));
|
||||
}
|
||||
& a:hover {
|
||||
transform: scale(110%);
|
||||
transition: 0.2s ease-in;
|
||||
}
|
||||
}
|
||||
|
||||
#logo-img {
|
||||
width: 128px;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user