Made more progress.

This commit is contained in:
Martin Sosic 2020-11-24 20:39:36 +01:00
parent 85d8f5066c
commit 08238e69b2
10 changed files with 188 additions and 22 deletions

View File

@ -12,8 +12,8 @@ Todo:
- [x] Profile page that shows basic user info.
- [x] Home page with navbar.
- [x] CRUD Articles (created from Markdown).
- [ ] On /article page, show author username and date of creation (of article).
- [ ] Render article content as markdown.
- [x] On /article page, show author username and date of creation (of article).
- [x] Render article content as markdown.
- [ ] For Article, use special id which contains title in the name, and display it in url?
- [ ] CR*D Comments on articles.
- [ ] Paginated list of articles.

View File

@ -102,8 +102,7 @@ const ArticleEditor = (props) => {
/>
<h2>Markdown content</h2>
<input
type='text'
<textarea
value={markdownContent}
onChange={e => setMarkdownContent(e.target.value)}
/>

View File

@ -1,10 +1,13 @@
import React from 'react'
import { useHistory } from 'react-router-dom'
import ReactMarkdown from 'react-markdown'
import moment from 'moment'
import useAuth from '@wasp/auth/useAuth.js'
import { useQuery } from '@wasp/queries'
import getArticle from '@wasp/queries/getArticle'
import getUser from '@wasp/queries/getUser'
import deleteArticle from '@wasp/actions/deleteArticle'
import Navbar from './Navbar'
@ -46,10 +49,17 @@ const ArticleViewPage = (props) => {
<div>
<Navbar />
<div>
<div> Author: { article.user.username } </div>
<div> Created at: { moment(article.createdAt).format('MMMM DD, YYYY') } </div>
</div>
<div>
<p> { article.title } </p>
<p> { article.description } </p>
<p> { article.markdownContent } </p>
<p>
<ReactMarkdown children={article.markdownContent} />
</p>
</div>
{ isMyArticle && (

View File

@ -86,8 +86,7 @@ const UserSettings = (props) => {
/>
<h2>Short bio</h2>
<input
type='text'
<textarea
value={bio}
onChange={e => setBio(e.target.value)}
/>

View File

@ -1,8 +1,22 @@
import HttpError from '@wasp/core/HttpError.js'
const userPublicSelection = {
id: true,
username: true,
email: true,
bio: true,
profilePictureUrl: true
}
export const getUser = async ({ username }, context) => {
// TODO: Do some error handling?
const user = await context.entities.User.findOne({ where: { username } })
const user = await context.entities.User.findOne({
where: { username },
// TODO: Tricky, if you forget this you could return unwanted fields
// like hashed password!
// It would be cool if we had some protection against making this mistake easily.
select: userPublicSelection
})
if (!user) throw new HttpError(404, 'No user with username ' + username)
return user
}
@ -10,17 +24,24 @@ export const getUser = async ({ username }, context) => {
export const getArticlesByUser = async ({ username }, context) => {
// TODO: Do some error handling?
const articles = await context.entities.Article.findMany({
where: {
user: { username }
}
where: { user: { username } }
})
return articles
}
export const getArticle = async ({ id }, context) => {
// TODO: Do some error handling?
const article = await context.entities.Article.findOne({
where: { id }
})
const article = await context.entities.Article
.findOne({
where: { id },
include: {
user: {
// TODO: Tricky, if you forget this you could return unwanted fields
// like hashed password!
// It would be cool if we had some protection against making this mistake easily.
select: userPublicSelection
}
}
})
return article
}

View File

@ -53,12 +53,13 @@ psl=}
// TODO: Add tags.
// TODO: Add creation and update times.
entity Article {=psl
id Int @id @default(autoincrement())
title String
description String
markdownContent String
user User @relation(fields: [userId], references: [id])
userId Int
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
title String
description String
markdownContent String
user User @relation(fields: [userId], references: [id])
userId Int
psl=}
auth {
@ -104,4 +105,9 @@ action updateArticle {
action deleteArticle {
fn: import { deleteArticle } from "@ext/actions.js",
entities: [Article]
}
}
dependencies {=json
"react-markdown": "5.0.3",
"moment": "2.29.1"
json=}

View File

@ -0,0 +1,62 @@
# Migration `20201124192901-added-created-at-to-article`
This migration has been generated by Martin Sosic at 11/24/2020, 8:29:01 PM.
You can check out the [state of the schema](./schema.prisma) after the migration.
## Database Steps
```sql
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Article" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"title" TEXT NOT NULL,
"description" TEXT NOT NULL,
"markdownContent" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_Article" ("id", "title", "description", "markdownContent", "userId") SELECT "id", "title", "description", "markdownContent", "userId" FROM "Article";
DROP TABLE "Article";
ALTER TABLE "new_Article" RENAME TO "Article";
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON
```
## Changes
```diff
diff --git schema.prisma schema.prisma
migration 20201119144622-added-article-entity..20201124192901-added-created-at-to-article
--- datamodel.dml
+++ datamodel.dml
@@ -1,8 +1,8 @@
datasource db {
provider = "sqlite"
- url = "***"
+ url = "***"
}
generator client {
provider = "prisma-client-js"
@@ -19,12 +19,13 @@
articles Article[]
}
model Article {
- id Int @id @default(autoincrement())
- title String
- description String
- markdownContent String
- user User @relation(fields: [userId], references: [id])
- userId Int
+ id Int @id @default(autoincrement())
+ createdAt DateTime @default(now())
+ title String
+ description String
+ markdownContent String
+ user User @relation(fields: [userId], references: [id])
+ userId Int
}
```

View File

@ -0,0 +1,31 @@
datasource db {
provider = "sqlite"
url = "***"
}
generator client {
provider = "prisma-client-js"
output = "../server/node_modules/.prisma/client"
}
model User {
id Int @id @default(autoincrement())
username String @unique
email String @unique
password String
bio String?
profilePictureUrl String?
articles Article[]
}
model Article {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
title String
description String
markdownContent String
user User @relation(fields: [userId], references: [id])
userId Int
}

View File

@ -0,0 +1,37 @@
{
"version": "0.3.14-fixed",
"steps": [
{
"tag": "CreateField",
"model": "Article",
"field": "createdAt",
"type": "DateTime",
"arity": "Required"
},
{
"tag": "CreateDirective",
"location": {
"path": {
"tag": "Field",
"model": "Article",
"field": "createdAt"
},
"directive": "default"
}
},
{
"tag": "CreateArgument",
"location": {
"tag": "Directive",
"path": {
"tag": "Field",
"model": "Article",
"field": "createdAt"
},
"directive": "default"
},
"argument": "",
"value": "now()"
}
]
}

View File

@ -3,4 +3,5 @@
20201030161549-user
20201030185724-fixed-user
20201117145436-added-bio-and-picture-to-user
20201119144622-added-article-entity
20201119144622-added-article-entity
20201124192901-added-created-at-to-article