mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-24 12:22:27 +03:00
Update posts/new example.
This commit is contained in:
parent
39db416e89
commit
51f7a8dbd7
@ -6,9 +6,10 @@ module Route.Posts.New exposing (ActionData, Data, route, RouteParams, Msg, Mode
|
||||
|
||||
-}
|
||||
|
||||
import BackendTask
|
||||
import BackendTask exposing (BackendTask)
|
||||
import BackendTask.Custom
|
||||
import Date
|
||||
import Debug
|
||||
import Dict
|
||||
import Effect
|
||||
import ErrorPage
|
||||
import FatalError
|
||||
@ -19,11 +20,13 @@ import Form.Validation
|
||||
import Head
|
||||
import Html
|
||||
import Html.Attributes
|
||||
import Json.Decode as Decode
|
||||
import Json.Encode as Encode
|
||||
import Pages.Msg
|
||||
import Pages.PageUrl
|
||||
import Pages.Script
|
||||
import Path
|
||||
import Platform.Sub
|
||||
import Route
|
||||
import RouteBuilder
|
||||
import Server.Request
|
||||
import Server.Response
|
||||
@ -92,7 +95,9 @@ type alias Data =
|
||||
|
||||
|
||||
type alias ActionData =
|
||||
{ errors : Form.Response String }
|
||||
{ errors : Form.Response String
|
||||
, errorMessage : Maybe String
|
||||
}
|
||||
|
||||
|
||||
data :
|
||||
@ -117,6 +122,20 @@ view maybeUrl sharedModel model app =
|
||||
{ title = "Posts.New"
|
||||
, body =
|
||||
[ Html.h2 [] [ Html.text "Form" ]
|
||||
, app.action
|
||||
|> Maybe.andThen .errorMessage
|
||||
|> Maybe.map
|
||||
(\errorMessage ->
|
||||
Html.p [ Html.Attributes.style "color" "red" ] [ Html.text errorMessage ]
|
||||
)
|
||||
|> Maybe.withDefault (Html.text "")
|
||||
, app.pageFormState
|
||||
--|> Debug.toString
|
||||
|> Dict.get "form"
|
||||
|> Maybe.andThen (.fields >> Dict.get "body")
|
||||
|> Maybe.map .value
|
||||
|> Maybe.withDefault ""
|
||||
|> Html.text
|
||||
, Form.renderHtml
|
||||
[]
|
||||
(\renderStyledHtmlUnpack -> Just renderStyledHtmlUnpack.errors)
|
||||
@ -135,14 +154,34 @@ action routeParams =
|
||||
(\formData ->
|
||||
case formData of
|
||||
( formResponse, parsedForm ) ->
|
||||
BackendTask.map
|
||||
(\_ ->
|
||||
Server.Response.render
|
||||
{ errors = formResponse }
|
||||
)
|
||||
(Pages.Script.log
|
||||
(Debug.toString parsedForm)
|
||||
)
|
||||
case parsedForm of
|
||||
Ok okForm ->
|
||||
BackendTask.Custom.run "createPost"
|
||||
(Encode.object
|
||||
[ ( "slug", Encode.string okForm.slug )
|
||||
, ( "title", Encode.string okForm.title )
|
||||
, ( "body", Encode.string okForm.body )
|
||||
]
|
||||
)
|
||||
(Decode.oneOf
|
||||
[ Decode.field "errorMessage" (Decode.string |> Decode.map Err)
|
||||
, Decode.succeed (Ok ())
|
||||
]
|
||||
)
|
||||
|> BackendTask.allowFatal
|
||||
|> BackendTask.map
|
||||
(\result ->
|
||||
case result of
|
||||
Ok () ->
|
||||
Route.redirectTo Route.Index
|
||||
|
||||
Err errorMessage ->
|
||||
Server.Response.render { errors = formResponse, errorMessage = Just errorMessage }
|
||||
)
|
||||
|
||||
Err errors ->
|
||||
Server.Response.render { errors = formResponse, errorMessage = Nothing }
|
||||
|> BackendTask.succeed
|
||||
)
|
||||
(Server.Request.formData (Form.initCombined Basics.identity form))
|
||||
|
||||
@ -155,7 +194,7 @@ form =
|
||||
"Required"
|
||||
(Form.Field.date { invalid = \_ -> "" })
|
||||
)
|
||||
((\title slug markdown publish ->
|
||||
((\title slug body publish ->
|
||||
{ combine =
|
||||
ParsedForm
|
||||
|> Form.Validation.succeed
|
||||
@ -173,7 +212,7 @@ form =
|
||||
Form.Validation.mapWithNever identity slug
|
||||
)
|
||||
)
|
||||
|> Form.Validation.andMap markdown
|
||||
|> Form.Validation.andMap body
|
||||
|> Form.Validation.andMap publish
|
||||
, view =
|
||||
\formState ->
|
||||
@ -193,21 +232,33 @@ form =
|
||||
in
|
||||
[ fieldView "title" title
|
||||
, fieldView "slug" slug
|
||||
, fieldView "markdown" markdown
|
||||
, fieldView "body" body
|
||||
, fieldView "publish" publish
|
||||
, Html.button [] [ Html.text "Submit" ]
|
||||
, if formState.isTransitioning then
|
||||
Html.button [ Html.Attributes.disabled True ]
|
||||
[ Html.text "Submitting..."
|
||||
]
|
||||
|
||||
else
|
||||
Html.button []
|
||||
[ Html.text "Submit"
|
||||
]
|
||||
]
|
||||
}
|
||||
)
|
||||
|> Form.init
|
||||
|> Form.field "title" (Form.Field.required "Required" Form.Field.text)
|
||||
|> Form.field "slug" (Form.Field.required "Required" Form.Field.text)
|
||||
|> Form.field "markdown" (Form.Field.required "Required" Form.Field.text |> Form.Field.textarea)
|
||||
|> Form.field "body"
|
||||
(Form.Field.required "Required" Form.Field.text
|
||||
|> Form.Field.textarea
|
||||
{ rows = Just 30, cols = Just 80 }
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
type alias ParsedForm =
|
||||
{ title : String, slug : String, markdown : String, publish : Date.Date }
|
||||
{ title : String, slug : String, body : String, publish : Date.Date }
|
||||
|
||||
|
||||
errorsView :
|
||||
|
@ -1,63 +1,49 @@
|
||||
import kleur from "kleur";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/index.js";
|
||||
|
||||
kleur.enabled = true;
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export async function environmentVariable(name: string) {
|
||||
const result = process.env[name];
|
||||
if (result) {
|
||||
return result;
|
||||
} else {
|
||||
throw `No environment variable called ${kleur
|
||||
.yellow()
|
||||
.underline(name)}\n\nAvailable:\n\n${Object.keys(process.env)
|
||||
.slice(0, 5)
|
||||
.join("\n")}`;
|
||||
export async function createPost({ slug, title, body }) {
|
||||
try {
|
||||
await prisma.post.create({
|
||||
data: {
|
||||
slug,
|
||||
title,
|
||||
body,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof PrismaClientKnownRequestError) {
|
||||
console.log("MESSAGE:", e.message, e.meta, e.code, e.name);
|
||||
console.dir(e);
|
||||
|
||||
return { errorMessage: e.message };
|
||||
|
||||
// specific error
|
||||
} else {
|
||||
console.trace(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function hello(name: string) {
|
||||
await waitFor(1000);
|
||||
return `147 ${name}!!`;
|
||||
export async function posts() {
|
||||
return (await prisma.post.findMany()).map(transformDates);
|
||||
}
|
||||
|
||||
function waitFor(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export async function addItem(name: string) {
|
||||
let timeToWait = 0;
|
||||
try {
|
||||
timeToWait = parseInt(name);
|
||||
} catch (e) {}
|
||||
|
||||
console.log("Adding ", name);
|
||||
await fs.promises.writeFile(path.join(folder, name), "");
|
||||
await waitFor(timeToWait);
|
||||
return await listFiles();
|
||||
}
|
||||
const folder = "./items-list";
|
||||
|
||||
async function listFiles(): Promise<string[]> {
|
||||
return (await fs.promises.readdir(folder)).filter(
|
||||
(file) => !file.startsWith(".")
|
||||
function transformDates(item) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(item).map(([key, value]) => [key, transformValue(value)])
|
||||
);
|
||||
}
|
||||
|
||||
export async function getItems() {
|
||||
return await listFiles();
|
||||
}
|
||||
|
||||
export async function deleteAllItems(name: string) {
|
||||
for (const file of await listFiles()) {
|
||||
await fs.promises.unlink(path.join(folder, file));
|
||||
function transformValue(value) {
|
||||
// if (typeof value === "bigint") {
|
||||
// obj[key] = toNumber(value);
|
||||
// }
|
||||
if (value instanceof Date) {
|
||||
return value.getMilliseconds();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
|
||||
return await listFiles();
|
||||
}
|
||||
|
||||
export async function log(message: string) {
|
||||
console.log(message);
|
||||
return null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user