parent
693748ee37
commit
3ccb44f6df
|
@ -17,8 +17,8 @@ body:
|
|||
options:
|
||||
- Artist
|
||||
- Administrator
|
||||
- Public User
|
||||
- Developer
|
||||
- User
|
||||
placeholder: ...role...
|
||||
validations:
|
||||
required: true
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package artist
|
||||
|
||||
import "github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
import (
|
||||
"errors"
|
||||
"git.l--n.de/nclazz/soundwerft/api/handler"
|
||||
"git.l--n.de/nclazz/soundwerft/internal/app/sketchbook"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
)
|
||||
|
||||
var (
|
||||
MsgCreateSketchbookTitle = &i18n.Message{
|
||||
|
@ -16,4 +21,45 @@ var (
|
|||
ID: "Artist.ErrCreateSketchbook",
|
||||
Other: "Failed to create sketchbook. Check your input and try again",
|
||||
}
|
||||
MsgCreateSketchTitle = &i18n.Message{
|
||||
ID: "Artist.CreateSketchTitle",
|
||||
Other: "Create new sketch",
|
||||
}
|
||||
MsgErrCreateSketch = &i18n.Message{
|
||||
ID: "Artist.ErrCreateSketch",
|
||||
Other: "Failed to create sketch. Please check your input and try again",
|
||||
}
|
||||
MsgSketchTitleLabel = &i18n.Message{
|
||||
ID: "Artist.SketchTitleLabel",
|
||||
Other: "Title",
|
||||
}
|
||||
MsgSketchDescriptionLabel = &i18n.Message{
|
||||
ID: "Artist.SketchDescriptionLabel",
|
||||
Other: "Description",
|
||||
}
|
||||
MsgSketchCreate = &i18n.Message{
|
||||
ID: "Artist.SketchCreate",
|
||||
Other: "Create",
|
||||
}
|
||||
MsgErrSketchTitleTooLong = &i18n.Message{
|
||||
ID: "Artist.SketchTitleTooLong",
|
||||
Other: "Exceeds maximum length",
|
||||
}
|
||||
MsgErrSketchDescriptionTooLong = &i18n.Message{
|
||||
ID: "Artist.SketchDescriptionTooLong",
|
||||
Other: "Exceeds maximum length",
|
||||
}
|
||||
)
|
||||
|
||||
func TranslateError(h *handler.Handler, err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
if errors.Is(err, sketchbook.ErrTitleTooLong) {
|
||||
return h.TranslateMessage(MsgErrSketchTitleTooLong)
|
||||
}
|
||||
if errors.Is(err, sketchbook.ErrDescriptionTooLong) {
|
||||
return h.TranslateMessage(MsgErrSketchDescriptionTooLong)
|
||||
}
|
||||
return err.Error()
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ func Routes(h *handler.Handler) {
|
|||
|
||||
g := h.Echo.Group("/sketchbook", guard.Authenticated(h))
|
||||
g.POST("", postCreateSketchbook(h))
|
||||
|
||||
g = h.Echo.Group("/sketch", guard.Authenticated(h))
|
||||
g.GET("/new", getCreateSketchPage(h))
|
||||
g.POST("", postCreateSketch(h))
|
||||
g.POST("/", postCreateSketch(h))
|
||||
}
|
||||
|
||||
func artistView(c echo.Context, h *handler.Handler) artist.ArtistView {
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package artist
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"git.l--n.de/nclazz/soundwerft/api/handler"
|
||||
"git.l--n.de/nclazz/soundwerft/api/web/templates/artist"
|
||||
"git.l--n.de/nclazz/soundwerft/internal/app/sketchbook"
|
||||
"git.l--n.de/nclazz/soundwerft/pkg/errx"
|
||||
"github.com/labstack/echo/v4"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
func createSketchFormView(c echo.Context, h *handler.Handler) artist.CreateSketchFormView {
|
||||
return artist.CreateSketchFormView{
|
||||
MsgTitleLabel: h.TranslateMessage(MsgSketchTitleLabel),
|
||||
MsgDescriptionLabel: h.TranslateMessage(MsgSketchDescriptionLabel),
|
||||
MsgTitle: h.TranslateMessage(MsgCreateSketchTitle),
|
||||
MsgCreate: h.TranslateMessage(MsgSketchCreate),
|
||||
}
|
||||
}
|
||||
|
||||
func getCreateSketchPage(h *handler.Handler) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
return h.Render(c, artist.CreateSketch(h.View(c), createSketchFormView(c, h)))
|
||||
}
|
||||
}
|
||||
|
||||
func postCreateSketch(h *handler.Handler) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
usr := h.User(c)
|
||||
sk, err := h.Repos.Sketchbooks.GetByOwnerID(ctx, usr.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := sketchbook.CreateSketchCommand{
|
||||
Sketchbook: sk.ID.String(),
|
||||
Title: c.FormValue("title"),
|
||||
Description: c.FormValue("description"),
|
||||
}
|
||||
view := createSketchFormView(c, h)
|
||||
view.Title = cmd.Title
|
||||
view.Description = cmd.Description
|
||||
log := h.Logger(c).With(slog.Group("sketch", "title", cmd.Title, "sketchbook", sk.ID))
|
||||
log.Info("create sketch")
|
||||
sketch, err := h.Services.Sketchbooks.CreateSketch(ctx, cmd)
|
||||
if err != nil {
|
||||
log.Warn("create sketch failed", "error", err)
|
||||
view.Err = h.TranslateMessage(MsgErrCreateSketch)
|
||||
mapCreateSketchErrs(h, &view, err)
|
||||
return h.Render(c, artist.CreateSketchForm(h.View(c), view))
|
||||
}
|
||||
log.Info("created sketch", "id", sketch.ID)
|
||||
return h.Render(c, artist.Dashboard())
|
||||
}
|
||||
}
|
||||
|
||||
func mapCreateSketchErrs(h *handler.Handler, view *artist.CreateSketchFormView, err error) {
|
||||
var errs errx.ErrMap
|
||||
if errors.As(err, &errs) {
|
||||
view.TitleErr = TranslateError(h, errs.Get("title"))
|
||||
view.DescriptionErr = TranslateError(h, errs.Get("description"))
|
||||
return
|
||||
}
|
||||
}
|
|
@ -68,7 +68,7 @@ func postLogin(h *handler.Handler) echo.HandlerFunc {
|
|||
if err := h.SaveSession(c); err != nil {
|
||||
return err
|
||||
}
|
||||
return h.HardRedirect(c, h.View(c).URLString("/artist"))
|
||||
return h.HardRedirect(c, h.View(c).URLString("/home"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package artist
|
||||
|
||||
import (
|
||||
"git.l--n.de/nclazz/soundwerft/api/web"
|
||||
"git.l--n.de/nclazz/soundwerft/api/web/templates/partials"
|
||||
)
|
||||
|
||||
type CreateSketchFormView struct {
|
||||
Title string
|
||||
Description string
|
||||
TitleErr string
|
||||
DescriptionErr string
|
||||
Err string
|
||||
MsgTitleLabel string
|
||||
MsgDescriptionLabel string
|
||||
MsgTitle string
|
||||
MsgCreate string
|
||||
}
|
||||
|
||||
|
||||
templ CreateSketch(view web.View, form CreateSketchFormView) {
|
||||
@partials.Document(view) {
|
||||
@CreateSketchForm(view, form)
|
||||
}
|
||||
}
|
||||
|
||||
templ CreateSketchForm(view web.View, form CreateSketchFormView) {
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-3">
|
||||
<h4>{ form.MsgTitle }</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-3">
|
||||
<form class="form"
|
||||
method="post"
|
||||
action={view.URL("/sketch")}
|
||||
hx-boost="true"
|
||||
hx-target="#main"
|
||||
hx-replace-url="false">
|
||||
|
||||
if form.Err != "" {
|
||||
@partials.Alert("danger") {
|
||||
{ form.Err }
|
||||
}
|
||||
}
|
||||
@partials.FormInput(partials.InputAttrs{
|
||||
ID: "sketch_title",
|
||||
Name: "title",
|
||||
Label: form.MsgTitleLabel,
|
||||
Placeholder: form.MsgTitleLabel,
|
||||
Required: true,
|
||||
Value: form.Title,
|
||||
HasErr: form.TitleErr != "",
|
||||
Err: form.TitleErr,
|
||||
})
|
||||
@partials.FormInput(partials.InputAttrs{
|
||||
ID: "sketch_description",
|
||||
Name: "description",
|
||||
Type: "textarea",
|
||||
Label: form.MsgDescriptionLabel,
|
||||
Placeholder: form.MsgDescriptionLabel,
|
||||
Value: form.Description,
|
||||
HasErr: form.DescriptionErr != "",
|
||||
Err: form.DescriptionErr,
|
||||
})
|
||||
<div class="d-grid gap-2">
|
||||
<input type="submit" class="btn btn-primary btn-lg" value={ form.MsgCreate }/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -17,6 +17,19 @@ type CreateSketchbookFormView struct {
|
|||
|
||||
templ ArtistPage(view web.View, artistView ArtistView, form CreateSketchbookFormView) {
|
||||
@partials.Document(view) {
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a class="btn btn-primary"
|
||||
href={ view.URL("/sketch/new") }
|
||||
hx-boost="true"
|
||||
hx-select="#main"
|
||||
hx-target="#main">
|
||||
Create Sketch
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
if !artistView.HasSketchbook {
|
||||
@CreateSketchbookForm(view, form)
|
||||
} else {
|
||||
|
@ -60,4 +73,3 @@ templ CreateSketchbookForm(view web.View, form CreateSketchbookFormView) {
|
|||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
|
|
@ -26,20 +26,24 @@ templ FormInput(attrs InputAttrs) {
|
|||
<div class="mb-3">
|
||||
<label for={ attrs.InputID() } class="form-label">{ attrs.Label }</label>
|
||||
<div class="input-group has-validation">
|
||||
<input id={ attrs.InputID() }
|
||||
name={ attrs.Name }
|
||||
if attrs.Type != "" {
|
||||
type={ attrs.Type }
|
||||
}
|
||||
if attrs.Placeholder != "" {
|
||||
placeholder={ attrs.Placeholder }
|
||||
}
|
||||
if attrs.Value != "" {
|
||||
value={ attrs.Value }
|
||||
}
|
||||
required?={ attrs.Required }
|
||||
class={ "form-control", templ.KV("is-invalid", attrs.HasErr), templ.KV("is-valid", attrs.Success != "" || attrs.HasSuccess) }
|
||||
/>
|
||||
if attrs.Type == "textarea" {
|
||||
@textArea(attrs)
|
||||
} else {
|
||||
<input id={ attrs.InputID() }
|
||||
name={ attrs.Name }
|
||||
if attrs.Type != "" {
|
||||
type={ attrs.Type }
|
||||
}
|
||||
if attrs.Placeholder != "" {
|
||||
placeholder={ attrs.Placeholder }
|
||||
}
|
||||
if attrs.Value != "" {
|
||||
value={ attrs.Value }
|
||||
}
|
||||
required?={ attrs.Required }
|
||||
class={ "form-control", templ.KV("is-invalid", attrs.HasErr), templ.KV("is-valid", attrs.Success != "" || attrs.HasSuccess) }
|
||||
/>
|
||||
}
|
||||
{children...}
|
||||
if attrs.Success != "" {
|
||||
<div class="valid-feedback">
|
||||
|
@ -58,6 +62,16 @@ templ FormInput(attrs InputAttrs) {
|
|||
</div>
|
||||
}
|
||||
|
||||
templ textArea(attrs InputAttrs) {
|
||||
<textarea id={attrs.ID}
|
||||
name={attrs.Name}
|
||||
placeholder={attrs.Placeholder}
|
||||
required?={attrs.Required}
|
||||
style="height: 150px"
|
||||
class={ "form-control", templ.KV("is-invalid", attrs.HasErr), templ.KV("is-valid", attrs.Success != "" || attrs.HasSuccess) }>
|
||||
{attrs.Value}</textarea>
|
||||
}
|
||||
|
||||
templ InputGroup() {
|
||||
<div class="input-group mb-3">
|
||||
{children...}
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
"Artist.CreateSketchTitle" = "Create new sketch"
|
||||
"Artist.CreateSketchbook" = "Create"
|
||||
"Artist.CreateSketchbookTitle" = "Set up your Sketchbook"
|
||||
"Artist.ErrCreateSketchbook" = "Failed to create sketchbook. Check your input and try again"
|
||||
"Artist.SketchCreate" = "Create"
|
||||
"Artist.SketchDescriptionLabel" = "Description"
|
||||
"Artist.SketchDescriptionTooLong" = "Exceeds maximum length"
|
||||
"Artist.SketchTitleLabel" = "Title"
|
||||
"Artist.SketchTitleTooLong" = "Exceeds maximum length"
|
||||
Save = "Save"
|
||||
"User.AlreadyHaveAccount" = "Already have an account?"
|
||||
"User.ConfirmPasswordLabel" = "Confirm password"
|
||||
|
|
Loading…
Reference in New Issue