跳转到主要内容

现在,您登录的几乎每个应用程序都有一个仪表板。它们中的大多数都是用React或Angular等现代框架构建的,并且有某种后端来支持它们。用户依靠这些仪表板来检查他们的帐户信息、更新他们的业务以及处理许多其他操作。

在本教程中,我们将使用Redwood为管理系统制作一个用户面板。用户可以采取一些操作将其他用户添加到具有不同角色的帐户中。仪表板还允许用户将新项目添加到其库存中,这些项目将附加到不同的位置。

让我们以红木为背景开始吧。

什么是Redwood

Redwood是一个使用Prisma、React和GraphQL构建的全栈框架。它有很多功能和一些命令,我们将使用这些功能快速制作这个应用程序。如果你有兴趣了解更多关于红木的信息,一定要查看他们的文档。

设置项目

现在,让我们开始设置我们的仪表板。我们将通过运行以下命令来引导此应用程序。只是提醒一下,它可能需要几分钟才能完成,但值得等待。

yarn create redwood-app ./redwood-dashboard

当命令执行完毕后,您会注意到您有相当多的文件夹和文件。最重要的文件夹是api目录和web目录。api目录保存后端和数据库的所有代码,而web目录保存前端的所有代码。

在我们开始使用该应用程序之前,您应该先运行它,看看它是如何工作的。使用以下命令启动前端和后端。

yarn rw dev

以下是您应该在浏览器中看到的内容。

基本红木应用程序

定义仪表板模型

既然您已经看到了该应用程序的运行情况,让我们开始利用Redwood的一些命令在后端工作。我们将首先为仪表板制作一个Prisma模型。这就是我们的应用程序连接到Postgres数据库的方式。在api>db内部,打开schema.prisma文件。

在这里,我们将使用几种不同类型的关系为数据库中所需的表创建模式。您将看到Redwood已经设置了一些配置和一个用户模型的示例。

我们将把数据源数据库提供程序更改为postgresql,您可以在下面的代码片段中看到。

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

然后,我们将删除TODO并更新示例用户模型。

model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String
  role  String
}

我们更新的用户模型有几个列,用于存储关于用户的信息。电子邮件字段有一个约束,即它必须始终是唯一的值。同一个电子邮件地址不能多次出现在数据库中。接下来,我们将为Item和Location表添加一个新模型。这些需要同时创建,因为它们彼此之间有关系。

 

model Item {
  id         Int      @id @default(autoincrement())
  sku        String   @unique
  name       String
  location   Location @relation(fields: [locationId], references: [id])
  locationId Int
}

model Location {
  id       Int    @id @default(autoincrement())
  name     String
  district Int
  Item     Item[]
}

然后,我们将更新seed.js文件,以便在启动应用程序之前存在一些值。这在产品面板上很常见,用于填充下拉选项或初始化用户可以添加到不同设置中的标记。我们将添加一个用户、一个项目和一个位置来为我们的数据库播种。提醒一下,我已经从这个文件中删除了很多评论。

/* eslint-disable no-console */
const { PrismaClient } = require('@prisma/client')
const dotenv = require('dotenv')

dotenv.config()
const db = new PrismaClient()

async function main() {
  console.warn('Please define your seed data.')

  await db.user.create({
    data: { name: 'Kaiya', email: 'best@test.com', role: 'inventory' },
  })

  await db.location.create({
    data: { name: 'Compound North', district: 1 },
  })

  await db.item.create({
    data: {
      name: 'Morning Glory',
      sku: 'hf8029ht8942ht8429pht8p942p',
      locationId: 1,
    },
  })
}

main()
  .catch((e) => console.error(e))
  .finally(async () => {
    await db.$disconnect()
  })

有了模式和种子数据,我们几乎可以运行第一次迁移了。在我们这样做之前,我们需要连接到数据库。因此,在项目根目录的.env文件中,更新DATABASE_URL以匹配Postgres实例。它看起来和这个相似。

DATABASE_URL=postgres://postgres:admin@localhost:5432/dashboard

如果你没有本地的Postgres实例,你可以很快在这里下载。

现在,我们将使用以下内容运行迁移:

yarn rw prisma migrate dev

这将提示您输入迁移名称,创建数据库和表,并添加种子数据。如果您通过pgAdmin查看数据库,您会看到这样的内容。

pgAdmin中的种子数据库

现在您已经准备好了数据库,可以存储和发送我们需要的值,让我们转到后端和前端。

添加后端和前端

Redwood有一个特殊的命令,它为我们做了很多工作。它将为从前端组件到后端GraphQL查询、类型和突变的表创建整个CRUD。我们将利用这一点来充分利用我们的仪表板。让我们从以下命令开始。

yarn rw g scaffold user

这将生成几个页面、组件和GraphQL文件,以处理仪表板用户部分的所有CRUD操作。查看web > pages。您应该看到一个名为User的新目录。这包含了我们需要处理的所有关于用户的页面。

现在查看web > components。将有另一个用户文件夹。这个包含了我们用来与GraphQL服务器交互的组件。大多数数据都是在这些组件中提取的,请求是从这些组件发送的。

web > layouts文件夹还将有一个新目录,其中包含用户页面的布局文件。这就是您可以为一组特定页面创建样式的方法。

在Routes.js文件中,您将看到UserLayout中为用户包装了一组新的路由。生成的所有页面也会将其路由自动添加到其父布局内的该文件中。

在api目录中还生成了一些新文件。如果您在api>src>graphql中查看,您会发现用于所有所需CRUD操作的graphql模式,并且类型已由schema.prisma文件中的模型定义。

然后在api > src > services,中,您将找到模式中定义的查询和突变的所有GraphQL解析器。

所有这些页面、组件、类型和解析器都是由Redwood命令生成的。让我们使用yarn rw-dev运行该应用程序,这样您就可以看到所有这些工作。如果你在浏览器中转到用户页面,你应该会看到类似的内容。

主页现在将返回404,因为我们还没有为该路由添加组件。我们稍后会这样做,但/users页面仍然可以工作。

您可以使用页面上的按钮添加新用户、更新当前用户或删除当前用户。

我们将再运行两次scaffold命令,以生成项目和位置的CRUD。

yarn rw g scaffold location
yarn rw g scaffold item

现在,我们已经拥有了用户面板所需的所有操作。我们需要做几件事来给这个仪表板一个更真实的感觉。我们将添加一个主页和一个布局,以帮助我们在仪表板的各个部分之间导航。

制作主页

让我们从添加样式化组件包开始,因为我们将使用它来样式化一些东西。首先,转到终端中的web目录。这就是这个软件包需要安装的地方。

yarn add styled-components

现在让我们运行一个神奇的Redwood命令来生成主页及其路由。

yarn rw g page home /

这将在web > src > pages中为主页组件创建一个新目录,并将一个新路由添加到Routes.js。您可以在此处重新运行应用程序以查看新主页。在浏览器中会是这样的。

新主页

现在我们已经有了主页,让我们制作一个适用于此页面和迄今为止所有其他页面的布局。当然,有一个Redwood命令可以处理这个问题。

yarn rw g layout home

这将为我们的主页在web > src > layouts中创建一个新文件夹。我们将在HomeLayout组件中使用一些样式化的组件来创建侧导航菜单,并为面板提供一个小的定义。我们还将使用红木路由在侧边导航中添加到其他页面的链接。

import { Link, routes } from '@redwoodjs/router'
import styled from 'styled-components'

const HomeLayout = ({ children }) => {
  return (
    <FlexBox>
      <SideNav>
        <LinkContainer>
          <Link to={routes.users()}>Users</Link>
        </LinkContainer>
        <LinkContainer>
          <Link to={routes.locations()}>Locations</Link>
        </LinkContainer>
        <LinkContainer>
          <Link to={routes.items()}>Items</Link>
        </LinkContainer>
      </SideNav>
      <FullPage>{children}</FullPage>
    </FlexBox>
  )
}

const FlexBox = styled.div`
  display: flex;
`

const FullPage = styled.div`
  height: 100vh;
  width: 100%;
`

const LinkContainer = styled.div`
  padding: 12px;

  > * {
    color: #000;
    font-family: sans-serif;
    font-size: 18px;
    text-decoration: none;
  }

  > *:hover {
    color: #5b5b5b;
  }
`

const SideNav = styled.nav`
  border-right: 1px solid;
  width: 250px;
`

export default HomeLayout

接下来,我们需要将此布局应用于应用程序中的所有页面。我们将在Routes.js文件中执行此操作。这意味着在所有现有路线周围添加一个<Set>组件,如下所示。

...
<Router>
  <Set wrap={HomeLayout}>
    <Route path="/" page={HomePage} name="home" />
    <Set wrap={ItemsLayout}>
      <Route path="/items/new" page={ItemNewItemPage} name="newItem" />
      <Route path="/items/{id:Int}/edit" page={ItemEditItemPage} name="editItem" />
      <Route path="/items/{id:Int}" page={ItemItemPage} name="item" />
      <Route path="/items" page={ItemItemsPage} name="items" />
    </Set>
    <Set wrap={LocationsLayout}>
      <Route path="/locations/new" page={LocationNewLocationPage} name="newLocation" />
      <Route path="/locations/{id:Int}/edit" page={LocationEditLocationPage} name="editLocation" />
      <Route path="/locations/{id:Int}" page={LocationLocationPage} name="location" />
      <Route path="/locations" page={LocationLocationsPage} name="locations" />
    </Set>
    <Set wrap={UsersLayout}>
      <Route path="/users/new" page={UserNewUserPage} name="newUser" />
      <Route path="/users/{id:Int}/edit" page={UserEditUserPage} name="editUser" />
      <Route path="/users/{id:Int}" page={UserUserPage} name="user" />
      <Route path="/users" page={UserUsersPage} name="users" />
    </Set>
    <Route notfound page={NotFoundPage} />
  </Set>
</Router>

 

现在,如果您运行yarn rw-dev,您将看到这样的内容。

应用了全局布局的仪表板

如果你浏览侧面导航中的任何链接,你都会看到这样的内容。

具有布局的仪表板中的用户

我把多余的款式留给你。设计这个可以是一个完全独立的教程!

这可能感觉像是一个悬念,因为我们实际上并没有写太多代码,但这就是我喜欢Redwood的地方。你可以让大型应用程序快速启动并运行,一切正常。

已完成代码

您可以在这个代码沙盒( Code Sandbox)上签出前端,而无需连接到后端。

如果您想要前端和后端的所有代码,请查看redwood-user-dashboard in this Git repo!!

结论

仪表板是许多应用程序的主要组成部分,因此了解如何快速创建仪表板很有帮助。红木是一个框架,可以帮助你开始这样的高级项目,它可以快速生成复杂的结构。

 

文章链接