Initial commit
This commit is contained in:
commit
77f1d417c9
13
.dockerignore
Normal file
13
.dockerignore
Normal file
@ -0,0 +1,13 @@
|
||||
.git
|
||||
data
|
||||
run
|
||||
bin
|
||||
nginx
|
||||
dist
|
||||
|
||||
.DS_Store
|
||||
._.DS_Store
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
||||
|
||||
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
.DS_Store
|
||||
._.DS_Store
|
||||
node_modules
|
||||
package-lock.json
|
||||
dist/*
|
||||
bin/*
|
||||
data/db/data.db
|
||||
nginx/flip_cohen.conf
|
||||
data/config/config.yaml
|
||||
dockercompose/*
|
||||
!dockercompose/docker-compose.yaml
|
||||
!.keep
|
||||
48
Dockerfile
Normal file
48
Dockerfile
Normal file
@ -0,0 +1,48 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
##
|
||||
## Build
|
||||
##
|
||||
FROM golang:alpine AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk update
|
||||
RUN apk add --update gcc g++
|
||||
RUN apk add --update python3
|
||||
RUN apk add --update npm
|
||||
|
||||
COPY package.json ./package.json
|
||||
RUN npm i
|
||||
|
||||
COPY ./src ./src
|
||||
COPY ./gulpfile.js ./gulpfile.js
|
||||
COPY ./webpack.config.js ./webpack.config.js
|
||||
RUN npx gulp build
|
||||
|
||||
COPY go.mod .
|
||||
COPY go.sum .
|
||||
RUN go mod download
|
||||
RUN go install github.com/mattn/go-sqlite3
|
||||
|
||||
COPY . ./
|
||||
RUN ls -l
|
||||
RUN mkdir bin
|
||||
RUN go build -o bin/thomasshop
|
||||
|
||||
##
|
||||
## Deploy
|
||||
##
|
||||
FROM alpine:latest
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY --from=build /app/bin/thomasshop /bin
|
||||
COPY --from=build /app/dist /dist
|
||||
COPY --from=build /app/templates /templates
|
||||
RUN echo "#!/bin/ash" > /run.sh
|
||||
RUN echo "cp -r /dist/* /outdist" >> /run.sh
|
||||
RUN echo "exec /bin/thomasshop" >> /run.sh
|
||||
RUN chmod +x /run.sh
|
||||
|
||||
ENTRYPOINT ["/run.sh"]
|
||||
21
Makefile
Normal file
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
.PHONY: all clean config
|
||||
|
||||
all: bin/site_flip dist/js/shared.js dist/css/index.css config
|
||||
|
||||
bin/site_flip: main.go events.go albums.go
|
||||
go build main.go events.go albums.go && mv main bin/site_flip
|
||||
|
||||
dist/js/shared.js: $(wildcard src/js/*.js src/js/*/*.js)
|
||||
NODE_ENV=production gulp build
|
||||
|
||||
dist/css/index.css: $(wildcard src/sass/*.scss src/sass/*/*.scss)
|
||||
NODE_ENV=production gulp build
|
||||
|
||||
config: nginx/flip_cohen.conf
|
||||
|
||||
nginx/flip_cohen.conf: nginx/template.conf
|
||||
./init.sh `pwd`
|
||||
|
||||
clean:
|
||||
rm -f nginx/flip_cohen.conf
|
||||
rm -f bin/site_flip
|
||||
152
albums.go
Normal file
152
albums.go
Normal file
@ -0,0 +1,152 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Song struct {
|
||||
Title string
|
||||
Lyrics []string
|
||||
Path string
|
||||
NR string
|
||||
}
|
||||
|
||||
type Album struct {
|
||||
Name string
|
||||
Release string
|
||||
Path string
|
||||
Songs []Song
|
||||
Links map[string]string
|
||||
}
|
||||
|
||||
const ALBUM_DIR = "./data/albums/"
|
||||
|
||||
var albums []*Album
|
||||
|
||||
func parseAlbumName(fName string) (string, string) {
|
||||
s := strings.Split(fName, ".")
|
||||
s = strings.Split(s[0], "_")
|
||||
|
||||
return s[0], strings.Join(s[1:], " ")
|
||||
}
|
||||
|
||||
func ParseSong(s os.FileInfo, basePath string) Song {
|
||||
nr, title := parseAlbumName(s.Name())
|
||||
|
||||
f, err := os.Open(path.Join(basePath, s.Name()))
|
||||
defer f.Close()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(f)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
lyrics := strings.Split(string(content), "\n\n")
|
||||
|
||||
song := Song{
|
||||
Title: title,
|
||||
Lyrics: lyrics,
|
||||
Path: strings.ToLower(strings.Replace(title, " ", "-", -1)),
|
||||
NR: nr,
|
||||
}
|
||||
|
||||
return song
|
||||
}
|
||||
|
||||
func getSong(album *Album, title string) (Song, error) {
|
||||
for _, song := range album.Songs {
|
||||
if song.Path == strings.ToLower(title) {
|
||||
return song, nil
|
||||
}
|
||||
}
|
||||
|
||||
return Song{}, io.EOF
|
||||
}
|
||||
|
||||
func ParseAlbum(f os.FileInfo) *Album {
|
||||
year, name := parseAlbumName(f.Name())
|
||||
|
||||
filen := path.Join(ROOT_DIR, ALBUM_DIR, f.Name())
|
||||
|
||||
files, err := ioutil.ReadDir(filen)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error read songs: %s", err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
album := Album{
|
||||
Name: name,
|
||||
Path: strings.ToLower(strings.Replace(name, " ", "-", -1)),
|
||||
Release: year,
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if !strings.HasSuffix(f.Name(), ".lyric") {
|
||||
continue
|
||||
}
|
||||
album.Songs = append(album.Songs, ParseSong(f, filen))
|
||||
}
|
||||
|
||||
fd, err := os.Open(path.Join(filen, "info.json"))
|
||||
defer fd.Close()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error info.json: %s", err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
content, _ := ioutil.ReadAll(fd)
|
||||
|
||||
json.Unmarshal(content, &album)
|
||||
|
||||
return &album
|
||||
}
|
||||
|
||||
func getAlbum(albums []*Album, title string) (*Album, error) {
|
||||
for _, album := range albums {
|
||||
if album.Path == strings.ToLower(title) {
|
||||
return album, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
func getAlbums() []*Album {
|
||||
if albums != nil {
|
||||
return albums
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(path.Join(ROOT_DIR, ALBUM_DIR))
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if strings.HasPrefix(f.Name(), ".") {
|
||||
continue
|
||||
}
|
||||
albums = append(albums, ParseAlbum(f))
|
||||
}
|
||||
|
||||
for i := len(albums)/2 - 1; i >= 0; i-- {
|
||||
opp := len(albums) - 1 - i
|
||||
albums[i], albums[opp] = albums[opp], albums[i]
|
||||
}
|
||||
|
||||
return albums
|
||||
}
|
||||
0
data/config/.keep
Normal file
0
data/config/.keep
Normal file
0
data/db/.keep
Normal file
0
data/db/.keep
Normal file
136
db.go
Normal file
136
db.go
Normal file
@ -0,0 +1,136 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
|
||||
sqlite "gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
PRE_ORDER_STATE_CREATED = "CREATED"
|
||||
)
|
||||
|
||||
func initDB() (*gorm.DB, error) {
|
||||
log.Printf("Connect to DB on path: %v", path.Join(ROOT_DIR, "data/db/data.db"))
|
||||
|
||||
newLogger := logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // Slow SQL threshold
|
||||
LogLevel: logger.Info, // Log level
|
||||
Colorful: false, // Disable color
|
||||
},
|
||||
)
|
||||
|
||||
db, err := gorm.Open(sqlite.Open(path.Join(ROOT_DIR, "data/db/data.db")), &gorm.Config{
|
||||
Logger: newLogger,
|
||||
})
|
||||
return db, err
|
||||
}
|
||||
|
||||
type Product struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
Image string
|
||||
Description string
|
||||
Price int
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
gorm.Model
|
||||
ProductID uint
|
||||
Product Product
|
||||
PreOrderID uuid.UUID
|
||||
PreOrder PreOrder
|
||||
}
|
||||
|
||||
type MolliePayment struct {
|
||||
gorm.Model
|
||||
MolliePaymentID string
|
||||
Amount int
|
||||
Status string
|
||||
PreOrderID uuid.UUID
|
||||
PreOrder PreOrder
|
||||
}
|
||||
|
||||
type PreOrder struct {
|
||||
ID uuid.UUID `sql:"type:string;primary_key;"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt *time.Time `sql:"index"`
|
||||
Name string
|
||||
Email string
|
||||
Items []Item
|
||||
Address string
|
||||
Postcode string
|
||||
City string
|
||||
Country string
|
||||
Status string
|
||||
MolliePayments []MolliePayment
|
||||
}
|
||||
|
||||
var nullUUID = uuid.UUID{}
|
||||
|
||||
func (base *PreOrder) BeforeCreate(scope *gorm.DB) error {
|
||||
fmt.Println(base.ID.String(), nullUUID.String())
|
||||
if base.ID.String() == nullUUID.String() {
|
||||
id := uuid.NewV4()
|
||||
base.ID = id
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (po *PreOrder) CalcTotal() int {
|
||||
total := 0
|
||||
|
||||
for _, i := range po.Items {
|
||||
total += i.Product.Price
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
func insertProducts(db *gorm.DB) {
|
||||
db.Create(&Product{
|
||||
Name: "Methods to Madness | LP",
|
||||
Image: "/static/img/mtm.jpg",
|
||||
Description: "Methods to Madness LP",
|
||||
Price: 2999,
|
||||
})
|
||||
|
||||
db.Create(&Product{
|
||||
Name: "Methods to Madness | CD",
|
||||
Image: "/static/img/mtm.jpg",
|
||||
Description: "Methods to Madness CD",
|
||||
Price: 1999,
|
||||
})
|
||||
}
|
||||
|
||||
func GetDB() *gorm.DB {
|
||||
db, err := initDB()
|
||||
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
}
|
||||
|
||||
// Migrate the schema
|
||||
db.AutoMigrate(
|
||||
&Product{},
|
||||
&Item{},
|
||||
&PreOrder{},
|
||||
&MolliePayment{},
|
||||
)
|
||||
|
||||
products := []Product{}
|
||||
db.Find(&products)
|
||||
|
||||
return db
|
||||
}
|
||||
0
dist/.keep
vendored
Normal file
0
dist/.keep
vendored
Normal file
18
dockercompose/docker-compose.yaml
Normal file
18
dockercompose/docker-compose.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
version: '3.0'
|
||||
services:
|
||||
alex:
|
||||
image: dregistry.baskloosterman.nl:5000/thomasshop
|
||||
container_name: thomasshop
|
||||
restart: always
|
||||
volumes:
|
||||
- "./thomas/data:/data"
|
||||
- "./thomas/dist:/outdist"
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: nginx_thomas
|
||||
restart: always
|
||||
volumes:
|
||||
- "./thomas/nginx:/etc/nginx/conf.d"
|
||||
- "./thomas/dist:/var/www/thomas/dist"
|
||||
ports:
|
||||
- "3999:80"
|
||||
185
events.go
Normal file
185
events.go
Normal file
@ -0,0 +1,185 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MyTime time.Time
|
||||
|
||||
func (mt *MyTime) UnmarshalJSON(b []byte) error {
|
||||
s := strings.Trim(string(b), "\"")
|
||||
t, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*mt = MyTime(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseDate(b string) MyTime {
|
||||
s := strings.Trim(b, "\"")
|
||||
t, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return MyTime{}
|
||||
}
|
||||
return MyTime(t)
|
||||
}
|
||||
|
||||
func (mt *MyTime) ParseDate(b []byte) error {
|
||||
s := strings.Trim(string(b), "\"")
|
||||
t, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*mt = MyTime(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mt MyTime) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(mt)
|
||||
}
|
||||
|
||||
var months = map[string]string{
|
||||
"1": "Jan",
|
||||
"2": "Feb",
|
||||
"3": "Mrt",
|
||||
"4": "Apr",
|
||||
"5": "Mei",
|
||||
"6": "Jun",
|
||||
"7": "Jul",
|
||||
"8": "Aug",
|
||||
"9": "Sept",
|
||||
"10": "Okt",
|
||||
"11": "Nov",
|
||||
"12": "Dec",
|
||||
}
|
||||
|
||||
var monthsLong = map[string]string{
|
||||
"1": "Januari",
|
||||
"2": "Februari",
|
||||
"3": "Maart",
|
||||
"4": "April",
|
||||
"5": "Mei",
|
||||
"6": "Juni",
|
||||
"7": "July",
|
||||
"8": "Augustus",
|
||||
"9": "September",
|
||||
"10": "Oktober",
|
||||
"11": "November",
|
||||
"12": "December",
|
||||
}
|
||||
|
||||
func (mt MyTime) Format() string {
|
||||
t := time.Time(mt)
|
||||
return fmt.Sprintf("%v %v %v", t.Format("Jan"), t.Format("02"), t.Format("2006"))
|
||||
}
|
||||
|
||||
func (mt MyTime) Title() string {
|
||||
t := time.Time(mt)
|
||||
return fmt.Sprintf("%v %v", t.Format("Januari"), t.Format("2006"))
|
||||
}
|
||||
|
||||
type EventFlags struct {
|
||||
Soldout bool
|
||||
Tryout bool
|
||||
Premiere bool
|
||||
Preview bool
|
||||
XL bool
|
||||
Solo bool
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Date MyTime `json:"date"`
|
||||
Venue string `json:"venue"`
|
||||
City string `json:"city"`
|
||||
Link string `json:"link"`
|
||||
Time string `json:"time"`
|
||||
Title string `json:"title"`
|
||||
Flags EventFlags `json:"flags"`
|
||||
}
|
||||
|
||||
func (e *Event) SetFlags(flags string) {
|
||||
for _, flag := range strings.Split(flags, ",") {
|
||||
switch strings.Trim(strings.ToLower(flag), " \t") {
|
||||
case "uitverkocht":
|
||||
e.Flags.Soldout = true
|
||||
case "tryout":
|
||||
e.Flags.Tryout = true
|
||||
case "preview":
|
||||
e.Flags.Preview = true
|
||||
case "premiere":
|
||||
e.Flags.Premiere = true
|
||||
case "solo":
|
||||
e.Flags.Solo = true
|
||||
case "xl":
|
||||
e.Flags.XL = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getEvents() *[]Event {
|
||||
var events []Event
|
||||
|
||||
f, err := os.Open(path.Join(ROOT_DIR, "data/events.csv"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
reader := csv.NewReader(bufio.NewReader(f))
|
||||
reader.Comma = ';'
|
||||
|
||||
now := time.Now()
|
||||
|
||||
for {
|
||||
line, error := reader.Read()
|
||||
if error == io.EOF {
|
||||
break
|
||||
} else if error != nil {
|
||||
log.Fatal(error)
|
||||
}
|
||||
|
||||
if line[0] == "date" {
|
||||
continue
|
||||
}
|
||||
|
||||
if now.After(
|
||||
(time.Time(ParseDate(line[0]))).Local().Add(time.Hour * time.Duration(24)),
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
event := Event{
|
||||
Date: ParseDate(line[0]),
|
||||
Time: line[1],
|
||||
City: line[2],
|
||||
Title: line[3],
|
||||
Venue: line[4],
|
||||
Link: line[5],
|
||||
}
|
||||
|
||||
event.SetFlags(line[6])
|
||||
|
||||
events = append(events, event)
|
||||
}
|
||||
|
||||
sort.SliceStable(events, func(i, j int) bool {
|
||||
a := events[i]
|
||||
b := events[j]
|
||||
|
||||
return time.Time(a.Date).Before(time.Time(b.Date))
|
||||
})
|
||||
|
||||
return &events
|
||||
}
|
||||
17
go.mod
Normal file
17
go.mod
Normal file
@ -0,0 +1,17 @@
|
||||
module gitea.basklooosterman.nl/thomasshop
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/VictorAvelar/mollie-api-go v1.6.6 // indirect
|
||||
github.com/VictorAvelar/mollie-api-go/v3 v3.1.2 // indirect
|
||||
github.com/gin-contrib/multitemplate v0.0.0-20220323084503-710510e67c20
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gorm.io/driver/sqlite v1.3.1
|
||||
gorm.io/gorm v1.23.4
|
||||
)
|
||||
469
go.sum
Normal file
469
go.sum
Normal file
@ -0,0 +1,469 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/VictorAvelar/mollie-api-go v1.6.6 h1:VWP+k0PRt6esWO8qbCMO/ZvIRDrhBonkt0kxYEnGugk=
|
||||
github.com/VictorAvelar/mollie-api-go v1.6.6/go.mod h1:ndE8MbwgUZoq827yh0ppyYncii5jZLa0acL6j5iqZyk=
|
||||
github.com/VictorAvelar/mollie-api-go/v3 v3.1.2 h1:uDtk4yMcehQflUkugqds9HQ6bBjV7a6Wjy9DMhWV9R0=
|
||||
github.com/VictorAvelar/mollie-api-go/v3 v3.1.2/go.mod h1:/twx+AOJSjclpc9yaUHFrCxET9ad6y0nlH0HOMOT38Q=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/gin-contrib/multitemplate v0.0.0-20211002122701-e9e3201b87a0 h1:5Ot5t4hgu/lhNzwbJhxEq3gsoHUf/C7yX4P1jZcJWO0=
|
||||
github.com/gin-contrib/multitemplate v0.0.0-20211002122701-e9e3201b87a0/go.mod h1:V2h3mKlTX44jWIvsJ6KDOq808yu3dws0qosCjP9Q7nY=
|
||||
github.com/gin-contrib/multitemplate v0.0.0-20220323084503-710510e67c20 h1:R8oLt08so7CFl7DHJDfNgWSgpf6iFCbjmUdJiepbbNU=
|
||||
github.com/gin-contrib/multitemplate v0.0.0-20220323084503-710510e67c20/go.mod h1:V2h3mKlTX44jWIvsJ6KDOq808yu3dws0qosCjP9Q7nY=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
|
||||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI=
|
||||
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c h1:dk0ukUIHmGHqASjP0iue2261isepFCC6XRCSd1nHgDw=
|
||||
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c/go.mod h1:iQL9McJNjoIa5mjH6nYTCTZXUN6RP+XW3eib7Ya3XcI=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225143145-3bcbab3f74ef/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
|
||||
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
|
||||
gorm.io/driver/sqlite v1.3.1 h1:bwfE+zTEWklBYoEodIOIBwuWHpnx52Z9zJFW5F33WLk=
|
||||
gorm.io/driver/sqlite v1.3.1/go.mod h1:wJx0hJspfycZ6myN38x1O/AqLtNS6c5o9TndewFbELg=
|
||||
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM=
|
||||
gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk=
|
||||
gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg=
|
||||
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
68
gulpfile.js
Normal file
68
gulpfile.js
Normal file
@ -0,0 +1,68 @@
|
||||
const gulp = require('gulp');
|
||||
// const sass = require('gulp-sass');
|
||||
const sass = require('gulp-sass')(require('sass'));
|
||||
const webpack = require('webpack');
|
||||
const webpackStream = require('webpack-stream');
|
||||
const config = require('./webpack.config');
|
||||
|
||||
const cleanCSS = require('gulp-clean-css');
|
||||
const autoprefixer = require('gulp-autoprefixer');
|
||||
|
||||
const newer = require('gulp-newer');
|
||||
|
||||
const fontsSrc = './src/fonts'
|
||||
const fontsDest = './dist/fonts'
|
||||
|
||||
const imgSrc = './src/img'
|
||||
const imgDest = './dist/img'
|
||||
|
||||
const downloadSrc = './src/download'
|
||||
const downloadDest = './dist/download'
|
||||
|
||||
const sassTask = () => {
|
||||
return gulp.src('./src/sass/**/*.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(autoprefixer({
|
||||
browsers: ['last 2 versions', 'ie > 8'],
|
||||
cascade: false
|
||||
}))
|
||||
.pipe(cleanCSS({compatibility: 'ie8'}))
|
||||
.pipe(gulp.dest('./dist/css'));
|
||||
}
|
||||
|
||||
const jsTask =() => {
|
||||
return gulp.src('./src/js/shared.js')
|
||||
.pipe(webpackStream(config, webpack))
|
||||
.pipe(gulp.dest('./dist/js/'));
|
||||
}
|
||||
|
||||
const fontsTask = () => {
|
||||
return gulp.src(`./${fontsSrc}/**`)
|
||||
.pipe(newer(fontsDest))
|
||||
.pipe(gulp.dest(fontsDest));
|
||||
}
|
||||
|
||||
const imgTask = () => {
|
||||
return gulp.src(`./${imgSrc}/**`)
|
||||
// .pipe(newer(imgDest))
|
||||
.pipe(gulp.dest(imgDest));
|
||||
}
|
||||
|
||||
const downloadTask = () => {
|
||||
return gulp.src(`./${downloadSrc}/**`)
|
||||
// .pipe(newer(downloadDest))
|
||||
.pipe(gulp.dest(downloadDest));
|
||||
}
|
||||
|
||||
const watch = () => {
|
||||
gulp.watch('./src/sass/**/*.scss', sassTask);
|
||||
gulp.watch('./src/fonts/**', fontsTask);
|
||||
gulp.watch('./src/img/**', imgTask);
|
||||
}
|
||||
|
||||
const build = gulp.parallel(jsTask, gulp.series(sassTask, fontsTask, imgTask, downloadTask));
|
||||
module.exports = {
|
||||
default: gulp.parallel(jsTask, gulp.series(sassTask, fontsTask, imgTask, watch)),
|
||||
build
|
||||
}
|
||||
|
||||
7
init.sh
Executable file
7
init.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#! /bin/sh
|
||||
|
||||
|
||||
echo "Enter fqdn:"
|
||||
read host_name
|
||||
|
||||
sed "s#{{root_dir}}#$1#g;s#{{host_name}}#$2#g" nginx/template.conf > nginx/flip_cohen.conf
|
||||
213
main.go
Normal file
213
main.go
Normal file
@ -0,0 +1,213 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/VictorAvelar/mollie-api-go/v3/mollie"
|
||||
"github.com/gin-contrib/multitemplate"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// var SOCKNAME = "thomas.sock"
|
||||
var addr = "0.0.0.0:3000"
|
||||
|
||||
type Config struct {
|
||||
MollieToken string `yaml:"mollie_token"`
|
||||
MollieTesting bool `yaml:"mollie_testing"`
|
||||
MollieWebhook string `yaml:"mollie_webhook"`
|
||||
MollieRedirectURL string `yaml:"mollie_redirect_url"`
|
||||
MailServer string `yaml:"mail_server"`
|
||||
MailPort int `yaml:"mail_port"`
|
||||
MailUser string `yaml:"mail_user"`
|
||||
MailPass string `yaml:"mail_pass"`
|
||||
FromAddr string `yaml:"from_addr"`
|
||||
BCC string `yaml:"bcc"`
|
||||
}
|
||||
|
||||
var config Config
|
||||
|
||||
var mollieClient *mollie.Client
|
||||
|
||||
var ROOT_DIR string
|
||||
|
||||
func notFound(w http.ResponseWriter, r *http.Request) error {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
t, err := template.ParseFiles(path.Join(ROOT_DIR, "templates/404.html"))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return t.Execute(w, nil)
|
||||
}
|
||||
|
||||
func index(c *gin.Context) {
|
||||
db := getDB(c)
|
||||
|
||||
products := []Product{}
|
||||
|
||||
db.Order("id desc").Find(&products)
|
||||
|
||||
c.HTML(http.StatusOK, "index", map[string]interface{}{
|
||||
"products": products,
|
||||
})
|
||||
}
|
||||
|
||||
func handle404(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "404.html", map[string]interface{}{})
|
||||
}
|
||||
|
||||
func createSocket(s string) net.Listener {
|
||||
os.Remove(s)
|
||||
|
||||
log.Println("Creating UNIX socket:", s)
|
||||
sock, err := net.Listen("unix", s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.Chmod(s, 0777)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return sock
|
||||
}
|
||||
|
||||
func getDB(c *gin.Context) *gorm.DB {
|
||||
item, _ := c.Get("db")
|
||||
db := item.(*gorm.DB)
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
func getProd(id uint, products []Product) *Product {
|
||||
for _, prod := range products {
|
||||
if prod.ID == id {
|
||||
return &prod
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createMyRender(base string) multitemplate.Renderer {
|
||||
r := multitemplate.NewRenderer()
|
||||
|
||||
f := template.FuncMap{
|
||||
"formatMoney": func(cents int) string {
|
||||
return fmt.Sprintf("€%.2f", float64(float64(cents)/100))
|
||||
},
|
||||
"mult": func(x, y int) int {
|
||||
return x * y
|
||||
},
|
||||
"plus": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"total": func(a Product, ac int, b Product, bc int, c Product, cc int) int {
|
||||
return a.Price*ac + b.Price*bc + c.Price*cc
|
||||
},
|
||||
"nowYear": func() string {
|
||||
return time.Now().Format("2006")
|
||||
},
|
||||
"getProd": getProd,
|
||||
"countries": func() map[string]string {
|
||||
return countries
|
||||
},
|
||||
"menu": func() []MenuItem {
|
||||
return getMenuItems()
|
||||
},
|
||||
}
|
||||
|
||||
r.AddFromFilesFuncs("404.html", f, path.Join(base, "base.html"), path.Join(base, "404.html"))
|
||||
r.AddFromFilesFuncs("index", f, path.Join(base, "base.html"), path.Join(base, "index.html"))
|
||||
r.AddFromFilesFuncs("orderInfo", f, path.Join(base, "base.html"), path.Join(base, "order_info.html"))
|
||||
r.AddFromFilesFuncs("orderPending", f, path.Join(base, "base.html"), path.Join(base, "order_pending.html"))
|
||||
r.AddFromFilesFuncs("orderThankyou", f, path.Join(base, "base.html"), path.Join(base, "order_thankyou.html"))
|
||||
r.AddFromFilesFuncs("checkout", f, path.Join(base, "base.html"), path.Join(base, "order_checkout.html"))
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 1 {
|
||||
ROOT_DIR = os.Args[1]
|
||||
}
|
||||
|
||||
go func() {
|
||||
getMenuItems()
|
||||
}()
|
||||
|
||||
log.Printf("Running from with app root dir: %s\n", ROOT_DIR)
|
||||
|
||||
configPath := path.Join(ROOT_DIR, "data/config/config.yaml")
|
||||
configBytes, err := ioutil.ReadFile(configPath)
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Can't open config file at %s; %v", configPath, err))
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal([]byte(configBytes), &config); err != nil {
|
||||
panic(fmt.Sprintf("Can't parse config file at %s; %v", configPath, err))
|
||||
}
|
||||
|
||||
if mollieClient, err = initMollie(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
db := GetDB()
|
||||
|
||||
r := gin.Default()
|
||||
r.HTMLRender = createMyRender(path.Join(ROOT_DIR, "templates"))
|
||||
|
||||
r.Use(func(c *gin.Context) {
|
||||
c.Set("db", db)
|
||||
c.Next()
|
||||
})
|
||||
|
||||
r.GET("/", index)
|
||||
r.POST("/order", postGetOrderInfo)
|
||||
r.GET("/order", index)
|
||||
r.POST("/order/checkout", postCheckout)
|
||||
r.POST("/order/create-order", createOrder)
|
||||
r.POST("/order/webhook", postMollieWebhook)
|
||||
r.GET("/order/thankyou", getPreOrderThankYou)
|
||||
r.POST("/order/retry/:orderid", postOrderRetry)
|
||||
r.GET("/order/pending/:orderid", getPendingOrder)
|
||||
r.NoRoute(handle404)
|
||||
|
||||
// sockPath := path.Join(ROOT_DIR, "run", SOCKNAME)
|
||||
// sock := createSocket(sockPath)
|
||||
|
||||
server := http.Server{
|
||||
Handler: r,
|
||||
Addr: addr,
|
||||
}
|
||||
|
||||
fmt.Println("Running...")
|
||||
go func() {
|
||||
log.Fatal(server.ListenAndServe())
|
||||
}()
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
|
||||
// Block until a signal is received.
|
||||
<-c
|
||||
fmt.Println("Stopping...")
|
||||
// os.Remove(path.Join(ROOT_DIR, "run", SOCKNAME))
|
||||
}
|
||||
50
menu.go
Normal file
50
menu.go
Normal file
@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var menuURL = "http://www.thomaspol.com/wp-json/wp/v2/menu"
|
||||
|
||||
type MenuItem struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func _getMenuItems() func() []MenuItem {
|
||||
var items []MenuItem
|
||||
return func() []MenuItem {
|
||||
if items == nil {
|
||||
res, err := http.DefaultClient.Get(menuURL)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("[Err] Error getting menu: %v", err)
|
||||
return items
|
||||
}
|
||||
|
||||
dec := json.NewDecoder(res.Body)
|
||||
tmpItems := []MenuItem{}
|
||||
if err := dec.Decode(&tmpItems); err != nil {
|
||||
return items
|
||||
}
|
||||
|
||||
items_ := []MenuItem{}
|
||||
|
||||
for _, item := range tmpItems {
|
||||
if item.URL == "#" {
|
||||
continue
|
||||
}
|
||||
|
||||
items_ = append(items_, item)
|
||||
}
|
||||
|
||||
items = items_
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
var getMenuItems = _getMenuItems()
|
||||
39
mollie.go
Normal file
39
mollie.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/VictorAvelar/mollie-api-go/v3/mollie"
|
||||
)
|
||||
|
||||
func createMolliePayment(preOrder PreOrder, shippingCost int) (*mollie.Response, *mollie.Payment, error) {
|
||||
amount := preOrder.CalcTotal() + shippingCost
|
||||
return mollieClient.Payments.Create(context.Background(), mollie.Payment{
|
||||
Amount: &mollie.Amount{
|
||||
Currency: "EUR",
|
||||
Value: fmt.Sprintf("%.2f", float64(amount)/float64(100)),
|
||||
},
|
||||
Description: fmt.Sprintf("Thomas Pol Shop"),
|
||||
Metadata: map[string]interface{}{
|
||||
"preorderID": preOrder.ID,
|
||||
},
|
||||
RedirectURL: fmt.Sprintf("%s/%v", config.MollieRedirectURL, preOrder.ID),
|
||||
WebhookURL: config.MollieWebhook,
|
||||
}, nil)
|
||||
}
|
||||
|
||||
func initMollie() (*mollie.Client, error) {
|
||||
os.Setenv("MOLLIE_API_TOKEN", config.MollieToken)
|
||||
apiTokenClient, err := mollie.NewClient(nil, mollie.NewConfig(
|
||||
false,
|
||||
mollie.APITokenEnv,
|
||||
))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return apiTokenClient, nil
|
||||
}
|
||||
37
nginx/alex-go.conf
Normal file
37
nginx/alex-go.conf
Normal file
@ -0,0 +1,37 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ;
|
||||
client_max_body_size 20M;
|
||||
|
||||
#charset koi8-r;
|
||||
|
||||
|
||||
# access_log /usr/local/var/log/nginx/.access.log;
|
||||
# error_log /usr/local/var/log/nginx/.error.log;
|
||||
|
||||
|
||||
location /static {
|
||||
alias /var/www/alex-go/dist;
|
||||
gzip_static on;
|
||||
expires max;
|
||||
add_header Cache-Control public;
|
||||
}
|
||||
|
||||
location /favicon {
|
||||
return 404 "Not Found";
|
||||
}
|
||||
|
||||
location /robots.txt {
|
||||
return 404 "Not Found";
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://unix://var/www/alex-go/run/flip.sock;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 5m;
|
||||
}
|
||||
}
|
||||
37
nginx/template.conf
Normal file
37
nginx/template.conf
Normal file
@ -0,0 +1,37 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{host_name}};
|
||||
client_max_body_size 20M;
|
||||
|
||||
#charset koi8-r;
|
||||
|
||||
|
||||
# access_log /usr/local/var/log/nginx/{{host_name}}.access.log;
|
||||
# error_log /usr/local/var/log/nginx/{{host_name}}.error.log;
|
||||
|
||||
|
||||
location /static {
|
||||
alias {{root_dir}}/dist;
|
||||
gzip_static on;
|
||||
expires max;
|
||||
add_header Cache-Control public;
|
||||
}
|
||||
|
||||
location /favicon {
|
||||
return 404 "Not Found";
|
||||
}
|
||||
|
||||
location /robots.txt {
|
||||
return 404 "Not Found";
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://unix:/{{root_dir}}/run/flip.sock;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 5m;
|
||||
}
|
||||
}
|
||||
667
order.go
Normal file
667
order.go
Normal file
@ -0,0 +1,667 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gopkg.in/gomail.v2"
|
||||
)
|
||||
|
||||
const SHIPPING = 675
|
||||
const SHIPPING_INT = 930
|
||||
|
||||
var countries = map[string]string{
|
||||
"AF": "Afghanistan",
|
||||
"AX": "Åland Islands",
|
||||
"AL": "Albania",
|
||||
"DZ": "Algeria",
|
||||
"AS": "American Samoa",
|
||||
"AD": "AndorrA",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarctica",
|
||||
"AG": "Antigua and Barbuda",
|
||||
"AR": "Argentina",
|
||||
"AM": "Armenia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Australia",
|
||||
"AT": "Austria",
|
||||
"AZ": "Azerbaijan",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BY": "Belarus",
|
||||
"BE": "Belgium",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnia and Herzegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet Island",
|
||||
"BR": "Brazil",
|
||||
"IO": "British Indian Ocean Territory",
|
||||
"BN": "Brunei Darussalam",
|
||||
"BG": "Bulgaria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KH": "Cambodia",
|
||||
"CM": "Cameroon",
|
||||
"CA": "Canada",
|
||||
"CV": "Cape Verde",
|
||||
"KY": "Cayman Islands",
|
||||
"CF": "Central African Republic",
|
||||
"TD": "Chad",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CX": "Christmas Island",
|
||||
"CC": "Cocos (Keeling) Islands",
|
||||
"CO": "Colombia",
|
||||
"KM": "Comoros",
|
||||
"CG": "Congo",
|
||||
"CD": "Congo, The Democratic Republic of the",
|
||||
"CK": "Cook Islands",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "Cote D'Ivoire",
|
||||
"HR": "Croatia",
|
||||
"CU": "Cuba",
|
||||
"CY": "Cyprus",
|
||||
"CZ": "Czech Republic",
|
||||
"DK": "Denmark",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominican Republic",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egypt",
|
||||
"SV": "El Salvador",
|
||||
"GQ": "Equatorial Guinea",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estonia",
|
||||
"ET": "Ethiopia",
|
||||
"FK": "Falkland Islands (Malvinas",
|
||||
"FO": "Faroe Islands",
|
||||
"FJ": "Fiji",
|
||||
"FI": "Finland",
|
||||
"FR": "France",
|
||||
"GF": "French Guiana",
|
||||
"PF": "French Polynesia",
|
||||
"TF": "French Southern Territories",
|
||||
"GA": "Gabon",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgia",
|
||||
"DE": "Germany",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GR": "Greece",
|
||||
"GL": "Greenland",
|
||||
"GD": "Grenada",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard Island and Mcdonald Islands",
|
||||
"VA": "Holy See (Vatican City State",
|
||||
"HN": "Honduras",
|
||||
"HK": "Hong Kong",
|
||||
"HU": "Hungary",
|
||||
"IS": "Iceland",
|
||||
"IN": "India",
|
||||
"ID": "Indonesia",
|
||||
"IR": "Iran, Islamic Republic Of",
|
||||
"IQ": "Iraq",
|
||||
"IE": "Ireland",
|
||||
"IM": "Isle of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italy",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Japan",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordan",
|
||||
"KZ": "Kazakhstan",
|
||||
"KE": "Kenya",
|
||||
"KI": "Kiribati",
|
||||
"KP": "Korea, Democratic People'S Republic of",
|
||||
"KR": "Korea, Republic of",
|
||||
"KW": "Kuwait",
|
||||
"KG": "Kyrgyzstan",
|
||||
"LA": "Lao People'S Democratic Republic",
|
||||
"LV": "Latvia",
|
||||
"LB": "Lebanon",
|
||||
"LS": "Lesotho",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libyan Arab Jamahiriya",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Lithuania",
|
||||
"LU": "Luxembourg",
|
||||
"MO": "Macao",
|
||||
"MK": "Macedonia, The Former Yugoslav Republic of",
|
||||
"MG": "Madagascar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Maldives",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MH": "Marshall Islands",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauritania",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexico",
|
||||
"FM": "Micronesia, Federated States of",
|
||||
"MD": "Moldova, Republic of",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolia",
|
||||
"MS": "Montserrat",
|
||||
"MA": "Morocco",
|
||||
"MZ": "Mozambique",
|
||||
"MM": "Myanmar",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NL": "Netherlands",
|
||||
"AN": "Netherlands Antilles",
|
||||
"NC": "New Caledonia",
|
||||
"NZ": "New Zealand",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"NF": "Norfolk Island",
|
||||
"MP": "Northern Mariana Islands",
|
||||
"NO": "Norway",
|
||||
"OM": "Oman",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PS": "Palestinian Territory, Occupied",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua New Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PH": "Philippines",
|
||||
"PN": "Pitcairn",
|
||||
"PL": "Poland",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"QA": "Qatar",
|
||||
"RE": "Reunion",
|
||||
"RO": "Romania",
|
||||
"RU": "Russian Federation",
|
||||
"RW": "RWANDA",
|
||||
"SH": "Saint Helena",
|
||||
"KN": "Saint Kitts and Nevis",
|
||||
"LC": "Saint Lucia",
|
||||
"PM": "Saint Pierre and Miquelon",
|
||||
"VC": "Saint Vincent and the Grenadines",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "Sao Tome and Principe",
|
||||
"SA": "Saudi Arabia",
|
||||
"SN": "Senegal",
|
||||
"CS": "Serbia and Montenegro",
|
||||
"SC": "Seychelles",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapore",
|
||||
"SK": "Slovakia",
|
||||
"SI": "Slovenia",
|
||||
"SB": "Solomon Islands",
|
||||
"SO": "Somalia",
|
||||
"ZA": "South Africa",
|
||||
"GS": "South Georgia and the South Sandwich Islands",
|
||||
"ES": "Spain",
|
||||
"LK": "Sri Lanka",
|
||||
"SD": "Sudan",
|
||||
"SR": "Suriname",
|
||||
"SJ": "Svalbard and Jan Mayen",
|
||||
"SZ": "Swaziland",
|
||||
"SE": "Sweden",
|
||||
"CH": "Switzerland",
|
||||
"SY": "Syrian Arab Republic",
|
||||
"TW": "Taiwan, Province of China",
|
||||
"TJ": "Tajikistan",
|
||||
"TZ": "Tanzania, United Republic of",
|
||||
"TH": "Thailand",
|
||||
"TL": "Timor-Leste",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad and Tobago",
|
||||
"TN": "Tunisia",
|
||||
"TR": "Turkey",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks and Caicos Islands",
|
||||
"TV": "Tuvalu",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"AE": "United Arab Emirates",
|
||||
"GB": "United Kingdom",
|
||||
"US": "United States",
|
||||
"UM": "United States Minor Outlying Islands",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Uzbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VE": "Venezuela",
|
||||
"VN": "Viet Nam",
|
||||
"VG": "Virgin Islands, British",
|
||||
"VI": "Virgin Islands, U.S",
|
||||
"WF": "Wallis and Futuna",
|
||||
"EH": "Western Sahara",
|
||||
"YE": "Yemen",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabwe",
|
||||
}
|
||||
|
||||
type orderPayload struct {
|
||||
Products []int `form:"product"`
|
||||
Name string `form:"name"`
|
||||
Streetname string `form:"streetname"`
|
||||
Postcode string `form:"postcode"`
|
||||
EmailAddress string `form:"email_address"`
|
||||
City string `form:"city"`
|
||||
}
|
||||
|
||||
func sendMail(preOrder PreOrder, config Config) {
|
||||
tpl, err := template.ParseFiles(path.Join(ROOT_DIR, "templates/preorder.email"))
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := gomail.NewMessage()
|
||||
|
||||
var w bytes.Buffer
|
||||
data := map[string]interface{}{
|
||||
"preOrder": preOrder,
|
||||
}
|
||||
|
||||
tpl.Execute(&w, data)
|
||||
|
||||
m.SetHeader("From", config.FromAddr)
|
||||
m.SetHeader("To", preOrder.Email)
|
||||
m.SetAddressHeader("Bcc", config.BCC, "admin")
|
||||
m.SetHeader("Subject", "Your Thomas Pol Shop order")
|
||||
m.SetBody("text/html", w.String())
|
||||
|
||||
d := gomail.NewDialer(config.MailServer, config.MailPort, config.MailUser, config.MailPass)
|
||||
|
||||
// Send the email to Bob, Cora and Dan.
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sendAdminMail(preOrder, config)
|
||||
}
|
||||
|
||||
func sendAdminMail(preOrder PreOrder, config Config) {
|
||||
tpl, err := template.New("tpl").Funcs(template.FuncMap{
|
||||
"countries": func() map[string]string {
|
||||
return countries
|
||||
},
|
||||
}).ParseFiles(path.Join(ROOT_DIR, "templates/preorder_admin.email"))
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
m := gomail.NewMessage()
|
||||
|
||||
var w bytes.Buffer
|
||||
data := map[string]interface{}{
|
||||
"preOrder": preOrder,
|
||||
}
|
||||
|
||||
tpl.Execute(&w, data)
|
||||
|
||||
m.SetHeader("From", config.FromAddr)
|
||||
m.SetHeader("To", config.BCC)
|
||||
m.SetAddressHeader("Bcc", config.BCC, "admin")
|
||||
m.SetHeader("Subject", "Thomas Pol order")
|
||||
m.SetBody("text/html", w.String())
|
||||
|
||||
d := gomail.NewDialer(config.MailServer, config.MailPort, config.MailUser, config.MailPass)
|
||||
|
||||
// Send the email to Bob, Cora and Dan.
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
var prodRegexp = regexp.MustCompile(`products\[(\d+)\]`)
|
||||
|
||||
func parseProducts(c *gin.Context) map[uint]int {
|
||||
prods := map[uint]int{}
|
||||
|
||||
c.Request.ParseForm()
|
||||
for k, v := range c.Request.Form {
|
||||
if m := prodRegexp.FindAllStringSubmatch(k, 1); len(m) > 0 {
|
||||
|
||||
id, _ := strconv.ParseInt(m[0][1], 10, 64)
|
||||
n, _ := strconv.ParseInt(v[0], 10, 64)
|
||||
prods[uint(id)] = int(n)
|
||||
}
|
||||
}
|
||||
|
||||
return prods
|
||||
}
|
||||
|
||||
type Shipping struct {
|
||||
Name string
|
||||
Email string
|
||||
Address string
|
||||
Postcode string
|
||||
City string
|
||||
Country string
|
||||
}
|
||||
|
||||
func (s Shipping) Valid() bool {
|
||||
if s.Name == "" {
|
||||
return false
|
||||
}
|
||||
if s.Email == "" {
|
||||
return false
|
||||
}
|
||||
if s.Address == "" {
|
||||
return false
|
||||
}
|
||||
if s.Postcode == "" {
|
||||
return false
|
||||
}
|
||||
if s.City == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if s.Country == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func parseShipping(c *gin.Context) Shipping {
|
||||
shipping := Shipping{}
|
||||
|
||||
c.Request.ParseForm()
|
||||
for k, v := range c.Request.Form {
|
||||
switch k {
|
||||
case "name":
|
||||
shipping.Name = v[0]
|
||||
case "email":
|
||||
shipping.Email = v[0]
|
||||
case "address":
|
||||
shipping.Address = v[0]
|
||||
case "postcode":
|
||||
shipping.Postcode = v[0]
|
||||
case "city":
|
||||
shipping.City = v[0]
|
||||
case "country":
|
||||
shipping.Country = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
if shipping.Country == "" {
|
||||
shipping.Country = "NL"
|
||||
}
|
||||
|
||||
return shipping
|
||||
}
|
||||
|
||||
func postGetOrderInfo(c *gin.Context) {
|
||||
db := getDB(c)
|
||||
products := []Product{}
|
||||
db.Find(&products)
|
||||
c.Request.ParseForm()
|
||||
prods := parseProducts(c)
|
||||
shipping := parseShipping(c)
|
||||
total := 0
|
||||
|
||||
for p, q := range prods {
|
||||
cur := getProd(p, products)
|
||||
|
||||
if cur == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
total += q * cur.Price
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "checkout", map[string]interface{}{
|
||||
"error": "",
|
||||
"total": total,
|
||||
"products": products,
|
||||
"shipping": shipping,
|
||||
"order": prods,
|
||||
})
|
||||
}
|
||||
|
||||
func postCheckout(c *gin.Context) {
|
||||
db := getDB(c)
|
||||
products := []Product{}
|
||||
db.Find(&products)
|
||||
c.Request.ParseForm()
|
||||
prods := parseProducts(c)
|
||||
|
||||
total := 0
|
||||
|
||||
for p, q := range prods {
|
||||
cur := getProd(p, products)
|
||||
|
||||
if cur == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
total += q * cur.Price
|
||||
}
|
||||
|
||||
shipping := parseShipping(c)
|
||||
|
||||
if !shipping.Valid() {
|
||||
c.HTML(http.StatusOK, "checkout", map[string]interface{}{
|
||||
"error": "All fields are required",
|
||||
"total": total,
|
||||
"products": products,
|
||||
"shipping": shipping,
|
||||
"order": prods,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
shippingCost := SHIPPING
|
||||
shippingLabel := "Shipping NL"
|
||||
|
||||
if shipping.Country != "NL" {
|
||||
shippingCost = SHIPPING_INT
|
||||
shippingLabel = "Shipping international"
|
||||
}
|
||||
|
||||
total += shippingCost
|
||||
|
||||
c.HTML(http.StatusOK, "orderInfo", map[string]interface{}{
|
||||
"total": total,
|
||||
"products": products,
|
||||
"shipping": shipping,
|
||||
"shippingCost": shippingCost,
|
||||
"shippingLabel": shippingLabel,
|
||||
"order": prods,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func createOrder(c *gin.Context) {
|
||||
db := getDB(c)
|
||||
products := []Product{}
|
||||
db.Find(&products)
|
||||
c.Request.ParseForm()
|
||||
prods := parseProducts(c)
|
||||
|
||||
shipping := parseShipping(c)
|
||||
|
||||
preOrder := PreOrder{
|
||||
Name: shipping.Name,
|
||||
Email: shipping.Email,
|
||||
Address: shipping.Address,
|
||||
Postcode: shipping.Postcode,
|
||||
City: shipping.City,
|
||||
Country: shipping.Country,
|
||||
Status: PRE_ORDER_STATE_CREATED,
|
||||
}
|
||||
|
||||
db.Create(&preOrder)
|
||||
|
||||
for p, q := range prods {
|
||||
for i := 0; i < q; i++ {
|
||||
db.Create(&Item{
|
||||
ProductID: p,
|
||||
PreOrderID: preOrder.ID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
shippingCost := SHIPPING
|
||||
if shipping.Country != "NL" {
|
||||
shippingCost = SHIPPING_INT
|
||||
}
|
||||
|
||||
db.Preload("Items").Preload("Items.Product").Where("id = ?", preOrder.ID).Find(&preOrder)
|
||||
|
||||
_, payment, err := createMolliePayment(preOrder, shippingCost)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Something went wrong creating payment: %v", err)
|
||||
c.AbortWithError(500, fmt.Errorf("I'am sorry, something went wrong...:("))
|
||||
return
|
||||
}
|
||||
|
||||
molliePayment := MolliePayment{
|
||||
MolliePaymentID: payment.ID,
|
||||
Amount: preOrder.CalcTotal() + shippingCost,
|
||||
Status: payment.Status,
|
||||
PreOrderID: preOrder.ID,
|
||||
}
|
||||
|
||||
db.Create(&molliePayment)
|
||||
|
||||
c.Redirect(http.StatusFound, payment.Links.Checkout.Href)
|
||||
}
|
||||
|
||||
func postMollieWebhook(c *gin.Context) {
|
||||
db := getDB(c)
|
||||
|
||||
paymentID := c.Request.FormValue("id")
|
||||
|
||||
_, payment, err := mollieClient.Payments.Get(context.Background(), paymentID, nil)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error get payment from mollie; %v; %s", err, paymentID)
|
||||
c.AbortWithError(500, fmt.Errorf("Deze bestelling is onbekend"))
|
||||
return
|
||||
}
|
||||
|
||||
molliePayment := &MolliePayment{}
|
||||
|
||||
if err := db.Preload("PreOrder").Where("mollie_payment_id = ?", paymentID).Find(&molliePayment).Error; err != nil {
|
||||
log.Printf("Error get payment from db; %v; %s", err, paymentID)
|
||||
c.AbortWithError(500, fmt.Errorf("Unknown order"))
|
||||
return
|
||||
}
|
||||
|
||||
if payment.Status != molliePayment.Status {
|
||||
molliePayment.Status = payment.Status
|
||||
db.Save(&molliePayment)
|
||||
|
||||
preOrder := PreOrder{}
|
||||
|
||||
db.Preload("Items").Preload("Items.Product").Where("id = ?", molliePayment.PreOrderID).Find(&preOrder)
|
||||
|
||||
if molliePayment.Status == "paid" {
|
||||
sendMail(preOrder, config)
|
||||
}
|
||||
}
|
||||
|
||||
c.Status(200)
|
||||
}
|
||||
|
||||
func postOrderRetry(c *gin.Context) {
|
||||
orderID := c.Param("orderid")
|
||||
|
||||
db := getDB(c)
|
||||
|
||||
preOrder := &PreOrder{}
|
||||
|
||||
if err := db.Preload("Items").Preload("Items.Product").Where("id = ?", orderID).Find(&preOrder).Error; err != nil {
|
||||
c.AbortWithError(500, fmt.Errorf("This order is unknown"))
|
||||
return
|
||||
}
|
||||
|
||||
if preOrder.ID.String() == nullUUID.String() {
|
||||
c.AbortWithError(500, fmt.Errorf("Unknown Order"))
|
||||
return
|
||||
}
|
||||
|
||||
db.Find(&preOrder)
|
||||
|
||||
shippingCost := SHIPPING
|
||||
if preOrder.Country != "NL" {
|
||||
shippingCost = SHIPPING_INT
|
||||
}
|
||||
|
||||
_, payment, err := createMolliePayment(*preOrder, shippingCost)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithError(500, fmt.Errorf("Sorry, something went wrong...:("))
|
||||
return
|
||||
}
|
||||
|
||||
molliePayment := MolliePayment{
|
||||
MolliePaymentID: payment.ID,
|
||||
Amount: preOrder.CalcTotal() + SHIPPING,
|
||||
Status: payment.Status,
|
||||
PreOrderID: preOrder.ID,
|
||||
}
|
||||
|
||||
db.Create(&molliePayment)
|
||||
|
||||
c.Redirect(http.StatusFound, payment.Links.Checkout.Href)
|
||||
}
|
||||
|
||||
func getPendingOrder(c *gin.Context) {
|
||||
orderID := c.Param("orderid")
|
||||
|
||||
db := getDB(c)
|
||||
|
||||
payments := []*MolliePayment{}
|
||||
|
||||
if err := db.Where("pre_order_id = ?", orderID).Order("created_at desc").Find(&payments).Error; err != nil {
|
||||
c.AbortWithError(500, fmt.Errorf("Unknown Order"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(payments) == 0 {
|
||||
c.AbortWithError(500, fmt.Errorf("Unknown Order"))
|
||||
return
|
||||
}
|
||||
|
||||
payment := payments[0]
|
||||
|
||||
if payment.Status == "paid" {
|
||||
c.Redirect(http.StatusFound, "/order/thankyou")
|
||||
return
|
||||
}
|
||||
|
||||
c.HTML(http.StatusOK, "orderPending", map[string]interface{}{"payment": payment, "orderID": orderID})
|
||||
}
|
||||
|
||||
func getPreOrderThankYou(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "orderThankyou", nil)
|
||||
}
|
||||
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "cohen_site",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-autoprefixer": "^6.1.0",
|
||||
"gulp-clean-css": "^4.2.0",
|
||||
"gulp-newer": "^1.4.0",
|
||||
"gulp-sass": "^5.1.0",
|
||||
"webpack": "^4.1.1",
|
||||
"webpack-stream": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"sass": "^1.50.1",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0"
|
||||
}
|
||||
}
|
||||
30
preorder_test.go
Normal file
30
preorder_test.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func TestSendMail(t *testing.T) {
|
||||
db := GetDB()
|
||||
config := Config{}
|
||||
configPath := path.Join(ROOT_DIR, "data/config/config.yaml")
|
||||
configBytes, err := ioutil.ReadFile(configPath)
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Can't open config file at %s; %v", configPath, err))
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal([]byte(configBytes), &config); err != nil {
|
||||
panic(fmt.Sprintf("Can't parse config file at %s; %v", configPath, err))
|
||||
}
|
||||
|
||||
preOrder := PreOrder{}
|
||||
|
||||
db.Preload("Items").Preload("Items.Product").Where("id = ?", "66297049-6019-45a3-bb98-959d4c2476d9").Find(&preOrder)
|
||||
sendMail(preOrder, config)
|
||||
}
|
||||
3
seed.sql
Normal file
3
seed.sql
Normal file
@ -0,0 +1,3 @@
|
||||
INSERT INTO "products" VALUES(1,'2021-12-11 09:53:59.584728+01:00','2021-12-11 09:53:59.584728+01:00',NULL,'In America (CD)','/static/img/tpia_front.png','In America (CD)', 1000);
|
||||
INSERT INTO "products" VALUES(2,'2021-12-11 09:53:59.584728+01:00','2021-12-11 09:53:59.584728+01:00',NULL,'In America (CD) + Blue Soil (LP)','/static/img/combi.png','In America (CD) + Blue Soil (LP)', 3000);
|
||||
INSERT INTO "products" VALUES(3,'2021-12-11 09:53:59.584728+01:00','2021-12-11 09:53:59.584728+01:00',NULL,'Blue Soil (LP)','/static/img/blue_soil.jpg','Blue Soil (LP)', 2500);
|
||||
BIN
src/fonts/socicon.woff
Normal file
BIN
src/fonts/socicon.woff
Normal file
Binary file not shown.
BIN
src/img/blue_soil.jpg
Normal file
BIN
src/img/blue_soil.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
src/img/caret.png
Normal file
BIN
src/img/caret.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
BIN
src/img/combi.jpg
Normal file
BIN
src/img/combi.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
BIN
src/img/favicon.ico
Normal file
BIN
src/img/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 393 B |
BIN
src/img/favicon.jpg
Normal file
BIN
src/img/favicon.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
BIN
src/img/tpia_front.png
Normal file
BIN
src/img/tpia_front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
21
src/js/shared.js
Normal file
21
src/js/shared.js
Normal file
@ -0,0 +1,21 @@
|
||||
!function () {
|
||||
var t = document.querySelector('.js-mobile-trigger')
|
||||
var menu = document.querySelector('.js-menu')
|
||||
var close = document.querySelector('.js-close')
|
||||
function foo() {
|
||||
menu.classList.remove('active')
|
||||
window.removeEventListener('click', foo)
|
||||
}
|
||||
t.addEventListener('click', function (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
menu.classList.add('active')
|
||||
window.addEventListener('click', foo)
|
||||
})
|
||||
|
||||
close.addEventListener('click', function (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
foo()
|
||||
})
|
||||
}()
|
||||
3
src/sass/_color.scss
Normal file
3
src/sass/_color.scss
Normal file
@ -0,0 +1,3 @@
|
||||
$black: #111;
|
||||
$primary:#00f596;
|
||||
$grey: #BFB7B0;
|
||||
7
src/sass/_hamburger.scss
Normal file
7
src/sass/_hamburger.scss
Normal file
File diff suppressed because one or more lines are too long
663
src/sass/_menu.scss
Normal file
663
src/sass/_menu.scss
Normal file
@ -0,0 +1,663 @@
|
||||
@font-face {
|
||||
font-family: socicon;
|
||||
src: url(../fonts/socicon.woff) format("woff");
|
||||
font-weight: 400;
|
||||
font-style: normal
|
||||
}
|
||||
|
||||
[data-icon]:before {
|
||||
content: attr(data-icon)
|
||||
}
|
||||
|
||||
.socicon-modelmayhem:before {
|
||||
content: "\e000"
|
||||
}
|
||||
|
||||
.socicon-mixcloud:before {
|
||||
content: "\e001"
|
||||
}
|
||||
|
||||
.socicon-drupal:before {
|
||||
content: "\e002"
|
||||
}
|
||||
|
||||
.socicon-swarm:before {
|
||||
content: "\e003"
|
||||
}
|
||||
|
||||
.socicon-istock:before {
|
||||
content: "\e004"
|
||||
}
|
||||
|
||||
.socicon-yammer:before {
|
||||
content: "\e005"
|
||||
}
|
||||
|
||||
.socicon-ello:before {
|
||||
content: "\e006"
|
||||
}
|
||||
|
||||
.socicon-stackoverflow:before {
|
||||
content: "\e007"
|
||||
}
|
||||
|
||||
.socicon-persona:before {
|
||||
content: "\e008"
|
||||
}
|
||||
|
||||
.socicon-triplej:before {
|
||||
content: "\e009"
|
||||
}
|
||||
|
||||
.socicon-houzz:before {
|
||||
content: "\e00a"
|
||||
}
|
||||
|
||||
.socicon-rss:before {
|
||||
content: "\e00b"
|
||||
}
|
||||
|
||||
.socicon-paypal:before {
|
||||
content: "\e00c"
|
||||
}
|
||||
|
||||
.socicon-odnoklassniki:before {
|
||||
content: "\e00d"
|
||||
}
|
||||
|
||||
.socicon-airbnb:before {
|
||||
content: "\e00e"
|
||||
}
|
||||
|
||||
.socicon-periscope:before {
|
||||
content: "\e00f"
|
||||
}
|
||||
|
||||
.socicon-outlook:before {
|
||||
content: "\e010"
|
||||
}
|
||||
|
||||
.socicon-coderwall:before {
|
||||
content: "\e011"
|
||||
}
|
||||
|
||||
.socicon-tripadvisor:before {
|
||||
content: "\e012"
|
||||
}
|
||||
|
||||
.socicon-appnet:before {
|
||||
content: "\e013"
|
||||
}
|
||||
|
||||
.socicon-goodreads:before {
|
||||
content: "\e014"
|
||||
}
|
||||
|
||||
.socicon-tripit:before {
|
||||
content: "\e015"
|
||||
}
|
||||
|
||||
.socicon-lanyrd:before {
|
||||
content: "\e016"
|
||||
}
|
||||
|
||||
.socicon-slideshare:before {
|
||||
content: "\e017"
|
||||
}
|
||||
|
||||
.socicon-buffer:before {
|
||||
content: "\e018"
|
||||
}
|
||||
|
||||
.socicon-disqus:before {
|
||||
content: "\e019"
|
||||
}
|
||||
|
||||
.socicon-vkontakte:before {
|
||||
content: "\e01a"
|
||||
}
|
||||
|
||||
.socicon-whatsapp:before {
|
||||
content: "\e01b"
|
||||
}
|
||||
|
||||
.socicon-patreon:before {
|
||||
content: "\e01c"
|
||||
}
|
||||
|
||||
.socicon-storehouse:before {
|
||||
content: "\e01d"
|
||||
}
|
||||
|
||||
.socicon-pocket:before {
|
||||
content: "\e01e"
|
||||
}
|
||||
|
||||
.socicon-mail:before {
|
||||
content: "\e01f"
|
||||
}
|
||||
|
||||
.socicon-blogger:before {
|
||||
content: "\e020"
|
||||
}
|
||||
|
||||
.socicon-technorati:before {
|
||||
content: "\e021"
|
||||
}
|
||||
|
||||
.socicon-reddit:before {
|
||||
content: "\e022"
|
||||
}
|
||||
|
||||
.socicon-dribbble:before {
|
||||
content: "\e023"
|
||||
}
|
||||
|
||||
.socicon-stumbleupon:before {
|
||||
content: "\e024"
|
||||
}
|
||||
|
||||
.socicon-digg:before {
|
||||
content: "\e025"
|
||||
}
|
||||
|
||||
.socicon-envato:before {
|
||||
content: "\e026"
|
||||
}
|
||||
|
||||
.socicon-behance:before {
|
||||
content: "\e027"
|
||||
}
|
||||
|
||||
.socicon-delicious:before {
|
||||
content: "\e028"
|
||||
}
|
||||
|
||||
.socicon-deviantart:before {
|
||||
content: "\e029"
|
||||
}
|
||||
|
||||
.socicon-forrst:before {
|
||||
content: "\e02a"
|
||||
}
|
||||
|
||||
.socicon-play:before {
|
||||
content: "\e02b"
|
||||
}
|
||||
|
||||
.socicon-zerply:before {
|
||||
content: "\e02c"
|
||||
}
|
||||
|
||||
.socicon-wikipedia:before {
|
||||
content: "\e02d"
|
||||
}
|
||||
|
||||
.socicon-apple:before {
|
||||
content: "\e02e"
|
||||
}
|
||||
|
||||
.socicon-flattr:before {
|
||||
content: "\e02f"
|
||||
}
|
||||
|
||||
.socicon-github:before {
|
||||
content: "\e030"
|
||||
}
|
||||
|
||||
.socicon-renren:before {
|
||||
content: "\e031"
|
||||
}
|
||||
|
||||
.socicon-friendfeed:before {
|
||||
content: "\e032"
|
||||
}
|
||||
|
||||
.socicon-newsvine:before {
|
||||
content: "\e033"
|
||||
}
|
||||
|
||||
.socicon-identica:before {
|
||||
content: "\e034"
|
||||
}
|
||||
|
||||
.socicon-bebo:before {
|
||||
content: "\e035"
|
||||
}
|
||||
|
||||
.socicon-zynga:before {
|
||||
content: "\e036"
|
||||
}
|
||||
|
||||
.socicon-steam:before {
|
||||
content: "\e037"
|
||||
}
|
||||
|
||||
.socicon-xbox:before {
|
||||
content: "\e038"
|
||||
}
|
||||
|
||||
.socicon-windows:before {
|
||||
content: "\e039"
|
||||
}
|
||||
|
||||
.socicon-qq:before {
|
||||
content: "\e03a"
|
||||
}
|
||||
|
||||
.socicon-douban:before {
|
||||
content: "\e03b"
|
||||
}
|
||||
|
||||
.socicon-meetup:before {
|
||||
content: "\e03c"
|
||||
}
|
||||
|
||||
.socicon-playstation:before {
|
||||
content: "\e03d"
|
||||
}
|
||||
|
||||
.socicon-android:before {
|
||||
content: "\e03e"
|
||||
}
|
||||
|
||||
.socicon-snapchat:before {
|
||||
content: "\e03f"
|
||||
}
|
||||
|
||||
.socicon-twitter:before {
|
||||
content: "\e040"
|
||||
}
|
||||
|
||||
.socicon-facebook:before {
|
||||
content: "\e041"
|
||||
}
|
||||
|
||||
.socicon-googleplus:before {
|
||||
content: "\e042"
|
||||
}
|
||||
|
||||
.socicon-pinterest:before {
|
||||
content: "\e043"
|
||||
}
|
||||
|
||||
.socicon-foursquare:before {
|
||||
content: "\e044"
|
||||
}
|
||||
|
||||
.socicon-yahoo:before {
|
||||
content: "\e045"
|
||||
}
|
||||
|
||||
.socicon-skype:before {
|
||||
content: "\e046"
|
||||
}
|
||||
|
||||
.socicon-yelp:before {
|
||||
content: "\e047"
|
||||
}
|
||||
|
||||
.socicon-feedburner:before {
|
||||
content: "\e048"
|
||||
}
|
||||
|
||||
.socicon-linkedin:before {
|
||||
content: "\e049"
|
||||
}
|
||||
|
||||
.socicon-viadeo:before {
|
||||
content: "\e04a"
|
||||
}
|
||||
|
||||
.socicon-xing:before {
|
||||
content: "\e04b"
|
||||
}
|
||||
|
||||
.socicon-myspace:before {
|
||||
content: "\e04c"
|
||||
}
|
||||
|
||||
.socicon-soundcloud:before {
|
||||
content: "\e04d"
|
||||
}
|
||||
|
||||
.socicon-spotify:before {
|
||||
content: "\e04e"
|
||||
}
|
||||
|
||||
.socicon-grooveshark:before {
|
||||
content: "\e04f"
|
||||
}
|
||||
|
||||
.socicon-lastfm:before {
|
||||
content: "\e050"
|
||||
}
|
||||
|
||||
.socicon-youtube:before {
|
||||
content: "\e051"
|
||||
}
|
||||
|
||||
.socicon-vimeo:before {
|
||||
content: "\e052"
|
||||
}
|
||||
|
||||
.socicon-dailymotion:before {
|
||||
content: "\e053"
|
||||
}
|
||||
|
||||
.socicon-vine:before {
|
||||
content: "\e054"
|
||||
}
|
||||
|
||||
.socicon-flickr:before {
|
||||
content: "\e055"
|
||||
}
|
||||
|
||||
.socicon-500px:before {
|
||||
content: "\e056"
|
||||
}
|
||||
|
||||
.socicon-instagram:before {
|
||||
content: "\e057"
|
||||
}
|
||||
|
||||
.socicon-wordpress:before {
|
||||
content: "\e058"
|
||||
}
|
||||
|
||||
.socicon-tumblr:before {
|
||||
content: "\e059"
|
||||
}
|
||||
|
||||
.socicon-twitch:before {
|
||||
content: "\e05a"
|
||||
}
|
||||
|
||||
.socicon-8tracks:before {
|
||||
content: "\e05b"
|
||||
}
|
||||
|
||||
.socicon-amazon:before {
|
||||
content: "\e05c"
|
||||
}
|
||||
|
||||
.socicon-icq:before {
|
||||
content: "\e05d"
|
||||
}
|
||||
|
||||
.socicon-smugmug:before {
|
||||
content: "\e05e"
|
||||
}
|
||||
|
||||
.socicon-ravelry:before {
|
||||
content: "\e05f"
|
||||
}
|
||||
|
||||
.socicon-weibo:before {
|
||||
content: "\e060"
|
||||
}
|
||||
|
||||
.socicon-baidu:before {
|
||||
content: "\e061"
|
||||
}
|
||||
|
||||
.socicon-angellist:before {
|
||||
content: "\e062"
|
||||
}
|
||||
|
||||
.socicon-ebay:before {
|
||||
content: "\e063"
|
||||
}
|
||||
|
||||
.socicon-imdb:before {
|
||||
content: "\e064"
|
||||
}
|
||||
|
||||
.socicon-stayfriends:before {
|
||||
content: "\e065"
|
||||
}
|
||||
|
||||
.socicon-residentadvisor:before {
|
||||
content: "\e066"
|
||||
}
|
||||
|
||||
.socicon-google:before {
|
||||
content: "\e067"
|
||||
}
|
||||
|
||||
.socicon-yandex:before {
|
||||
content: "\e068"
|
||||
}
|
||||
|
||||
.socicon-sharethis:before {
|
||||
content: "\e069"
|
||||
}
|
||||
|
||||
.socicon-bandcamp:before {
|
||||
content: "\e06a"
|
||||
}
|
||||
|
||||
.socicon-itunes:before {
|
||||
content: "\e06b"
|
||||
}
|
||||
|
||||
.socicon-deezer:before {
|
||||
content: "\e06c"
|
||||
}
|
||||
|
||||
[class*=" socicon-"]:before,
|
||||
[class^=socicon-]:before,
|
||||
[data-icon]:before {
|
||||
font-family: socicon !important;
|
||||
font-style: normal !important;
|
||||
font-weight: 400 !important;
|
||||
font-variant: normal !important;
|
||||
text-transform: none !important;
|
||||
speak: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale
|
||||
}
|
||||
|
||||
.c-main-nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(1, 1, 1, .95);
|
||||
color: #fdfdfd;
|
||||
width: 100%;
|
||||
z-index: 9999;
|
||||
-moz-box-shadow: 2px 2px 9px transparent;
|
||||
-webkit-box-shadow: 2px 2px 9px transparent;
|
||||
box-shadow: 2px 2px 9px transparent;
|
||||
-moz-transform: translate(0, -100%);
|
||||
-ms-transform: translate(0, -100%);
|
||||
-webkit-transform: translate(0, -100%);
|
||||
transform: translate(0, -100%);
|
||||
-moz-transition: -moz-transform 1s;
|
||||
-o-transition: -o-transform 1s;
|
||||
-webkit-transition: -webkit-transform 1s;
|
||||
transition: all 1s ease-out;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.c-main-nav.active {
|
||||
-moz-transform: translate(0, 0);
|
||||
-ms-transform: translate(0, 0);
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
-moz-box-shadow: 2px 2px 9px rgba(0, 0, 0, .4);
|
||||
-webkit-box-shadow: 2px 2px 9px rgba(0, 0, 0, .4);
|
||||
box-shadow: 2px 2px 9px rgba(0, 0, 0, .4);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.c-main-nav__list {
|
||||
list-style-type: none;
|
||||
font-size: 1.5rem;
|
||||
padding: 0;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.c-main-nav__item {
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.c-main-nav__link {
|
||||
color: #fdfdfd;
|
||||
display: block;
|
||||
padding: 12px 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.c-main-nav__link:hover {
|
||||
background-color: #00f596;
|
||||
color: #111
|
||||
}
|
||||
|
||||
.c-main-nav__item:last-of-type .c-main-nav__link {
|
||||
color: #00f596
|
||||
}
|
||||
|
||||
.c-main-nav__item:last-of-type .c-main-nav__link:hover {
|
||||
background-color: transparent;
|
||||
color: #00f596
|
||||
}
|
||||
|
||||
@media (max-height:575px) {
|
||||
.c-main-nav__list {
|
||||
font-size: 1.5rem
|
||||
}
|
||||
|
||||
.c-main-nav__link {
|
||||
padding: 9px 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.c-mobile-trigger {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
padding: 5px 10px;
|
||||
z-index: 1000;
|
||||
box-shadow: 2px 2px 10px rgba(0,0,0,0.2);
|
||||
background-color: rgba(0,0,0,1);
|
||||
display: block;
|
||||
|
||||
&__link {
|
||||
color: white!important;
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.page-header {
|
||||
position: fixed;
|
||||
background-color: #111;
|
||||
padding: 10px 30px;
|
||||
width: 100%;
|
||||
color: #fdfdfd;
|
||||
z-index: 9998
|
||||
}
|
||||
|
||||
.page-header .subtitle {
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 1px;
|
||||
margin-left: 7px;
|
||||
color: #00f596
|
||||
}
|
||||
|
||||
@media (max-width:650px) {
|
||||
.page-header .subtitle {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
|
||||
.page-header a,
|
||||
.page-header a:active,
|
||||
.page-header a:visited {
|
||||
color: #fdfdfd;
|
||||
text-decoration: none;
|
||||
|
||||
}
|
||||
|
||||
.page-header a.home-link,
|
||||
.page-header a:active.home-link,
|
||||
.page-header a:visited.home-link {
|
||||
font-family: mohave;
|
||||
font-size: 2rem;
|
||||
letter-spacing: 3px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.page-header .open-menu-wrapper {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%)
|
||||
}
|
||||
|
||||
.page-header .open-menu {
|
||||
font-size: 1.3rem;
|
||||
line-height: 0;
|
||||
height: 1.5rem;
|
||||
padding: 2px 3px
|
||||
}
|
||||
|
||||
.page-header ul.social-container {
|
||||
float: right;
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
font-size: 1.2rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 115px;
|
||||
top: 51%;
|
||||
-moz-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
-webkit-transform: translateY(-50%);
|
||||
transform: translateY(-50%)
|
||||
}
|
||||
|
||||
.page-header ul.social-container li {
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.page-header ul.social-container a {
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.page-header ul.social-container a span {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.bg-hr,
|
||||
.bg-stretch {
|
||||
position: absolute;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.page-header ul.social-container a .socicon-facebook {
|
||||
font-size: .95rem;
|
||||
top: -2px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
@media (max-width:740px) {
|
||||
.page-header ul.social-container {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
4
src/sass/_mixins.scss
Normal file
4
src/sass/_mixins.scss
Normal file
@ -0,0 +1,4 @@
|
||||
@mixin font-size($sizeValue) {
|
||||
font-size: $sizeValue + px;
|
||||
font-size: ($sizeValue / 16) + rem;
|
||||
}
|
||||
289
src/sass/_order.scss
Normal file
289
src/sass/_order.scss
Normal file
@ -0,0 +1,289 @@
|
||||
.c-products {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-column-gap: 25px;
|
||||
grid-row-gap: 25px;
|
||||
|
||||
@media (max-width: 900px) {
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.c-product {
|
||||
|
||||
&__name {
|
||||
font-weight: 500;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
&__order {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
&__input {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #111;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
font-family: 'Roboto';
|
||||
width: 50px;
|
||||
margin-left: 5px;
|
||||
&:focus {
|
||||
border-color: $primary;
|
||||
}
|
||||
}
|
||||
|
||||
&__img {
|
||||
max-width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&__price {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.c-order-info {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.c-form-row {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
|
||||
.c-error {
|
||||
@extend .t-p1;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
background-color: red;
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
.c-label {
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.c-input {
|
||||
$this: &;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.2);
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 20px;
|
||||
width: 100%;
|
||||
font-weight: 200;
|
||||
|
||||
&:focus {
|
||||
border-bottom: 1px solid rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
transition: border-color 200ms ease-out;
|
||||
|
||||
&:read-only {
|
||||
margin-left: -2px;
|
||||
border-bottom: 0;
|
||||
&:focus {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-select {
|
||||
position: relative;
|
||||
&__select {
|
||||
$this: &;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid rgba(0,0,0,0.2);
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 20px;
|
||||
width: 100%;
|
||||
font-weight: 200;
|
||||
padding: 10px;
|
||||
// border-bottom: 1px solid rgba(0,0,0,0.8);
|
||||
appearance: none;
|
||||
transition: border-color 200ms ease-out;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
top: 15px;
|
||||
right: 12px;
|
||||
background-image: url(/static/img/caret.png);
|
||||
background-size: cover;
|
||||
}
|
||||
// &:read-only {
|
||||
// margin-left: -2px;
|
||||
// border-bottom: 0;
|
||||
// &:focus {
|
||||
// border-bottom: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
.o-input-select-margin input {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.c-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
grid-column-gap: 50px;
|
||||
|
||||
@media (max-width: 900px) {
|
||||
div:last-of-type {
|
||||
margin-top: 25px;
|
||||
}
|
||||
grid-template-columns: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.c-col {
|
||||
// width: 50%;
|
||||
}
|
||||
|
||||
.c-product-container {
|
||||
display: flex;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.c-button-container {
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.c-button {
|
||||
$this: &;
|
||||
padding: 15px 45px;
|
||||
background-color: black;
|
||||
color: white!important;
|
||||
text-decoration: none;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
transition: all 300ms ease-out;
|
||||
|
||||
&:hover {
|
||||
background-color: $primary;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// .c-product {
|
||||
// $this: &;
|
||||
// padding: 25px 0;
|
||||
// margin-right: 50px;
|
||||
|
||||
// &:last-of-type {
|
||||
// margin-right: 0;
|
||||
// }
|
||||
// &__img {
|
||||
// display: block;
|
||||
// width: 250px;
|
||||
// margin: 15px 0;
|
||||
// }
|
||||
|
||||
// &__x {
|
||||
// height: 31px;
|
||||
// display: inline-block;
|
||||
// }
|
||||
|
||||
// &__title {
|
||||
// display: inline-block;
|
||||
// text-transform: uppercase;
|
||||
// font-weight: 400;
|
||||
// }
|
||||
// &__price {
|
||||
// display: block;
|
||||
// }
|
||||
|
||||
// &__input {
|
||||
// padding: 5px;
|
||||
// border: 1px solid rgba(0,0,0,0.2)!important;
|
||||
// width: 43px;
|
||||
|
||||
// &:focus {
|
||||
// border: 1px solid rgba(0,0,0,0.8)!important;
|
||||
// }
|
||||
|
||||
// transition: border-color 200ms ease-out;
|
||||
// }
|
||||
|
||||
// &__order-info {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// span {
|
||||
// margin-right: 10px;
|
||||
// };
|
||||
// }
|
||||
|
||||
// @media (max-width: 700px) {
|
||||
// width: 100%;
|
||||
// margin-right: 0;
|
||||
|
||||
// #{$this}__img {
|
||||
// width: 100%;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.c-price-order {
|
||||
|
||||
}
|
||||
|
||||
.c-price-table {
|
||||
width: 100%;
|
||||
td {
|
||||
padding: 0px 0;
|
||||
}
|
||||
|
||||
&__right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&__top {
|
||||
td {
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&__underline {
|
||||
border-bottom: 1px solid black;
|
||||
td {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/sass/_reset.scss
Normal file
52
src/sass/_reset.scss
Normal file
@ -0,0 +1,52 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
html * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
35
src/sass/_typography.scss
Normal file
35
src/sass/_typography.scss
Normal file
@ -0,0 +1,35 @@
|
||||
.t-h1 {
|
||||
font-family: mohave;
|
||||
display: block;
|
||||
font-size: 5rem;
|
||||
margin: 0 0 15px 0;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
p, .t-p1 {
|
||||
display: block;
|
||||
margin-block-start: 1rem;
|
||||
margin-block-end: 1rem;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
}
|
||||
|
||||
.t-h2 {
|
||||
font-family: mohave;
|
||||
display: block;
|
||||
font-size: 1.6rem;
|
||||
margin: 0 0 15px 0;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.t-h3 {
|
||||
display: block;
|
||||
font-size: 1.1rem;
|
||||
margin-block-start: 0.67rem;
|
||||
margin-block-end: 0.67rem;
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
99
src/sass/index.scss
Normal file
99
src/sass/index.scss
Normal file
@ -0,0 +1,99 @@
|
||||
@import "reset";
|
||||
@import "mixins";
|
||||
@import "color";
|
||||
@import "typography";
|
||||
@import "order";
|
||||
@import "menu";
|
||||
|
||||
body {
|
||||
/* text-transform: uppercase; */
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 20px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
font-weight: 100;
|
||||
color: $black;
|
||||
}
|
||||
|
||||
main {
|
||||
min-height: calc(100vh - 58px);
|
||||
padding-top: 75px;
|
||||
}
|
||||
|
||||
// table {
|
||||
// height: 100vh;
|
||||
// width: 100%;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
.c-link, .c-link:hover, .c-link:visited {
|
||||
color: black;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.main {
|
||||
background-image: url('/static/img/alex.jpg');
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.c-section {
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.c-section {
|
||||
padding: 25px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.c-section__content {
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
ul {list-style: none; padding: 0;}
|
||||
li {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
|
||||
.c-auto-ratio__inner {
|
||||
padding-top: 56.25%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.c-auto-ratio__inner iframe {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.c-footer {
|
||||
background-color: black;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.c-footer ul {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.c-footer__item {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
display: inline-block;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.c-footer__item a {
|
||||
color: white!important;
|
||||
text-decoration: none;
|
||||
}
|
||||
11
templates/404.html
Normal file
11
templates/404.html
Normal file
@ -0,0 +1,11 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-page-section">
|
||||
<div class="c-page-section__content" style="text-align: center;">
|
||||
<h1 class="t-h1" style="font-size: 200px; font-weight: bold; margin-top: 100px;">404</h1>
|
||||
<p class="t-p1">The page you trying to find is no longer there.</p>
|
||||
<p class="t-p1"><a href="/" class="t-p1 t-p1--invert">Back to shop</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
73
templates/base.html
Normal file
73
templates/base.html
Normal file
File diff suppressed because one or more lines are too long
32
templates/index.html
Normal file
32
templates/index.html
Normal file
@ -0,0 +1,32 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-section">
|
||||
<div class="c-section__content">
|
||||
<h1 class="t-h1">
|
||||
Shop
|
||||
</h1>
|
||||
<p class="t-p1">
|
||||
Welcome to the T.Pol shop! My solo album 'Blue Soil' is fresh out on vinyl and it sounds great. My debut album 'In America' is on sale and discounted when you order the Vinyl! Enjoy my music and thank you very much.
|
||||
</p>
|
||||
<form method="POST" action="/order">
|
||||
<div class="c-products">
|
||||
{{range .products}}
|
||||
<div class="c-product">
|
||||
<h1 class="c-product__name">{{.Name}}</h1>
|
||||
<img class="c-product__img" src="{{.Image}}"/>
|
||||
<div class="c-product__order">
|
||||
<span class="c-product__price">{{formatMoney .Price}}</span>
|
||||
<span>×</span>
|
||||
<input name="products[{{.ID}}]"class="c-product__input" type="number" value="0">
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="c-button-container">
|
||||
<button class="c-button">Place order</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
76
templates/order_checkout.html
Normal file
76
templates/order_checkout.html
Normal file
@ -0,0 +1,76 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-section" style="margin-top: 25px;">
|
||||
<div class="c-section__content">
|
||||
<form action="/order/checkout" method="POST">
|
||||
{{range $k, $v := .order}}
|
||||
<input name="products[{{$k}}]" type="hidden" value="{{$v}}">
|
||||
{{end}}
|
||||
<h2 class="t-h2">Order summary</h2>
|
||||
|
||||
<div class="c-order-info">
|
||||
<div class="c-form-row">
|
||||
<table class="c-price-table">
|
||||
{{range $k, $v := .order}}
|
||||
{{if gt $v 0}}
|
||||
{{$prod := getProd $k $.products}}
|
||||
<tr>
|
||||
<td style="font-weight: 400;">{{$prod.Name}} × {{$v}}</td>
|
||||
<td class="c-price-table__right">{{formatMoney (mult $prod.Price $v)}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{if ne .error ""}}
|
||||
<div class="c-error">
|
||||
{{.error}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div style="margin-top: 50px">
|
||||
<h2 class="t-h2">Shipping info</h2>
|
||||
<div class="c-grid c-form-row">
|
||||
<div>
|
||||
<label for="name" class="c-label">Name</label>
|
||||
<input name="name" id="name" class="c-input" type="text" value="{{.shipping.Name}}"/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="c-label">Email address</label>
|
||||
<input name="email" id="email" class="c-input" type="text" value="{{.shipping.Email}}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-grid c-form-row">
|
||||
<div>
|
||||
<label for="address" class="c-label">Streetname + number</label>
|
||||
<input name="address" id="address" class="c-input" type="text" value="{{.shipping.Address}}"/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="postcode" class="c-label">Postcode</label>
|
||||
<input name="postcode" id="postcode" class="c-input" type="text" value="{{.shipping.Postcode}}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-grid c-form-row">
|
||||
<div class="o-input-select-margin">
|
||||
<label for="city" class="c-label">City</label>
|
||||
<input name="city" id="city" class="c-input" value="{{.shipping.City}}"/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="country" class="c-label">Country</label>
|
||||
<div class="c-select">
|
||||
<select class="c-select__select" name="country" value="{{.shipping.Country}}" id="country">
|
||||
{{range $key, $description := countries}}
|
||||
<option value="{{$key}}"{{if eq $.shipping.Country $key}}selected{{end}}>{{$description}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="c-button c-button">Next</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
52
templates/order_index.html
Normal file
52
templates/order_index.html
Normal file
@ -0,0 +1,52 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-section" style="margin-top: 25px;">
|
||||
<div class="c-section__content">
|
||||
<h1>Store</h1>
|
||||
{{if ne .error ""}}
|
||||
<p class="c-error">{{.error}}</p>
|
||||
{{end}}
|
||||
<form action="/order/checkout" method="POST">
|
||||
<p>At the moment we only ship within the Netherlands. If you live outside the Netherlands and would like to receive the album please send an email to <a class="c-link" href="mailto:info@alexandervanpopta.com">info@alexandervanpopta.nl</a>.</p>
|
||||
<ul class="c-product-container">
|
||||
{{range .products}}
|
||||
<li class="c-product">
|
||||
<span class="c-product__title">{{.Name}}</span>
|
||||
<img class="c-product__img" src="{{.Image}}" alt="">
|
||||
<div class="c-product__order-info">
|
||||
<span class="c-product__price">{{formatMoney .Price}}</span> <span class="c-product__x">×</span>
|
||||
<input class="c-input c-product__input" name="product[{{.ID}}]" type="number" value="{{if eq .ID 1}}{{$.order.MTMLP}}{{else if eq .ID 2}}{{$.order.MTMCD}}{{else}}{{$.order.AllTheMemCD}}{{end}}">
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
<h2 class="t-h2">Order info</h2>
|
||||
<div class="c-order-info">
|
||||
<div class="c-form-row">
|
||||
<label for="name" class="c-label">Name</label>
|
||||
<input name="name" id="name" class="c-input" type="text" value="{{.order.Name}}"/>
|
||||
</div>
|
||||
<div class="c-form-row">
|
||||
<label for="email_address" class="c-label">Email address</label>
|
||||
<input name="email_address" id="email_address" class="c-input" type="text" value="{{.order.EmailAddress}}"/>
|
||||
</div>
|
||||
<div class="c-form-row">
|
||||
<label for="streetname" class="c-label">Streetname + number</label>
|
||||
<input name="streetname" id="streetname" class="c-input" type="text" value="{{.order.Streetname}}"/>
|
||||
</div>
|
||||
<div class="c-form-row">
|
||||
<label for="postcode" class="c-label">Postcode</label>
|
||||
<input name="postcode" id="postcode" class="c-input" type="text" value="{{.order.Postcode}}"/>
|
||||
</div>
|
||||
<div class="c-form-row">
|
||||
<label for="city" class="c-label">City</label>
|
||||
<input name="city" id="city" class="c-input" value="{{.order.City}}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="c-button">Order</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
58
templates/order_info.html
Normal file
58
templates/order_info.html
Normal file
@ -0,0 +1,58 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-section" style="margin-top: 25px;">
|
||||
<div class="c-section__content">
|
||||
<form action="/order/create-order" method="POST">
|
||||
{{range $k, $v := .order}}
|
||||
<input name="products[{{$k}}]" type="hidden" value="{{$v}}">
|
||||
{{end}}
|
||||
<h2 class="t-h2">Order summary</h2>
|
||||
<div class="c-order-info">
|
||||
<div class="c-form-row">
|
||||
<table class="c-price-table">
|
||||
{{range $k, $v := .order}}
|
||||
{{if gt $v 0}}
|
||||
{{$prod := getProd $k $.products}}
|
||||
<tr>
|
||||
<td style="font-weight: 400;">{{$prod.Name}} × {{$v}}</td>
|
||||
<td class="c-price-table__right">{{formatMoney (mult $prod.Price $v)}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<tr class="c-price-table__underline">
|
||||
<td style="font-weight: 400;">{{.shippingLabel}}</td>
|
||||
<td class="c-price-table__right">{{formatMoney .shippingCost}}</td>
|
||||
</tr>
|
||||
<tr class="c-price-table__top">
|
||||
<td style="font-weight: 400;">Total</td>
|
||||
<td class="c-price-table__right">{{formatMoney .total}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 50px">
|
||||
<h2 class="t-h2">Shipping info</h2>
|
||||
<label for="" class="c-label">Name/Email</label>
|
||||
<div class="c-form-row">
|
||||
<input type="hidden" name="name" id="name" readonly class="c-input" value="{{.shipping.Name}}"/>
|
||||
<input type="hidden" name="email" readonly class="c-input" value="{{.shipping.Email}}"/>
|
||||
|
||||
<input readonly class="c-input" value="{{.shipping.Name}}"/>
|
||||
<input readonly class="c-input" value="{{.shipping.Email}}"/>
|
||||
</div>
|
||||
<label for="" class="c-label">Address</label>
|
||||
<div class="c-form-row">
|
||||
<input type="hidden" name="address" readonly class="c-input" value="{{.shipping.Address}}"/>
|
||||
<input type="hidden" name="postcode" readonly class="c-input" value="{{.shipping.Postcode}}"/>
|
||||
<input type="hidden" name="city" readonly class="c-input" value="{{.shipping.City}}"/>
|
||||
<input type="hidden" name="country" readonly class="c-input" value="{{.shipping.Country}}"/>
|
||||
|
||||
<input readonly class="c-input" value="{{.shipping.Address}}"/>
|
||||
<input readonly class="c-input" value="{{.shipping.Postcode}} {{.shipping.City}}, {{index countries .shipping.Country}}"/>
|
||||
</div>
|
||||
<button class="c-button c-button">Pay</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
36
templates/order_pending.html
Normal file
36
templates/order_pending.html
Normal file
@ -0,0 +1,36 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-section" style="margin-top: 25px;">
|
||||
<div class="c-section__content">
|
||||
{{if eq .payment.Status "open"}}
|
||||
<p class="t-p1">Processing payment <span class="js-loading" style="display: inline-block; width: 15px; text-align: left"></span></p>
|
||||
{{else}}
|
||||
<form action="/order/retry/{{.orderID}}" method="POST">
|
||||
<p class="t-p1">Your payment failed</p>
|
||||
<button style="margin-top: 50px"class="c-button">try again</button>
|
||||
</form>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
{{if eq .payment.Status "open"}}
|
||||
var loading = document.querySelector('.js-loading')
|
||||
|
||||
setInterval((function () {
|
||||
var times = 0
|
||||
return function () {
|
||||
times++
|
||||
var dots = ''
|
||||
for (i = 0; i < times % 4; i++) {
|
||||
dots += '.'
|
||||
}
|
||||
|
||||
loading.textContent = dots
|
||||
}
|
||||
})(), 200)
|
||||
setTimeout(function () {window.location.reload()}, 2000)
|
||||
{{end}}
|
||||
</script>
|
||||
{{end}}
|
||||
16
templates/order_thankyou.html
Normal file
16
templates/order_thankyou.html
Normal file
@ -0,0 +1,16 @@
|
||||
{{define "body"}}
|
||||
<main>
|
||||
<div class="c-section" style="margin-top: 25px;">
|
||||
<div class="c-section__content">
|
||||
<p class="t-p1">
|
||||
Thank you for ordering my music and I hope you enjoy it!
|
||||
</p>
|
||||
<p class="t-p1">
|
||||
Yours truly,<br>
|
||||
Thomas Pol
|
||||
</p>
|
||||
<p style="margin-top: 50px"><a href="/" style="margin-top: 10px" class="c-button">HOME</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
8
templates/preorder.email
Normal file
8
templates/preorder.email
Normal file
@ -0,0 +1,8 @@
|
||||
<p>Dear {{.preOrder.Name}},</p>
|
||||
<p> </p>
|
||||
<p>Thank you for your order! I will ship your order as soon as possible.</p>
|
||||
<p> </p>
|
||||
<p>For questions regarding your order you can contact me at <a href="mailto:info@thomaspol.com">info@thomaspol.com</a></p>
|
||||
<p> </p>
|
||||
<p>Yours truly,</p>
|
||||
<p>Thomas Pol</p>
|
||||
31
templates/preorder_admin.email
Normal file
31
templates/preorder_admin.email
Normal file
@ -0,0 +1,31 @@
|
||||
{{define "tpl"}}
|
||||
<table>
|
||||
<tr>
|
||||
<th style="text-align: left; padding: 5px;">Naam</th>
|
||||
<th style="text-align: left; padding: 5px;">Email</th>
|
||||
<th style="text-align: left; padding: 5px;">Straatnaam + nr</th>
|
||||
<th style="text-align: left; padding: 5px;">Postcode</th>
|
||||
<th style="text-align: left; padding: 5px;">Stad</th>
|
||||
<th style="text-align: left; padding: 5px;">Land</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px;">{{.preOrder.Name}}</td>
|
||||
<td style="padding: 5px;">{{.preOrder.Email}}</td>
|
||||
<td style="padding: 5px;">{{.preOrder.Address}}</td>
|
||||
<td style="padding: 5px;">{{.preOrder.Postcode}}</td>
|
||||
<td style="padding: 5px;">{{.preOrder.City}}</td>
|
||||
<td style="padding: 5px;">{{index countries .preOrder.Country}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th style="text-align: left; padding: 5px;">Producten</th>
|
||||
</tr>
|
||||
{{range .preOrder.Items}}
|
||||
<tr>
|
||||
<td style="padding: 5px;">{{.Product.Name}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
{{end}}
|
||||
48
templates/song.html
Normal file
48
templates/song.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="/static/css/index.css?v4">
|
||||
<link rel="icon" type="image/png" href="/static/img/favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="nav">
|
||||
<div class="nav__section nav__left">
|
||||
<a href="/albums#{{.album.Path}}">Terug</a>
|
||||
</div>
|
||||
<div class="nav__section nav__right">
|
||||
<a href="/">Zingt Leonard Cohen</a>
|
||||
<a href="/love-it">Love It!</a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="c-page-section">
|
||||
<div class="c-page-section__content">
|
||||
<a class="t-h2" style="text-decoration: none; font-size: 26px; margin-bottom: 25px;" href="/albums#{{.album.Path}}">terug</a>
|
||||
<div></div>
|
||||
<h1 class="t-h1" style="margin-bottom: 15px;">
|
||||
{{.album.Name}} ({{.album.Release}})
|
||||
</h1>
|
||||
<div></div>
|
||||
<h1 class="t-h2">
|
||||
{{.song.Title}}
|
||||
</h1>
|
||||
<div style="margin-bottom: 35px;"></div>
|
||||
{{range .song.Lyrics}}
|
||||
<pre class="t-p1" style="margin-bottom: 25px; font-size: 24px;">
|
||||
{{- . -}}
|
||||
</pre>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<footer class="c-footer">
|
||||
<span>© {{.nowYear}} Flip Noorman </span>
|
||||
<span>info@flipnoorman.nl</span>
|
||||
</footer>
|
||||
<script src="/static/js/shared.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
50
webpack.config.js
Normal file
50
webpack.config.js
Normal file
@ -0,0 +1,50 @@
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
|
||||
|
||||
const srcPath = path.join(__dirname, 'src');
|
||||
const srcJsPath = path.join(srcPath, 'js');
|
||||
|
||||
const destPath = path.join(__dirname, 'dist');
|
||||
const destJsPath = path.join(destPath, 'js');
|
||||
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
|
||||
const env = process.env.NODE_ENV || 'production';
|
||||
|
||||
const config = {
|
||||
watch: env !== 'production',
|
||||
entry: {
|
||||
"shared": srcJsPath + '/shared',
|
||||
},
|
||||
output: {
|
||||
path: destJsPath,
|
||||
filename: '[name].js'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['es2015']
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
stats: {
|
||||
colors: true
|
||||
},
|
||||
plugins: []
|
||||
}
|
||||
|
||||
if (env === 'production') {
|
||||
config.plugins.push(
|
||||
new UglifyJsPlugin()
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
Loading…
Reference in New Issue
Block a user