先决条件
- javascript
- 下一步|反应
介绍
使用XATA作为后端构建博客配置文件,并构建用于处理图像的云。
XATA是为与您的前端应用程序连接而创建的无服务器后端。
设置NextJ
在本节中,我们将使用下一个JS构建前端应用的结构。
n:b在本文的那一刻,已实施了12.2.0版,并且版本13可能很快就会发布。
- nextjs的安装: 在安装下一个之前,本文假设我们已安装了节点和NPM https://nodejs.org/en/download/package-manager/
NPM安装。
https://docs.npmjs.com/cli/v6/commands/npm-install
安装nextjs
https://nextjs.org/learn/basics/create-nextjs-app/setup
成功安装了这些工具后,我们的结构为
在我的应用程序夹中,我们需要创建一个组件文件夹,该文件夹将保存我们的Web应用程序的每个组件。
我们将创建文件
- header.js
- post.js
- uploadwidget.js
在我们的Header.js
文件中,我们将建立一个导航栏和按钮,该按钮在登录应用程序时处理我们的身份验证以供我们在pages/index.js
中渲染。
import { useSession, signIn, signOut } from "next-auth/react";
import Link from "next/link";
export default function Header() {
const handleSignin = (e) => {
e.preventDefault();
signIn();
};
const handleSignout = (e) => {
e.preventDefault();
signOut();
};
const { data: session } = useSession();
return (
<div className="header">
<Link href="/">
<a className="logo">FlauntSpace</a>
</Link>
{session && (
<a href="#" onClick={handleSignout} className="btn-signin">
SIGN OUT
</a>
)}
{!session && (
<a href="#" onClick={handleSignin} className="btn-signin">
SIGN IN
</a>
)}
</div>
);
}
我们导入了下一个链接和下一个实现,以便使用第三方(Github,google)处理身份验证,而我们这样做时,下一个auth库为我们提供了处理签名的功能。
现在,我们打开我们的pages/index.js
并清除使我们思想家的默认代码
import { useSession } from "next-auth/react";
export default function Home() {
const { data: session, status } = useSession();
const loading = status === "loading";
return (
<>
<div className={styles.container}>
<Head>
<title>FlauntSpace</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
</div>
</>
)
}
我们必须设置代码来美化它,以获得更好的界面和体验。下一个软件包给出默认的styles/global.css
html,
body {
padding: 0;
margin: 0;
background-color: #2d3436;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
ext-decoration: none;
}
* {
box-sizing: border-box;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
background-color: rgb(110, 90, 90);
color: #fff;
padding: 0 2rem;
width: 100%;
box-shadow: 0 10px 20px rgba(82, 71, 71, 0.19), 0 6px 6px rgba(0,0,0,0.23);
}
.logo {
font-weight: 800;
color: #fff;
font-size: 1.8rem;
font-style: oblique;
}
.btn-signin {
box-sizing: border-box;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #000;;
outline: none;
border: 0;
cursor: pointer;
display: -webkit-box;
display: flex;
align-self: center;
font-size: 1.2rem;
line-height: 1;
margin: 20px;
font-weight: 700;
padding: 1.2rem;
width: 14rem;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-family: inherit;
user-select: none;
color: #000;
background-color: #353430;
}
.btn-signin:hover {
background-color: #353430;
color: #000;
}
我们使用此CSS代码段。
向前迈进,我们创建了我们的身份验证以进入我们的应用程序配置文件,我们使用GitHub和Google身份验证来绕过此阶段。
创建一个github客户端ID和秘密键
https://www.knowband.com/blog/user-manual/get-github-client-id-client-secret-api-details/
我们对Google身份验证做同样的事情。
https://developers.google.com/adwords/api/docs/guides/authentication
现在我们将在应用程序中创建我们的.env
文件,这是为了我们不要向用户揭示我们的安全密钥
遵循
的过程后,我们的.env
文件应该看起来像这样
https://next-auth.js.org/providers/github
GOOGLE_ID=<your googleID generated>
GOOGLE_SECRET=<secret key generated by google>
GITHUB_ID=<githubID>
GITHUB_SECRET=<AUTHENTICATION SECRETKEY BY GITHUB USING THE ACTION>
NEXTAUTH_URL=http://localhost:3000
在pages/api/auth/…nextauth.js
文件中,从Google和GitHub导入生成的身份验证,以使我们的应用程序与API交互。
import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";
const options = {
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
authorization: { params: { scope: "notifications" } },
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
authorization: {
params: {
scope: "notifications",
},
},
}),
],
};
export default (req, res) => NextAuth(req, res, options);
我们可以安全地添加我们的身份验证,并应在通过身份验证时显示我们的应用程序
在我们的应用程序中,我们有一个显示屏可以让用户上传个人资料图片,他们也可以发布一个迷你博客。
在我们的组件文件夹中创建一个post.js
文件,该文件列出了文本区域和发布按钮,以允许用户发布内容
import { useState } from "react";
import styles from "../styles/Home.module.css";
export function Post() {
return (
<form action="api/form" method="post">
<label htmlFor="body-content" className={styles.flauntText}>
Flaunt
</label>
<textarea rows="4" cols="50" className={styles.bodyText}>
Enter text here...
</textarea>
<br />
<button type="submit" className={styles.postbut}>
Post
</button>
</form>
);
}
另外,我们在组件中创建uploadWidget.js
。
import { useState } from "react";
import styles from "../styles/Home.module.css";
export function ImageUpload() {
const [isImageUploaded, setIsImageUploaded] = useState(false);
async function handleWidgetClick() {
const widget = window.cloudinary.createUploadWidget(
{
cloudName: "dhpp7gaty",
uploadPreset: "my upload",
resourceType: "image",
},
(error, result) => {
if (!error && result && result.event === "success") {
console.log("Done! Here is the image info: ", result.info);
setIsImageUploaded(true);
} else if (error) {
console.log(error);
}
}
);
widget.open();
}
return (
<div className={styles.container}>
<div className={styles.vertical}>
<button
className={styles.button}
type="button"
onClick={handleWidgetClick}
>
Upload image
</button>
</div>
{isImageUploaded ? (
<>
<div>Successfully uploaded</div>
</>
) : null}
</div>
);
}
我们有我们的上传按钮正在使用Cloudinary上传小部件。
https://cloudinary.com/documentation/upload_widget,现在我们将为我们的应用程序设计。
让我们在样式文件夹中创建Home.module.css
文件,我们应该使用此片段。
@import url('https://fonts.googleapis.com/css2?family=Island+Moments&display=swap');
.container {
min-height: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.main {
}
.title {
border-radius: 50%
}
.profile {
grid-column: 2;
grid-row: 2;
background-color: #eef6f8;
}
.content {
display: grid;
grid-column: 1/3;
grid-row: 1;
}
.uploadsec {
grid-column: 1;
grid-row: 2;
background-color: #ccc;
}
.profileimg {
border-radius: 50%;
}
.avatar {
flex: 1;
flex-basis: 250px;
}
.details {
flex: 2;
}
.button {
background-color: #449a79; /* Green */
border-radius: 10px;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
cursor: pointer;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
.bodyText {
width: 100%;
height: 150px;
padding: 12px 20px;
box-sizing: border-box;
border: 2px solid #ccc;
border-radius: 4px;
background-color: #f8f8f8;
resize: none;
}
.post {
align-items: center;
justify-content: center;
display: flex;
}
.flauntText {
font-family: 'Island Moments', cursive;
font-weight: bold;
font-size: 40px;
}
.postbut {
background-color: #449a79; /* Green */
border-radius: 10px;
border: none;
color: white;
padding: 15px 30px;
text-align: center;
cursor: pointer;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
.imageCloud {
/*border: 5px solid #555;*/
border-radius: 50%;
display: inline-block;
justify-content: center;
align-items: center;
width: 100px;
border: 3px solid black;
}
现在,我们必须在pages/index.js
文件上渲染所有这些组件
import Head from "next/head";
import Header from "../components/Header";
import styles from "../styles/Home.module.css";
import { useSession } from "next-auth/react";
import { ImageUpload } from "../components/uploadWidget";
import { Post } from "../components/post";
import { getXataClient, XataClient } from "../src/xata";
export default function Home() {
const { data: session, status } = useSession();
const loading = status === "loading";
// const [url, updateUrl] = useState();
// const [error, updateError] = useState();
return (
<>
<div className={styles.container}>
<Head>
<title>FlauntSpace</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
</div>
<main className={styles.main}>
<div className={styles.user}>
{loading && <div className={styles.title}>Loading...</div>}{" "}
{/*authentication process */}
{/**Renders the home page after authentication passed of third-party */}
{session && (
<div className={styles.content}>
<div className={styles.profile}>
<>
<p>
You're logged in as
{/**Get's the name and mail from the third-party nextauth and display it as the user name on the home page */}
{session.user.name ?? session.user.email}
</p>
{/**SPLIT spage to two section where one is for the upload preset and the other is for posting blog post */}
<form className={styles.post}>
<Post />
</form>
</>
</div>
<div className={styles.uploadsec}>
<img
src="https://res.cloudinary.com/dhpp7gaty/image/upload/v1667560004/Profile-uploads/jnbkgndxzlnhapxv8eed.jpg"
alt="upload here"
className={styles.imageCloud}
/>
<ImageUpload />
</div>
</div>
)}
</div>
</main>
</>
);
}
用XATA建立后端
快速参观XATA在视频中的工作方式。
https://www.youtube.com/watch?v=-KNRS2fIWdA&
初始化XATA我们的项目,使其在JavaScript或Typescript中自动生成代码。
xata init
现在,让我们将XATA导入我们的pages/index.js
import Head from "next/head";
import Header from "../components/Header";
import styles from "../styles/Home.module.css";
import { useSession } from "next-auth/react";
import { ImageUpload } from "../components/uploadWidget";
import { Post } from "../components/post";
import { getXataClient, XataClient } from "../src/xata";
export default function Home() {
const { data: session, status } = useSession();
const loading = status === "loading";
return (
<>
<div className={styles.container}>
<Head>
<title>FlauntSpace</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
</div>
<main className={styles.main}>
<div className={styles.user}>
{loading && <div className={styles.title}>Loading...</div>}{" "}
{/*authentication process */}
{/**Renders the home page after authentication passed of third-party */}
{session && (
<div className={styles.content}>
<div className={styles.profile}>
<>
<p>
You're logged in as
{/**Get's the name and mail from the third-party nextauth and display it as the user name on the home page */}
{session.user.name ?? session.user.email}
</p>
{/**SPLIT spage to two section where one is for the upload preset and the other is for posting blog post */}
<form className={styles.post}>
<Post />
</form>
</>
</div>
<div className={styles.uploadsec}>
<img
src="https://res.cloudinary.com/dhpp7gaty/image/upload/v1667560004/Profile-uploads/jnbkgndxzlnhapxv8eed.jpg"
alt="upload here"
className={styles.imageCloud}
/>
<ImageUpload />
</div>
</div>
)}
</div>
</main>
</>
);
}
{
/**Connecting the xata to our app */
}
const xata = new XataClient();
export const getServerSideProps = async () => {
const FlauntSpace = await xata.db.items.getAll();
return {
props: {
FlauntSpace,
},
};
};
我们成功地将XATA数据库连接到了前端应用程序,更多功能是从数据库中查询数据以在前端渲染。
n:b本文打算添加更多功能,并在更改后立即进行编辑。