Compare commits
3 Commits
4d449e2b9d
...
0b29602cb8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b29602cb8 | ||
|
|
e8d4d8d8ab | ||
|
|
9b7166f3b6 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/flake.lock
|
||||
/go.sum
|
||||
0
cmd/web/main.go
Normal file
0
cmd/web/main.go
Normal file
101
doc/ProjectStructure.md
Normal file
101
doc/ProjectStructure.md
Normal file
@ -0,0 +1,101 @@
|
||||
# Project Structure
|
||||
|
||||
<!--toc:start-->
|
||||
- [Project Structure](#project-structure)
|
||||
- [Data Flow](#data-flow)
|
||||
- [Directory Structure](#directory-structure)
|
||||
- [Handler](#internalapphanders)
|
||||
- [Services](#internalappservices)
|
||||
- [Domain](#internaldomain)
|
||||
- [Infrastructure](#internalinfrastructuredatabase)
|
||||
- [Templates](#internaltemplates)
|
||||
- [Static](#webstatic)
|
||||
<!--toc:end-->
|
||||
|
||||
This document describes how the **Potion project** is build. Where each piece can
|
||||
be found, and where new pieces should be built.
|
||||
|
||||
This project attempts to follow the **Domain Driven Design** (DDD) pattern which
|
||||
means that the software should be written in a way that represents the business
|
||||
requirements and domain. The goal is to produce software that is technically
|
||||
sound but also a strong reflection of the business domain.
|
||||
|
||||
DDD implementation in this project means that each "domain" (users, recipes,
|
||||
etc) are defined in their own domain segment and should be used throughout the
|
||||
project.
|
||||
|
||||
|
||||
## Data Flow
|
||||
|
||||
Data flows through a strict pipe line, as described bellow:
|
||||
|
||||
```md
|
||||
**HTTP > handler > service > repository**
|
||||
```
|
||||
|
||||
The data is first send from the client via **HTTP**. The data is routed to the
|
||||
proper **handler** which will take control of request and eventually send the
|
||||
response back to the client.
|
||||
|
||||
The handler will then call the proper **service** which will complete any business
|
||||
logic required before sending the data to the respective **repository.** This
|
||||
repository (which implemented the proper *domain* interface) will communicate with
|
||||
the database and perform and database actions, finally returning the new data
|
||||
back to the service.
|
||||
|
||||
Finally, the service will clean up the data and ensure the data fits into the
|
||||
proper *domain* object and is then bubbled back up to the handler which sends the
|
||||
response to the client.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
The directory structure of this project intends to achieve the most efficient
|
||||
structure while still meeting the goals defined above.
|
||||
|
||||
|
||||
#### `internal/app/handers`
|
||||
|
||||
**Handlers** are responsible for receiving requests and sending back responses.
|
||||
These strongly mimic the controller in the well-known **Model View Controller**
|
||||
(MVC) architecture. Very little logic takes place here.
|
||||
|
||||
|
||||
#### `internal/app/services`
|
||||
|
||||
**Services** are responsible for the majority of the software's business logic. When
|
||||
a request is received by the handler, the service is called and executes all logic
|
||||
required to achieve the end response. However, the service has no communication
|
||||
and therefore relies on the repository for the database.
|
||||
|
||||
#### `internal/domain`
|
||||
|
||||
The **domain** is the definition of the data models and interfaces that are used by
|
||||
the application. The data model of each domain object is defined here as well as
|
||||
the respective service and repository interfaces are defined here. No logic will
|
||||
be placed here, simply just definitions and interfaces.
|
||||
|
||||
#### `internal/infrastructure/database`
|
||||
|
||||
The **infrastructure** module is responsible for housing communication to outside
|
||||
sources, such as the database. The database section (defined here) contains all
|
||||
**migrations**: SQL definitions of database changes. It also contains all of the
|
||||
**repository** implementations as defined by the domain interfaces.
|
||||
|
||||
#### `internal/templates`
|
||||
**Templates** are HTML templates which are served to the user as the web UI. This
|
||||
directory has a very module structure; being broken down into many categories:
|
||||
|
||||
- **Layouts:** Page layouts and other large wrappers.
|
||||
- **Components:** Small scale components for use in various other templates.
|
||||
- **Partials:** Smallest size elements: common buttons, headers, text elements.
|
||||
- **Pages:** Individual pages which are composed and served to the user.
|
||||
|
||||
|
||||
#### `web/static`
|
||||
|
||||
**Static** documents, elements, or other assets are stored in the web directory.
|
||||
Items such as images, icons, style sheets, or even JS scripts can be stored here.
|
||||
This directory will be hosted by the server as a static directory for access by
|
||||
the UI.
|
||||
|
||||
|
||||
45
examples/hello.templ
Normal file
45
examples/hello.templ
Normal file
@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
script log(s string) {
|
||||
console.log(s)
|
||||
}
|
||||
|
||||
templ hello(name string) {
|
||||
<div>Hello, { name }</div>
|
||||
}
|
||||
|
||||
templ headerTemplate(name string) {
|
||||
<header data-testid="headerTemplate">
|
||||
<h1>{ name } </h1>
|
||||
</header>
|
||||
}
|
||||
|
||||
templ button(text string) {
|
||||
<button onClick={log("clicked")} class="button">
|
||||
{ text }
|
||||
</button>
|
||||
}
|
||||
|
||||
templ component(testID string) {
|
||||
<p data-testid={ testID }>text </p>
|
||||
@headerTemplate("Hayden")
|
||||
}
|
||||
|
||||
templ page2() {
|
||||
<p
|
||||
if 5==5 {
|
||||
class="also five"
|
||||
}
|
||||
>
|
||||
if 5 == 5 {
|
||||
"five is five"
|
||||
}
|
||||
</p>
|
||||
@component("testid-123")
|
||||
}
|
||||
|
||||
templ spread(attrs templ.Attributes) {
|
||||
<p class="bg-red-500" { attrs... }>
|
||||
Text
|
||||
</p>
|
||||
}
|
||||
296
examples/hello_templ.go
Normal file
296
examples/hello_templ.go
Normal file
@ -0,0 +1,296 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.865
|
||||
package main
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func log(s string) templ.ComponentScript {
|
||||
return templ.ComponentScript{
|
||||
Name: `__templ_log_bfa8`,
|
||||
Function: `function __templ_log_bfa8(s){console.log(s)
|
||||
}`,
|
||||
Call: templ.SafeScript(`__templ_log_bfa8`, s),
|
||||
CallInline: templ.SafeScriptInline(`__templ_log_bfa8`, s),
|
||||
}
|
||||
}
|
||||
|
||||
func hello(name string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div>Hello, ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/hello.templ`, Line: 8, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func headerTemplate(name string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<header data-testid=\"headerTemplate\"><h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/hello.templ`, Line: 13, Col: 12}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</h1></header>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func button(text string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, log("clicked"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<button onClick=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 templ.ComponentScript = log("clicked")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6.Call)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" class=\"button\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(text)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/hello.templ`, Line: 19, Col: 9}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func component(testID string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var8 == nil {
|
||||
templ_7745c5c3_Var8 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<p data-testid=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(testID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/hello.templ`, Line: 24, Col: 24}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\">text </p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = headerTemplate("Hayden").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func page2() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var10 == nil {
|
||||
templ_7745c5c3_Var10 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<p")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if 5 == 5 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"also five\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, ">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if 5 == 5 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\"five is five\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = component("testid-123").Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func spread(attrs templ.Attributes) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<p class=\"bg-red-500\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, attrs)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, ">Text</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
19
examples/main.go
Normal file
19
examples/main.go
Normal file
@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
func main() {
|
||||
component := page2()
|
||||
btn := button("Click me")
|
||||
|
||||
http.Handle("/", templ.Handler(component))
|
||||
http.Handle("/button", templ.Handler(btn))
|
||||
|
||||
fmt.Println("Listening on :3000")
|
||||
http.ListenAndServe(":3000", nil)
|
||||
}
|
||||
48
flake.nix
Normal file
48
flake.nix
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
description = "Go development flake. Adjust as needed.";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
in
|
||||
{
|
||||
# Define the development shell.
|
||||
# When you run `nix develop` (or direnv activates), you'll enter this shell.
|
||||
devShells.default = pkgs.mkShell {
|
||||
# List all the development tools you need available in this shell's PATH.
|
||||
packages = with pkgs; [
|
||||
go
|
||||
gopls
|
||||
go-tools
|
||||
htmx-lsp2
|
||||
templ
|
||||
tailwindcss_4
|
||||
tailwindcss-language-server
|
||||
];
|
||||
|
||||
# Define the shell that will be executed.
|
||||
# Here, we explicitly use zsh.
|
||||
# Note: pkgs.zsh needs to be included in `packages` or `nativeBuildInputs`
|
||||
# for it to be found in the shell's environment. `inherit pkgs.zsh;` is concise.
|
||||
inherit (pkgs) zsh;
|
||||
|
||||
# Environment variables and commands to run when the shell starts.
|
||||
shellHook = ''
|
||||
# Use the .local directory instead of home
|
||||
export GOPATH="$HOME/.local/go"
|
||||
echo "Settings GOPATH to: $HOME/.local/go "
|
||||
|
||||
# Exec zsh to replace the current shell process with zsh.
|
||||
# This ensures your prompt and zsh configurations load correctly.
|
||||
exec zsh
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/haydenhargreaves/Potion
|
||||
|
||||
go 1.24.3
|
||||
|
||||
require github.com/a-h/templ v0.3.898 // indirect
|
||||
0
internal/app/handlers/recipe_handler.go
Normal file
0
internal/app/handlers/recipe_handler.go
Normal file
0
internal/app/handlers/user_handler.go
Normal file
0
internal/app/handlers/user_handler.go
Normal file
0
internal/app/server/server.go
Normal file
0
internal/app/server/server.go
Normal file
0
internal/app/services/recipe_service.go
Normal file
0
internal/app/services/recipe_service.go
Normal file
0
internal/app/services/user_service.go
Normal file
0
internal/app/services/user_service.go
Normal file
0
internal/domain/recipe/recipe.go
Normal file
0
internal/domain/recipe/recipe.go
Normal file
0
internal/domain/recipe/repository.go
Normal file
0
internal/domain/recipe/repository.go
Normal file
0
internal/domain/recipe/service.go
Normal file
0
internal/domain/recipe/service.go
Normal file
0
internal/domain/user/repository.go
Normal file
0
internal/domain/user/repository.go
Normal file
0
internal/domain/user/service.go
Normal file
0
internal/domain/user/service.go
Normal file
0
internal/domain/user/user.go
Normal file
0
internal/domain/user/user.go
Normal file
0
internal/templates/components/button.templ
Normal file
0
internal/templates/components/button.templ
Normal file
10
internal/templates/components/button_templ.go
Normal file
10
internal/templates/components/button_templ.go
Normal file
@ -0,0 +1,10 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.865
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
0
internal/templates/layouts/app_layout.templ
Normal file
0
internal/templates/layouts/app_layout.templ
Normal file
10
internal/templates/layouts/app_layout_templ.go
Normal file
10
internal/templates/layouts/app_layout_templ.go
Normal file
@ -0,0 +1,10 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.865
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
0
internal/templates/pages/home.templ
Normal file
0
internal/templates/pages/home.templ
Normal file
10
internal/templates/pages/home_templ.go
Normal file
10
internal/templates/pages/home_templ.go
Normal file
@ -0,0 +1,10 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.865
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
0
internal/templates/partials/row.templ
Normal file
0
internal/templates/partials/row.templ
Normal file
10
internal/templates/partials/row_templ.go
Normal file
10
internal/templates/partials/row_templ.go
Normal file
@ -0,0 +1,10 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.865
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
5
tailwind.config.js
Normal file
5
tailwind.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
content: ["./**/*.html", "./**/*.templ", "./**/*.go",],
|
||||
theme: { extend: {}, },
|
||||
plugins: [],
|
||||
}
|
||||
0
web/static/css/style.css
Normal file
0
web/static/css/style.css
Normal file
0
web/static/img/.gitkeep
Normal file
0
web/static/img/.gitkeep
Normal file
Loading…
x
Reference in New Issue
Block a user