Next js でサービスを作っていく
yarn create next-app --example with-typescript my-next-app
で作成
UIを作るのにはchakra-uiを使ってそれでカバーできない部分にはtailwindcssを使用しスタイリングする
ページのレイアウトはこんな感じで
長いので折りたたみ
import React, { ReactNode, SVGProps } from "react";
import NextLink from "next/link";
import Head from "next/head";
import {
Flex,
Spacer,
Box,
useColorMode,
IconButton,
Link,
Heading,
useColorModeValue,
Container,
Text,
} from "@chakra-ui/react";
function FaSolidMoon(props: SVGProps<SVGSVGElement>) {
// 月
return (
<svg
focusable="false"
width="1.2em"
height="1.2em"
viewBox="0 0 512 512"
{...props}
>
<path
d="M283.211 512c78.962 0 151.079-35.925 198.857-94.792c7.068-8.708-.639-21.43-11.562-19.35c-124.203 23.654-238.262-71.576-238.262-196.954c0-72.222 38.662-138.635 101.498-174.394c9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256c0 141.309 114.511 256 256 256z"
fill="currentColor"
></path>
</svg>
);
}
function IcRoundWbSunny(props: SVGProps<SVGSVGElement>) {
// 太陽
return (
<svg
focusable="false"
width="1.4em"
height="1.4em"
viewBox="0 0 24 24"
{...props}
>
<path
d="M6.05 4.14l-.39-.39a.993.993 0 0 0-1.4 0l-.01.01a.984.984 0 0 0 0 1.4l.39.39c.39.39 1.01.39 1.4 0l.01-.01a.984.984 0 0 0 0-1.4zM3.01 10.5H1.99c-.55 0-.99.44-.99.99v.01c0 .55.44.99.99.99H3c.56.01 1-.43 1-.98v-.01c0-.56-.44-1-.99-1zm9-9.95H12c-.56 0-1 .44-1 .99v.96c0 .55.44.99.99.99H12c.56.01 1-.43 1-.98v-.97c0-.55-.44-.99-.99-.99zm7.74 3.21c-.39-.39-1.02-.39-1.41-.01l-.39.39a.984.984 0 0 0 0 1.4l.01.01c.39.39 1.02.39 1.4 0l.39-.39a.984.984 0 0 0 0-1.4zm-1.81 15.1l.39.39a.996.996 0 1 0 1.41-1.41l-.39-.39a.993.993 0 0 0-1.4 0c-.4.4-.4 1.02-.01 1.41zM20 11.49v.01c0 .55.44.99.99.99H22c.55 0 .99-.44.99-.99v-.01c0-.55-.44-.99-.99-.99h-1.01c-.55 0-.99.44-.99.99zM12 5.5c-3.31 0-6 2.69-6 6s2.69 6 6 6s6-2.69 6-6s-2.69-6-6-6zm-.01 16.95H12c.55 0 .99-.44.99-.99v-.96c0-.55-.44-.99-.99-.99h-.01c-.55 0-.99.44-.99.99v.96c0 .55.44.99.99.99zm-7.74-3.21c.39.39 1.02.39 1.41 0l.39-.39a.993.993 0 0 0 0-1.4l-.01-.01a.996.996 0 0 0-1.41 0l-.39.39c-.38.4-.38 1.02.01 1.41z"
fill="currentColor"
></path>
</svg>
);
}
function ChangeDarkModeAndLightMode() {
const { colorMode, toggleColorMode } = useColorMode();
return (
<>
<IconButton
aria-label="dark mode Light mode change Button"
onClick={toggleColorMode}
>
{colorMode === "light" ? <IcRoundWbSunny /> : <FaSolidMoon />}
</IconButton>
</>
);
}
type HeadsDetaPropsType = {
children?: ReactNode;
title?: string;
};
const HeadsDeta = ({ children, title }: HeadsDetaPropsType) => {
return (
<Head>
<title>{title}</title>
<meta charSet="utf-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
{/* For new browsers - multisize ico */}
<link
rel="icon"
type="image/x-icon"
sizes="16x16 32x32"
href="favicon.ico"
/>
{children}
</Head>
);
};
type Props = {
children?: ReactNode;
title?: string;
};
const Layout = ({ children, title = "This is the default title" }: Props) => {
const headerBg = useColorModeValue("#fff", "gray.900");
const HeaderTextColor = useColorModeValue("#000", "#fff");
return (
<>
<HeadsDeta title={title}>
{/* <link rel="shortcut icon" href="open-book.png" type="image/x-icon" /> */}
</HeadsDeta>
<Flex
bg={headerBg}
position="sticky"
w="100vw"
top="0"
left="0"
boxShadow="md"
p="2"
>
<Container maxWidth="800px" p="0">
<Flex>
<Box>
<NextLink href="/">
<Link href="/">
<Heading color={HeaderTextColor} as="h1" size="lg">
Chakra App
</Heading>
</Link>
</NextLink>
</Box>
<Spacer />
<Box>
<ChangeDarkModeAndLightMode />
</Box>
</Flex>
</Container>
</Flex>
<Container maxWidth="800px">{children}</Container>
<Box bg={useColorModeValue("gray.200", "gray.700")}>
<hr className="mt-4" />
<Container maxWidth="800px" className="py-8">
<Text className="text-center ">
<Link href="https://github.com/Mochichi2003">Mochi</Link>
が作りました
</Text>
</Container>
</Box>
</>
);
};
export default Layout;
Next.jsのLinkとChakara-uiのリンクがかぶるからNextjsの方はNextLinkにしてる
アイコンはhttps://icones.js.orgから適当に取得してる
あと
に載ってるやるとダークモードとライトモードが切り替わるようになる投稿したものとかログイン状態をFirebaseで管理したいので作る
なんとなく作ってみたアイコン本番で使うかどうかはまだ未定
参考にする
NEXT_PUBLIC_FIREBASE_API_KEY=xxx
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=xxx
NEXT_PUBLIC_FIREBASE_DATABASE_URL=xxx
NEXT_PUBLIC_FIREBASE_PROJECT_ID=xxx
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=xxxx
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=xxx
NEXT_PUBLIC_FIREBASE_APP_ID=xxxx
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=xxx
xxxのところをそれぞれFirebaseで作ったやつで入れ替えていく。DATABASE_URL が出てこないときはコンソールを開いてリアルタイムデーターベースを作ってからだとURLを取得できる
lib/firebase.ts
を作成して書く
import firebase from "firebase/app";
import "firebase/auth"; // 完成したときに不要なら消す
import "firebase/firestore"; //完成したときに不要なら消す
import "firebase/storage"; // 完成したときに不要なら消す
import "firebase/analytics"; // 完成したときに不要なら消す
import "firebase/performance";// 完成したときに不要なら消す
const config = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};
!firebase.apps.length ? firebase.initializeApp(config) : firebase.app();
export const db = firebase.firestore(); // If you need it
ここに書かれてることをもとにLogin処理を実装していく
component/svg/
を作ってそっちに移動しようかな
追記
components/svgs/icon.tsx
にアイコンを入れておくようにした他のファイルでだいぶ軽量化された。
そういえばfontawesomeとかってどうなんだろう
Headerのheightってどんくらいがいいんだろう。とりあえず今は56pxにしてる。
zennは52pxか
Firebase Authを使ってGoogleでのログインができた
/** 省略**/
export const login = () => {
const provider = new firebase.auth.GoogleAuthProvider();
// provider.addScope("https://www.googleapis.com/auth/contacts.readonly");
firebase
.auth()
.signInWithPopup(provider)
.then(function (result: any) {
// This gives you a Google Access Token. You can use it to access the Google API.
console.log(`result : ${result}`);
// ...
})
.catch(function (error) {
console.log(error);
//続きはここに書く
});
};
/** 省略**/
あとcomponents/Layout.tsx
のヘッダーにSign in with Googleボタンを入れてボタンの onClick
でさっきのloginを呼び出すようにした
そういえば書いてなかったけどESLintとPrettier入れてる
開発とは全く関係ないことだけどZennのMarkdown書くときに等幅フォントのモードがほしい
追記
でzennのところに
.zenn-mde-textarea {
font-family: 'JetBrains Mono', monospace !important;
font-weight: 400!important;
}
って書き加えて
こんな感じでに等幅フォントで表示されるようにした
これを参考にしてログイン状態を保存できるようにした
ログインするところを /login
から下のDrawerを使って画像のように横から出てきたのを使うようにする
Formには
を使おうと思うForm 管理を
に変更するFormで送信するとき
{
"hoge":{
"1":"hoge1",
"2":"hoge2",
"3":"hoge3",
"4":"hoge4",
},
....
}
的な感じにして送信できるようにできないかな
これでできそう
input の nameを "hoge.1"とかにすれば
"hoge":{
"1":"hoge1",
"2":"hoge2",
"3":"hoge3",
"4":"hoge4",
},
にできるんだね