/ plan.go
plan.go
1 package main 2 3 import ( 4 "encoding/json" 5 "log" 6 "strconv" 7 8 "github.com/google/uuid" 9 "github.com/maxence-charriere/go-app/v10/pkg/app" 10 shell "github.com/stateless-minds/go-ipfs-api" 11 ) 12 13 const dbPlan = "plan" 14 15 // plan is a component that holds cyber-gubi. A component is a 16 // customizable, independent, and reusable UI element. It is created by 17 // embedding app.Compo into a struct. 18 type plan struct { 19 app.Compo 20 sh *shell.Shell 21 loggedIn bool 22 userID string 23 businessName string 24 price int 25 plan Plan 26 } 27 28 type Plan struct { 29 ID string `mapstructure:"_id" json:"_id" validate:"uuid_rfc4122"` // Unique identifier for the transaction 30 Name string `mapstructure:"name" json:"name" validate:"uuid_rfc4122"` // Business name 31 Price int `mapstructure:"price" json:"price" validate:"uuid_rfc4122"` // Monthly recurring price 32 CreatedBy string `mapstructure:"created_by" json:"created_by" validate:"uuid_rfc4122"` // User ID of business who created it 33 } 34 35 func (p *plan) OnMount(ctx app.Context) { 36 sh := shell.NewShell("localhost:5001") 37 p.sh = sh 38 39 ctx.GetState("loggedIn", &p.loggedIn) 40 if !p.loggedIn { 41 ctx.Navigate("/auth") 42 } 43 44 ctx.GetState("userID", &p.userID) 45 46 ctx.ObserveState("plan", &p.plan) 47 48 ctx.ObserveState("businessName", &p.businessName) 49 } 50 51 func (p *plan) createPlan(ctx app.Context, e app.Event) { 52 e.PreventDefault() 53 valid := app.Window().GetElementByID("plan-form").Call("reportValidity").Bool() 54 if valid { 55 p.storePLan(ctx) 56 } 57 } 58 59 func (p *plan) storePLan(ctx app.Context) { 60 ctx.Async(func() { 61 var plan Plan 62 if (p.plan == Plan{}) { 63 plan = Plan{ 64 ID: uuid.NewString(), 65 Name: p.businessName, 66 Price: p.price * 100, 67 CreatedBy: p.userID, 68 } 69 } else { 70 plan = Plan{ 71 ID: p.plan.ID, 72 Name: p.businessName, 73 Price: p.price * 100, 74 CreatedBy: p.plan.CreatedBy, 75 } 76 } 77 78 planJSON, err := json.Marshal(plan) 79 if err != nil { 80 log.Fatal(err) 81 } 82 83 err = p.sh.OrbitDocsPut(dbPlan, planJSON) 84 if err != nil { 85 log.Fatal(err) 86 } 87 88 ctx.Dispatch(func(ctx app.Context) { 89 if (p.plan == Plan{}) { 90 ctx.Notifications().New(app.Notification{ 91 Title: "Success", 92 Body: "Plan created successfully!", 93 }) 94 } else { 95 ctx.Notifications().New(app.Notification{ 96 Title: "Success", 97 Body: "Plan updated successfully!", 98 }) 99 } 100 ctx.Navigate("/wallet") 101 }) 102 }) 103 } 104 105 // The Render method is where the component appearance is defined. Here, a 106 // create plan form is displayed. 107 func (p *plan) Render() app.UI { 108 return app.Div().Class("container").Body( 109 app.Div().Class("mobile").Body( 110 app.Div().Class("header").Body( 111 newNav(), 112 app.Div().Class("header-summary").Body( 113 app.Span().Class("logo").Text("cyber-gubi"), 114 app.Div().Class("summary-text").Body( 115 app.Span().Text("Plan"), 116 ), 117 ), 118 ), 119 app.Div().ID("content").Body( 120 app.Div().Class("card").Body( 121 app.Div().Class("upper-row").Body( 122 app.Div().Class("card-item").Body( 123 app.If(p.plan == Plan{}, func() app.UI { 124 return app.Span().Class("span-header").Text("Create Plan") 125 }).Else(func() app.UI { 126 return app.Span().Class("span-header").Text("Update Plan") 127 }), 128 app.Form().ID("plan-form").Body( 129 app.Div().ID("plan").Body( 130 app.If(p.plan == Plan{}, func() app.UI { 131 return app.Div().Body( 132 app.Input().ID("plan-price").Class("product").Type("number").Min(1).Name("plan-price").Placeholder("Monthly amount").Required(true).OnChange(p.ValueTo(&p.price)), 133 ) 134 }).Else(func() app.UI { 135 return app.Div().Body( 136 app.Input().ID("plan-price").Class("product").Type("number").Min(1).Name("plan-price").Placeholder(strconv.Itoa(p.plan.Price / 100)).Required(true).OnChange(p.ValueTo(&p.price)), 137 ) 138 }), 139 ), 140 app.Div().Class("drawer drawer-pay").Body( 141 app.Div().Class("menu-btn").Body( 142 app.Button().Class("submit").Type("submit").Text("Submit").OnClick(p.createPlan), 143 ), 144 ), 145 ), 146 ), 147 ), 148 ), 149 ), 150 ), 151 ) 152 }