diff --git a/api/prisma/migrations/20201018233330-add-simple-user-model/README.md b/api/prisma/migrations/20201018233330-add-simple-user-model/README.md new file mode 100644 index 0000000..c8ec755 --- /dev/null +++ b/api/prisma/migrations/20201018233330-add-simple-user-model/README.md @@ -0,0 +1,65 @@ +# Migration `20201018233330-add-simple-user-model` + +This migration has been generated by Kurt Hutten at 10/19/2020, 10:33:30 AM. +You can check out the [state of the schema](./schema.prisma) after the migration. + +## Database Steps + +```sql +CREATE TABLE "User" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "userName" TEXT NOT NULL, + "email" TEXT NOT NULL, + "issuer" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "image" TEXT, + "bio" TEXT +) + +CREATE UNIQUE INDEX "User.userName_unique" ON "User"("userName") + +CREATE UNIQUE INDEX "User.email_unique" ON "User"("email") + +CREATE UNIQUE INDEX "User.issuer_unique" ON "User"("issuer") +``` + +## Changes + +```diff +diff --git schema.prisma schema.prisma +migration 20201011095227-create-contact..20201018233330-add-simple-user-model +--- datamodel.dml ++++ datamodel.dml +@@ -1,9 +1,7 @@ + datasource DS { +- // optionally set multiple providers +- // example: provider = ["sqlite", "postgresql"] +- provider = "sqlite" +- url = "***" ++ provider = ["sqlite", "postgresql"] ++ url = "***" + } + generator client { + provider = "prisma-client-js" +@@ -34,4 +32,17 @@ + email String + message String + createdAt DateTime @default(now()) + } ++ ++model User { ++ id Int @id @default(autoincrement()) ++ userName String @unique ++ email String @unique ++ issuer String @unique ++ ++ createdAt DateTime @default(now()) ++ updatedAt DateTime @updatedAt ++ ++ image String? // url maybe id or file storage service? cloudinary? ++ bio String? //mark down ++} +``` + + diff --git a/api/prisma/migrations/20201018233330-add-simple-user-model/schema.prisma b/api/prisma/migrations/20201018233330-add-simple-user-model/schema.prisma new file mode 100644 index 0000000..15e3468 --- /dev/null +++ b/api/prisma/migrations/20201018233330-add-simple-user-model/schema.prisma @@ -0,0 +1,48 @@ +datasource DS { + provider = ["sqlite", "postgresql"] + url = "***" +} + +generator client { + provider = "prisma-client-js" + binaryTargets = "native" +} + +model Post { + id Int @id @default(autoincrement()) + title String + body String + createdAt DateTime @default(now()) +} + +model Part { + id Int @id @default(autoincrement()) + title String + description String // markdown string + code String @default("// Welcome to Cascade Studio! Here are some useful functions:\n// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()\n// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()\n// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),\n// FilletEdges(), ChamferEdges(),\n// Slider(), Button(), Checkbox()\nlet holeRadius = Slider(\"Radius\", 30 , 20 , 40);\nlet sphere = Sphere(50);\nlet cylinderZ = Cylinder(holeRadius, 200, true);\nlet cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));\nlet cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));\nTranslate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));\n\nTranslate([-25, 0, 40], Text3D(\"Hi!\"));\n// Don't forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!") + mainImage String // link to cloudinary + createdAt DateTime @default(now()) + // userId + //likes, comments, reactions +} + +model Contact { + id Int @id @default(autoincrement()) + name String + email String + message String + createdAt DateTime @default(now()) +} + +model User { + id Int @id @default(autoincrement()) + userName String @unique + email String @unique + issuer String @unique + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + image String? // url maybe id or file storage service? cloudinary? + bio String? //mark down +} diff --git a/api/prisma/migrations/20201018233330-add-simple-user-model/steps.json b/api/prisma/migrations/20201018233330-add-simple-user-model/steps.json new file mode 100644 index 0000000..8ea741d --- /dev/null +++ b/api/prisma/migrations/20201018233330-add-simple-user-model/steps.json @@ -0,0 +1,179 @@ +{ + "version": "0.3.14-fixed", + "steps": [ + { + "tag": "UpdateArgument", + "location": { + "tag": "Source", + "source": "DS" + }, + "argument": "provider", + "newValue": "[\"sqlite\", \"postgresql\"]" + }, + { + "tag": "CreateModel", + "model": "User" + }, + { + "tag": "CreateField", + "model": "User", + "field": "id", + "type": "Int", + "arity": "Required" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "id" + }, + "directive": "id" + } + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "id" + }, + "directive": "default" + } + }, + { + "tag": "CreateArgument", + "location": { + "tag": "Directive", + "path": { + "tag": "Field", + "model": "User", + "field": "id" + }, + "directive": "default" + }, + "argument": "", + "value": "autoincrement()" + }, + { + "tag": "CreateField", + "model": "User", + "field": "userName", + "type": "String", + "arity": "Required" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "userName" + }, + "directive": "unique" + } + }, + { + "tag": "CreateField", + "model": "User", + "field": "email", + "type": "String", + "arity": "Required" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "email" + }, + "directive": "unique" + } + }, + { + "tag": "CreateField", + "model": "User", + "field": "issuer", + "type": "String", + "arity": "Required" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "issuer" + }, + "directive": "unique" + } + }, + { + "tag": "CreateField", + "model": "User", + "field": "createdAt", + "type": "DateTime", + "arity": "Required" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "createdAt" + }, + "directive": "default" + } + }, + { + "tag": "CreateArgument", + "location": { + "tag": "Directive", + "path": { + "tag": "Field", + "model": "User", + "field": "createdAt" + }, + "directive": "default" + }, + "argument": "", + "value": "now()" + }, + { + "tag": "CreateField", + "model": "User", + "field": "updatedAt", + "type": "DateTime", + "arity": "Required" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "User", + "field": "updatedAt" + }, + "directive": "updatedAt" + } + }, + { + "tag": "CreateField", + "model": "User", + "field": "image", + "type": "String", + "arity": "Optional" + }, + { + "tag": "CreateField", + "model": "User", + "field": "bio", + "type": "String", + "arity": "Optional" + } + ] +} \ No newline at end of file diff --git a/api/prisma/migrations/20201019072122-add-simplify-user-model/README.md b/api/prisma/migrations/20201019072122-add-simplify-user-model/README.md new file mode 100644 index 0000000..29d4e11 --- /dev/null +++ b/api/prisma/migrations/20201019072122-add-simplify-user-model/README.md @@ -0,0 +1,61 @@ +# Migration `20201019072122-add-simplify-user-model` + +This migration has been generated by Kurt Hutten at 10/19/2020, 6:21:22 PM. +You can check out the [state of the schema](./schema.prisma) after the migration. + +## Database Steps + +```sql +DROP INDEX "User.issuer_unique" + +DROP INDEX "User.userName_unique" + +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_User" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "email" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "image" TEXT, + "bio" TEXT +); +INSERT INTO "new_User" ("id", "email", "createdAt", "updatedAt", "image", "bio") SELECT "id", "email", "createdAt", "updatedAt", "image", "bio" FROM "User"; +DROP TABLE "User"; +ALTER TABLE "new_User" RENAME TO "User"; +CREATE UNIQUE INDEX "User.email_unique" ON "User"("email"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON +``` + +## Changes + +```diff +diff --git schema.prisma schema.prisma +migration 20201018233330-add-simple-user-model..20201019072122-add-simplify-user-model +--- datamodel.dml ++++ datamodel.dml +@@ -1,7 +1,7 @@ + datasource DS { + provider = ["sqlite", "postgresql"] +- url = "***" ++ url = "***" + } + generator client { + provider = "prisma-client-js" +@@ -34,12 +34,12 @@ + createdAt DateTime @default(now()) + } + model User { +- id Int @id @default(autoincrement()) +- userName String @unique +- email String @unique +- issuer String @unique ++ id Int @id @default(autoincrement()) ++ email String @unique ++ // userName String @unique ++ // issuer String @unique + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +``` + + diff --git a/api/prisma/migrations/20201019072122-add-simplify-user-model/schema.prisma b/api/prisma/migrations/20201019072122-add-simplify-user-model/schema.prisma new file mode 100644 index 0000000..24140d8 --- /dev/null +++ b/api/prisma/migrations/20201019072122-add-simplify-user-model/schema.prisma @@ -0,0 +1,48 @@ +datasource DS { + provider = ["sqlite", "postgresql"] + url = "***" +} + +generator client { + provider = "prisma-client-js" + binaryTargets = "native" +} + +model Post { + id Int @id @default(autoincrement()) + title String + body String + createdAt DateTime @default(now()) +} + +model Part { + id Int @id @default(autoincrement()) + title String + description String // markdown string + code String @default("// Welcome to Cascade Studio! Here are some useful functions:\n// Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()\n// Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()\n// Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(),\n// FilletEdges(), ChamferEdges(),\n// Slider(), Button(), Checkbox()\nlet holeRadius = Slider(\"Radius\", 30 , 20 , 40);\nlet sphere = Sphere(50);\nlet cylinderZ = Cylinder(holeRadius, 200, true);\nlet cylinderY = Rotate([0,1,0], 90, Cylinder(holeRadius, 200, true));\nlet cylinderX = Rotate([1,0,0], 90, Cylinder(holeRadius, 200, true));\nTranslate([0, 0, 50], Difference(sphere, [cylinderX, cylinderY, cylinderZ]));\n\nTranslate([-25, 0, 40], Text3D(\"Hi!\"));\n// Don't forget to push imported or oc-defined shapes into sceneShapes to add them to the workspace!") + mainImage String // link to cloudinary + createdAt DateTime @default(now()) + // userId + //likes, comments, reactions +} + +model Contact { + id Int @id @default(autoincrement()) + name String + email String + message String + createdAt DateTime @default(now()) +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + // userName String @unique + // issuer String @unique + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + image String? // url maybe id or file storage service? cloudinary? + bio String? //mark down +} diff --git a/api/prisma/migrations/20201019072122-add-simplify-user-model/steps.json b/api/prisma/migrations/20201019072122-add-simplify-user-model/steps.json new file mode 100644 index 0000000..0285263 --- /dev/null +++ b/api/prisma/migrations/20201019072122-add-simplify-user-model/steps.json @@ -0,0 +1,15 @@ +{ + "version": "0.3.14-fixed", + "steps": [ + { + "tag": "DeleteField", + "model": "User", + "field": "userName" + }, + { + "tag": "DeleteField", + "model": "User", + "field": "issuer" + } + ] +} \ No newline at end of file diff --git a/api/prisma/migrations/migrate.lock b/api/prisma/migrations/migrate.lock index 086c06b..dddc03e 100644 --- a/api/prisma/migrations/migrate.lock +++ b/api/prisma/migrations/migrate.lock @@ -4,4 +4,6 @@ 20201011043647-create-parts 20201011052155-add-code-to-part 20201011082558-add-code-not-needed-upon-create -20201011095227-create-contact \ No newline at end of file +20201011095227-create-contact +20201018233330-add-simple-user-model +20201019072122-add-simplify-user-model \ No newline at end of file diff --git a/api/prisma/schema.prisma b/api/prisma/schema.prisma index e11b1c6..baecb2a 100644 --- a/api/prisma/schema.prisma +++ b/api/prisma/schema.prisma @@ -33,3 +33,16 @@ model Contact { message String createdAt DateTime @default(now()) } + +model User { + id Int @id @default(autoincrement()) + email String @unique + // userName String @unique + // issuer String @unique + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + image String? // url maybe id or file storage service? cloudinary? + bio String? //mark down +} diff --git a/api/src/functions/identity-signup.js b/api/src/functions/identity-signup.js new file mode 100644 index 0000000..9524495 --- /dev/null +++ b/api/src/functions/identity-signup.js @@ -0,0 +1,35 @@ +import { createUser } from 'src/services/users/users.js' + +export const handler = async (req, _context) => { + const body = JSON.parse(req.body) + console.log(body) + console.log(_context) + + const eventType = body.event + const user = body.user + const email = user.email + + let roles = [] + + if (eventType === 'signup') { + roles.push('user') + const hi = { + email: 'kurt.hutten@gmail.com', + image: '', + bio: '' + } + const input = { + email, + } + createUser({input}) + + return { + statusCode: 200, + body: JSON.stringify({ app_metadata: { roles: roles } }), + } + } else { + return { + statusCode: 200, + } + } +} diff --git a/api/src/graphql/users.sdl.js b/api/src/graphql/users.sdl.js new file mode 100644 index 0000000..52c3411 --- /dev/null +++ b/api/src/graphql/users.sdl.js @@ -0,0 +1,35 @@ +export const schema = gql` + type User { + id: Int! + email: String! + createdAt: DateTime! + updatedAt: DateTime! + image: String + bio: String + } + + type Query { + users: [User!]! + user(id: Int!): User + } + + input CreateUserInput { + email: String! + issuer: String! + image: String + bio: String + } + + input UpdateUserInput { + email: String + issuer: String + image: String + bio: String + } + + type Mutation { + createUser(input: CreateUserInput!): User! + updateUser(id: Int!, input: UpdateUserInput!): User! + deleteUser(id: Int!): User! + } +` diff --git a/api/src/services/users/users.js b/api/src/services/users/users.js new file mode 100644 index 0000000..f3875f8 --- /dev/null +++ b/api/src/services/users/users.js @@ -0,0 +1,38 @@ +import { db } from 'src/lib/db' +import { requireAuth } from 'src/lib/auth' + +export const users = () => { + requireAuth({ role: 'admin' }) + return db.user.findMany() +} + +export const user = ({ id }) => { + requireAuth() + return db.user.findOne({ + where: { id }, + }) +} + +export const createUser = ({ input }) => { + console.log(input) + console.log(JSON.stringify(input)) + requireAuth({ role: 'admin' }) + return db.user.create({ + data: input, + }) +} + +export const updateUser = ({ id, input }) => { + requireAuth() + return db.user.update({ + data: input, + where: { id }, + }) +} + +export const deleteUser = ({ id }) => { + requireAuth({ role: 'admin' }) + return db.user.delete({ + where: { id }, + }) +} diff --git a/api/src/services/users/users.test.js b/api/src/services/users/users.test.js new file mode 100644 index 0000000..bac7cb4 --- /dev/null +++ b/api/src/services/users/users.test.js @@ -0,0 +1,9 @@ +/* +import { users } from './users' +*/ + +describe('users', () => { + it('returns true', () => { + expect(true).toBe(true) + }) +}) diff --git a/web/src/Routes.js b/web/src/Routes.js index 200ecb1..8255681 100644 --- a/web/src/Routes.js +++ b/web/src/Routes.js @@ -12,6 +12,15 @@ import { Router, Route, Private } from '@redwoodjs/router' const Routes = () => { return ( + {/* TODO add add min role to users and users/new */} + + + + + + + + diff --git a/web/src/components/EditUserCell/EditUserCell.js b/web/src/components/EditUserCell/EditUserCell.js new file mode 100644 index 0000000..34f940c --- /dev/null +++ b/web/src/components/EditUserCell/EditUserCell.js @@ -0,0 +1,50 @@ +import { useMutation, useFlash } from '@redwoodjs/web' +import { navigate, routes } from '@redwoodjs/router' +import UserForm from 'src/components/UserForm' + +export const QUERY = gql` + query FIND_USER_BY_ID($id: Int!) { + user: user(id: $id) { + id + email + createdAt + updatedAt + image + bio + } + } +` +const UPDATE_USER_MUTATION = gql` + mutation UpdateUserMutation($id: Int!, $input: UpdateUserInput!) { + updateUser(id: $id, input: $input) { + id + } + } +` + +export const Loading = () =>
Loading...
+ +export const Success = ({ user }) => { + const { addMessage } = useFlash() + const [updateUser, { loading, error }] = useMutation(UPDATE_USER_MUTATION, { + onCompleted: () => { + navigate(routes.users()) + addMessage('User updated.', { classes: 'rw-flash-success' }) + }, + }) + + const onSave = (input, id) => { + updateUser({ variables: { id, input } }) + } + + return ( +
+
+

Edit User {user.id}

+
+
+ +
+
+ ) +} diff --git a/web/src/components/NewUser/NewUser.js b/web/src/components/NewUser/NewUser.js new file mode 100644 index 0000000..6f89a18 --- /dev/null +++ b/web/src/components/NewUser/NewUser.js @@ -0,0 +1,38 @@ +import { useMutation, useFlash } from '@redwoodjs/web' +import { navigate, routes } from '@redwoodjs/router' +import UserForm from 'src/components/UserForm' + +const CREATE_USER_MUTATION = gql` + mutation CreateUserMutation($input: CreateUserInput!) { + createUser(input: $input) { + id + } + } +` + +const NewUser = () => { + const { addMessage } = useFlash() + const [createUser, { loading, error }] = useMutation(CREATE_USER_MUTATION, { + onCompleted: () => { + navigate(routes.users()) + addMessage('User created.', { classes: 'rw-flash-success' }) + }, + }) + + const onSave = (input) => { + createUser({ variables: { input } }) + } + + return ( +
+
+

New User

+
+
+ +
+
+ ) +} + +export default NewUser diff --git a/web/src/components/User/User.js b/web/src/components/User/User.js new file mode 100644 index 0000000..2b50035 --- /dev/null +++ b/web/src/components/User/User.js @@ -0,0 +1,103 @@ +import { useMutation, useFlash } from '@redwoodjs/web' +import { Link, routes, navigate } from '@redwoodjs/router' + +const DELETE_USER_MUTATION = gql` + mutation DeleteUserMutation($id: Int!) { + deleteUser(id: $id) { + id + } + } +` + +const jsonDisplay = (obj) => { + return ( +
+      {JSON.stringify(obj, null, 2)}
+    
+ ) +} + +const timeTag = (datetime) => { + return ( + + ) +} + +const checkboxInputTag = (checked) => { + return +} + +const User = ({ user }) => { + const { addMessage } = useFlash() + const [deleteUser] = useMutation(DELETE_USER_MUTATION, { + onCompleted: () => { + navigate(routes.users()) + addMessage('User deleted.', { classes: 'rw-flash-success' }) + }, + }) + + const onDeleteClick = (id) => { + if (confirm('Are you sure you want to delete user ' + id + '?')) { + deleteUser({ variables: { id } }) + } + } + + return ( + <> +
+
+

+ User {user.id} Detail +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Id{user.id}
Email{user.email}
Created at{timeTag(user.createdAt)}
Updated at{timeTag(user.updatedAt)}
Image{user.image}
Bio{user.bio}
+
+ + + ) +} + +export default User diff --git a/web/src/components/UserCell/UserCell.js b/web/src/components/UserCell/UserCell.js new file mode 100644 index 0000000..f89a7fd --- /dev/null +++ b/web/src/components/UserCell/UserCell.js @@ -0,0 +1,22 @@ +import User from 'src/components/User' + +export const QUERY = gql` + query FIND_USER_BY_ID($id: Int!) { + user: user(id: $id) { + id + email + createdAt + updatedAt + image + bio + } + } +` + +export const Loading = () =>
Loading...
+ +export const Empty = () =>
User not found
+ +export const Success = ({ user }) => { + return +} diff --git a/web/src/components/UserForm/UserForm.js b/web/src/components/UserForm/UserForm.js new file mode 100644 index 0000000..2527758 --- /dev/null +++ b/web/src/components/UserForm/UserForm.js @@ -0,0 +1,81 @@ +import { + Form, + FormError, + FieldError, + Label, + TextField, + Submit, +} from '@redwoodjs/forms' + +const UserForm = (props) => { + const onSubmit = (data) => { + props.onSave(data, props?.user?.id) + } + + return ( +
+
+ + + + + + + + + + + + + + +
+ + Save + +
+ +
+ ) +} + +export default UserForm diff --git a/web/src/components/Users/Users.js b/web/src/components/Users/Users.js new file mode 100644 index 0000000..427139e --- /dev/null +++ b/web/src/components/Users/Users.js @@ -0,0 +1,109 @@ +import { useMutation, useFlash } from '@redwoodjs/web' +import { Link, routes } from '@redwoodjs/router' + +const DELETE_USER_MUTATION = gql` + mutation DeleteUserMutation($id: Int!) { + deleteUser(id: $id) { + id + } + } +` + +const MAX_STRING_LENGTH = 150 + +const truncate = (text) => { + let output = text + if (text && text.length > MAX_STRING_LENGTH) { + output = output.substring(0, MAX_STRING_LENGTH) + '...' + } + return output +} + +const jsonTruncate = (obj) => { + return truncate(JSON.stringify(obj, null, 2)) +} + +const timeTag = (datetime) => { + return ( + + ) +} + +const checkboxInputTag = (checked) => { + return +} + +const UsersList = ({ users }) => { + const { addMessage } = useFlash() + const [deleteUser] = useMutation(DELETE_USER_MUTATION, { + onCompleted: () => { + addMessage('User deleted.', { classes: 'rw-flash-success' }) + }, + }) + + const onDeleteClick = (id) => { + if (confirm('Are you sure you want to delete user ' + id + '?')) { + deleteUser({ variables: { id }, refetchQueries: ['USERS'] }) + } + } + + return ( +
+ + + + + + + + + + + + + + {users.map((user) => ( + + + + + + + + + + ))} + +
IdEmailCreated atUpdated atImageBio 
{truncate(user.id)}{truncate(user.email)}{timeTag(user.createdAt)}{timeTag(user.updatedAt)}{truncate(user.image)}{truncate(user.bio)} + +
+
+ ) +} + +export default UsersList diff --git a/web/src/components/UsersCell/UsersCell.js b/web/src/components/UsersCell/UsersCell.js new file mode 100644 index 0000000..9fb8655 --- /dev/null +++ b/web/src/components/UsersCell/UsersCell.js @@ -0,0 +1,33 @@ +import { Link, routes } from '@redwoodjs/router' + +import Users from 'src/components/Users' + +export const QUERY = gql` + query USERS { + users { + id + email + createdAt + updatedAt + image + bio + } + } +` + +export const Loading = () =>
Loading...
+ +export const Empty = () => { + return ( +
+ {'No users yet. '} + + {'Create one?'} + +
+ ) +} + +export const Success = ({ users }) => { + return +} diff --git a/web/src/layouts/MainLayout/MainLayout.js b/web/src/layouts/MainLayout/MainLayout.js index 685985f..5d5dcba 100644 --- a/web/src/layouts/MainLayout/MainLayout.js +++ b/web/src/layouts/MainLayout/MainLayout.js @@ -35,7 +35,12 @@ const MainLayout = ({ children }) => { -
  • +
  • + + {isAuthenticated ? 'Log Out' : 'Log In'} + + +
  • diff --git a/web/src/pages/EditUserPage/EditUserPage.js b/web/src/pages/EditUserPage/EditUserPage.js new file mode 100644 index 0000000..5c8fa8d --- /dev/null +++ b/web/src/pages/EditUserPage/EditUserPage.js @@ -0,0 +1,12 @@ +import MainLayout from 'src/layouts/MainLayout' +import EditUserCell from 'src/components/EditUserCell' + +const EditUserPage = ({ id }) => { + return ( + + + + ) +} + +export default EditUserPage diff --git a/web/src/pages/NewUserPage/NewUserPage.js b/web/src/pages/NewUserPage/NewUserPage.js new file mode 100644 index 0000000..0368b02 --- /dev/null +++ b/web/src/pages/NewUserPage/NewUserPage.js @@ -0,0 +1,12 @@ +import MainLayout from 'src/layouts/MainLayout' +import NewUser from 'src/components/NewUser' + +const NewUserPage = () => { + return ( + + + + ) +} + +export default NewUserPage diff --git a/web/src/pages/UserPage/UserPage.js b/web/src/pages/UserPage/UserPage.js new file mode 100644 index 0000000..cf81dc9 --- /dev/null +++ b/web/src/pages/UserPage/UserPage.js @@ -0,0 +1,12 @@ +import MainLayout from 'src/layouts/MainLayout' +import UserCell from 'src/components/UserCell' + +const UserPage = ({ id }) => { + return ( + + + + ) +} + +export default UserPage diff --git a/web/src/pages/UsersPage/UsersPage.js b/web/src/pages/UsersPage/UsersPage.js new file mode 100644 index 0000000..7331b05 --- /dev/null +++ b/web/src/pages/UsersPage/UsersPage.js @@ -0,0 +1,12 @@ +import MainLayout from 'src/layouts/MainLayout' +import UsersCell from 'src/components/UsersCell' + +const UsersPage = () => { + return ( + + + + ) +} + +export default UsersPage