]> git.feebdaed.xyz Git - lgtm-rsvp.git/commitdiff
save button and list left
authorseantywork <seantywork@gmail.com>
Wed, 8 Jan 2025 13:47:15 +0000 (13:47 +0000)
committerseantywork <seantywork@gmail.com>
Wed, 8 Jan 2025 13:47:15 +0000 (13:47 +0000)
16 files changed:
config.yaml
go.mod
go.sum
main.go
main_test_.go
pkg/auth/auth.go
pkg/auth/auth_session.go
pkg/auth/auth_verify.go
pkg/db/db.go
pkg/glob/glob.go
pkg/server/api/api_auth.go
pkg/server/server.go
public/js/common.js [new file with mode: 0644]
public/js/story/read.js
public/js/story/write.js
view/signin.html

index 2651025f9bb1eb4154779f15d2939d4d8e705c63..94b8665ca4afee07d7f5005fe78a7549bee3ff8d 100644 (file)
@@ -1,5 +1,6 @@
-test: 0
+test: -1
 serveAddr: "0.0.0.0:8080"
+sessionStore: "our-wedding-rsvp"
 db: 
   addr: "data/rsvp.db"
   initFile: "init.sql"
diff --git a/go.mod b/go.mod
index 41e97081c61cbd23560b4c31301fa2bf39759922..29cb5e30ed8c17fd4d816be6d354116e646d5a10 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -18,6 +18,7 @@ require (
        github.com/cloudwego/base64x v0.1.4 // indirect
        github.com/cloudwego/iasm v0.2.0 // indirect
        github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+       github.com/gin-contrib/sessions v1.0.2 // indirect
        github.com/gin-contrib/sse v0.1.0 // indirect
        github.com/go-playground/locales v0.14.1 // indirect
        github.com/go-playground/universal-translator v0.18.1 // indirect
@@ -37,9 +38,9 @@ require (
        github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
        github.com/ugorji/go/codec v1.2.12 // indirect
        golang.org/x/arch v0.8.0 // indirect
-       golang.org/x/crypto v0.23.0 // indirect
-       golang.org/x/net v0.25.0 // indirect
-       golang.org/x/sys v0.20.0 // indirect
-       golang.org/x/text v0.15.0 // indirect
+       golang.org/x/crypto v0.31.0 // indirect
+       golang.org/x/net v0.33.0 // indirect
+       golang.org/x/sys v0.28.0 // indirect
+       golang.org/x/text v0.21.0 // indirect
        google.golang.org/protobuf v1.34.1 // indirect
 )
diff --git a/go.sum b/go.sum
index 4e790e82a9cab13d3d4acb4787033f01d2c51209..3366799a0010f32b7a35b1a405d2f35e3f5194f3 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -15,6 +15,8 @@ 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/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
 github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA=
+github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs=
 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/contrib v0.0.0-20240508051311-c1c6bf0061b0 h1:EUFmvQ8ffefnSAmaUZd9HZYZSw9w/bFjp3FiNaJ5WmE=
@@ -89,16 +91,24 @@ golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
 golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
 golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
 golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
 golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
+golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
 golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
 golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
 golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
 golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
 google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
diff --git a/main.go b/main.go
index 5f512fe4a5bab72dd2dbd6d3976e0cd2df43f912..5f66c8f05b05f39c0113a7faed5379ab6f2d9122 100644 (file)
--- a/main.go
+++ b/main.go
@@ -3,8 +3,8 @@ package main
 import (
        "log"
        "os"
+       pkgdb "our-wedding-rsvp/pkg/db"
        pkgglob "our-wedding-rsvp/pkg/glob"
-
        pkgserver "our-wedding-rsvp/pkg/server"
 )
 
@@ -50,6 +50,25 @@ func main() {
 
        }
 
+       err = pkgdb.OpenDB(pkgglob.G_CONF.Db.Addr)
+
+       if err != nil {
+
+               log.Printf("failed to open db: %s\n", err.Error())
+
+               os.Exit(-1)
+
+       }
+
+       err = pkgdb.Init(pkgglob.G_CONF.Db.InitFile, pkgglob.G_CONF.Admin.Id, pkgglob.G_CONF.Admin.Pw)
+
+       if err != nil {
+
+               log.Printf("failed to open db: %s\n", err.Error())
+
+               os.Exit(-1)
+       }
+
        if err := srv.Run(pkgglob.G_CONF.ServeAddr); err != nil {
 
                log.Printf("failed to run: %v\n", err)
index 2a264ff2de94dd3a57c5c1f961987eef1a0d3d00..1ccdd9f1580782b4284f8e751f1e6d2ff62f32c0 100644 (file)
@@ -36,7 +36,7 @@ func test_db() error {
                return err
        }
 
-       err = pkgdb.Init(pkgglob.G_CONF.Db.InitFile)
+       err = pkgdb.Init(pkgglob.G_CONF.Db.InitFile, pkgglob.G_CONF.Admin.Id, pkgglob.G_CONF.Admin.Pw)
 
        if err != nil {
                return err
index b1e88abb0917aa56572244cbbabdad31950373dd..63d06ff23e6ab678d6a394b2557b63398076b901 100644 (file)
@@ -2,9 +2,12 @@ package auth
 
 import (
        "fmt"
+       "log"
 
        pkgdb "our-wedding-rsvp/pkg/db"
 
+       pkgglob "our-wedding-rsvp/pkg/glob"
+
        "github.com/gin-gonic/contrib/sessions"
        "github.com/gin-gonic/gin"
 
@@ -23,8 +26,12 @@ func GenerateStateAuthCookie(c *gin.Context) string {
 
        session := sessions.Default(c)
 
-       session.Set("RSVP", state)
-       session.Save()
+       session.Set(pkgglob.G_CONF.SessionStore, state)
+       err := session.Save()
+
+       if err != nil {
+               log.Printf("cookie gen failed: %s\n", err.Error())
+       }
 
        return state
 }
index 31dea8b384f2f0cf9aad69fc1de409b546e98584..45fc11904f066df96e0f5f655f366834ceb3a72e 100644 (file)
@@ -3,6 +3,7 @@ package auth
 import (
        "log"
        pkgdb "our-wedding-rsvp/pkg/db"
+       pkgglob "our-wedding-rsvp/pkg/glob"
 
        "github.com/gin-gonic/contrib/sessions"
        "github.com/gin-gonic/gin"
@@ -14,7 +15,7 @@ func Is0(c *gin.Context, userId *string, sessionId *string) bool {
 
        var session_id string
 
-       v := session.Get("RSVP")
+       v := session.Get(pkgglob.G_CONF.SessionStore)
 
        if v == nil {
                return false
index 8ffac8dc32e61a14f54d056760905036b20c7c91..50cb350f709ece2d9475eaee75598ebc9f89caf2 100644 (file)
@@ -19,6 +19,11 @@ func VerifyDefaultValue(raw string) bool {
 
                } else if c == '-' {
 
+                       continue
+               } else if c == '@' {
+                       continue
+               } else if c == '.' {
+                       continue
                } else {
 
                        return false
index 7afabcb84c39ecad3dc1d4d141119f86b782ef77..c19e31813c9d1d99af6290088187893b95efffa2 100644 (file)
@@ -66,10 +66,12 @@ func OpenDB(addr string) error {
        return nil
 }
 
-func Init(initfile string) error {
+func Init(initfile string, adminId string, adminPw string) error {
 
        tables := make([]SqliteMaster, 0)
 
+       admins := make([]Admin, 0)
+
        q := `
        
        SELECT 
@@ -123,6 +125,60 @@ func Init(initfile string) error {
 
        }
 
+       q = `
+       
+       SELECT
+               admin_id
+       FROM
+               admin
+       WHERE
+               id = ?
+
+       `
+       a = []any{
+               adminId,
+       }
+
+       res, err = query(q, a)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to get tables: %v", err)
+       }
+
+       for res.Next() {
+
+               a := Admin{}
+
+               err = res.Scan(&a.AdminId)
+
+               if err != nil {
+
+                       return fmt.Errorf("failed to read admin record: %v", err)
+
+               }
+
+               admins = append(admins, a)
+
+       }
+
+       alen := len(admins)
+
+       if alen == 0 {
+
+               log.Printf("no admins found\n")
+
+               err = addAdmin(adminId, adminPw)
+
+               if err != nil {
+
+                       return fmt.Errorf("add admin: %v", err)
+               }
+
+               log.Printf("admin successfully added\n")
+
+       }
+
        initiated = true
 
        return nil
@@ -196,3 +252,80 @@ func createFromInitSql(initfile string) error {
 
        return nil
 }
+
+func addAdmin(id string, pw string) error {
+
+       admins := make([]Admin, 0)
+
+       q := `
+       
+       INSERT INTO admin (
+               id,
+               session_id,
+               pw
+       )
+       VALUES (
+               ?,
+               NULL,
+               ?
+       )
+
+       `
+
+       a := []any{
+               id,
+               pw,
+       }
+
+       err := exec(q, a)
+
+       if err != nil {
+               return fmt.Errorf("failed to add admin: %v", err)
+       }
+
+       q = `
+       
+       SELECT
+               admin_id
+       FROM
+               admin
+       WHERE
+               id = ?
+
+       `
+       a = []any{
+               id,
+       }
+
+       res, err := query(q, a)
+
+       if err != nil {
+
+               return fmt.Errorf("failed to add admins: %v", err)
+       }
+
+       for res.Next() {
+
+               a := Admin{}
+
+               err = res.Scan(&a.AdminId)
+
+               if err != nil {
+
+                       return fmt.Errorf("failed to read admin record: %v", err)
+
+               }
+
+               admins = append(admins, a)
+
+       }
+
+       alen := len(admins)
+
+       if alen == 0 {
+
+               return fmt.Errorf("failed to add admin: 0")
+       }
+
+       return nil
+}
index 302dac7059c5a2a765968d30016e1cd3db0ce7de..dba9eb89b4ed9d9dfd03e33de271cc07b7fc7d6e 100644 (file)
@@ -1,9 +1,10 @@
 package glob
 
 type Config struct {
-       Test      int    `yaml:"test"`
-       ServeAddr string `yaml:"serveAddr"`
-       Db        struct {
+       Test         int    `yaml:"test"`
+       ServeAddr    string `yaml:"serveAddr"`
+       SessionStore string `yaml:"sessionStore"`
+       Db           struct {
                Addr     string `yaml:"addr"`
                InitFile string `yaml:"initFile"`
        } `yaml:"db"`
index 9c86e01f08ea0c97e49406cb55cf003b667a96da..fc646697b034e6e1fbd4855596af1893f4ec36aa 100644 (file)
@@ -7,6 +7,7 @@ import (
 
        pkgauth "our-wedding-rsvp/pkg/auth"
        pkgdb "our-wedding-rsvp/pkg/db"
+       pkgglob "our-wedding-rsvp/pkg/glob"
 
        "github.com/gin-gonic/contrib/sessions"
        "github.com/gin-gonic/gin"
@@ -53,7 +54,7 @@ func OauthGoogleCallback(c *gin.Context) {
 
        var session_id string
 
-       v := session.Get("RSVP")
+       v := session.Get(pkgglob.G_CONF.SessionStore)
 
        if v == nil {
                log.Printf("access auth failed: %s\n", "session id not found")
index 6cf89982aa9da62f9f3e8bc3bdc7f0628d9432cd..1ed67649aa681158e2da25f1e4d7b65c98792f48 100644 (file)
@@ -1,19 +1,30 @@
 package server
 
 import (
+       pkgserverapi "our-wedding-rsvp/pkg/server/api"
+
+       pkgauth "our-wedding-rsvp/pkg/auth"
+       pkgglob "our-wedding-rsvp/pkg/glob"
+
        "github.com/gin-gonic/contrib/sessions"
        "github.com/gin-gonic/gin"
-
-       pkgserverapi "our-wedding-rsvp/pkg/server/api"
 )
 
 func CreateServerFromConfig() (*gin.Engine, error) {
 
        genserver := gin.Default()
 
-       store := sessions.NewCookieStore([]byte("RSVP"))
+       store := sessions.NewCookieStore([]byte(pkgglob.G_CONF.SessionStore))
+
+       so := sessions.Options{
+               Path: "/",
+       }
+
+       store.Options(so)
+
+       genserver.Use(sessions.Sessions(pkgglob.G_CONF.SessionStore, store))
 
-       genserver.Use(sessions.Sessions("RSVP", store))
+       pkgauth.USE_OAUTH2 = pkgglob.G_CONF.Admin.UseOauth2
 
        err := configureServer(genserver)
 
diff --git a/public/js/common.js b/public/js/common.js
new file mode 100644 (file)
index 0000000..1ddc8d8
--- /dev/null
@@ -0,0 +1,94 @@
+USER_LOGIN = {
+
+    id: "",
+    passphrase: ""
+}
+
+async function userSignin(){
+
+
+
+    let u_id = document.getElementById("user-id").value 
+
+    if(u_id == ""){
+  
+        alert("no user id")
+    
+        return
+    
+    }
+
+
+    let u_pw = document.getElementById("user-pw").value 
+
+
+    if(u_pw == ""){
+  
+        alert("no user pw")
+    
+        return
+    
+    }
+
+
+
+    let uc = JSON.parse(JSON.stringify(USER_LOGIN))
+
+    uc.id = u_id
+    uc.passphrase = u_pw
+
+    let req = {
+        data: JSON.stringify(uc)
+    }
+
+    let resp = await fetch(`/api/signin`, {
+        body: JSON.stringify(req),
+        method: "POST"
+    })
+
+
+    let result = await resp.json()
+
+    if(result.status != "success"){
+
+        alert("failed to login")
+
+        return
+    }
+
+    alert("successfully logged in: " + result.reply)
+
+    location.href = "/"
+
+
+}
+
+
+
+
+async function getArticleList(){
+
+
+      let resp = await fetch("/api/story/list", {
+        method: "GET"
+    })
+
+    let result = await resp.json()
+
+    if(result.status != "success"){
+
+        alert("failed to get sample list")
+
+        return
+
+    }
+
+
+    let contentReader = document.getElementById("article-reader")
+
+    let contentEntry = JSON.parse(result.reply)
+    
+    console.log(contentEntry)
+  
+}
+  
index 82a9f3ded1ea06a8e82ac5228cbe0ed39be9635e..24dada635dee0e96c82ea99e0a83ca7e6f75e9a4 100644 (file)
@@ -10,7 +10,7 @@ async function getArticleContent(){
       return
   }
 
-  let resp = await fetch(`/api/story/r/${contentId}`, {
+  let resp = await fetch(`/api/story/download/${contentId}`, {
       method: "GET"
   })
 
@@ -238,7 +238,7 @@ async function loadArticleContent(){
 
 (async function(){
 
-  await loadArticleContent()
+  await getArticleContent()
 
 })()
 
index 811c0a2070364f42ad41462903e5ae9b410958e7..ce018c772bd13e3ba70ae38aaf8efbb369e7f7ec 100644 (file)
@@ -1,7 +1,10 @@
 
 ARTICLE_INFO = {
     "title": "",
-    "content": ""
+    "content": "",
+    "dateMarked": "",
+    "primaryMediaName":""
+
 }
 
 
@@ -187,7 +190,14 @@ var editor = new EditorJS({
           type: "header",
           data: {
             text: "Title",
-            level: 2
+            level: 1
+          }
+        },
+        {
+          type: "header",
+          data: {
+            text: "[0000-00]",
+            level: 3
           }
         },
         {
@@ -224,6 +234,17 @@ saveButton.addEventListener('click', async function () {
 
     a_info.title = savedData.blocks[0].data.text
 
+    a_info.dateMarked = savedData.blocks[1].data.text
+
+    blen = savedData.blocks.len 
+
+    for (let i = 0 ; i < blen; i ++){
+
+
+
+
+    }
+
     a_info.content = JSON.stringify(savedData)
 
     let req = {
@@ -249,8 +270,6 @@ saveButton.addEventListener('click', async function () {
 
     alert("successfully submitted: " + result.reply)
 
-    await getArticleList()
-
 });
 
 toggleReadOnlyButton.addEventListener('click', async () => {
index 482f9e8fc4acf3625927f593aa4b53ed13638946..8a36d75355bf76a2df626df4844b1a8cc1691514 100644 (file)
 {{ define "signin.html" }}
-<!DOCTYPE html>
-<html lang="en-US">
-<head>
-    <meta charset="UTF-8">
-    <meta content="IE=edge" http-equiv="X-UA-Compatible">
-    <meta content="width=device-width, initial-scale=1" name="viewport">
-    <title>최원영과 이소민의 결혼식</title>
-    <meta content="최원영과 이소민의 결혼식에 와서 축하해주세요~!" name="description"/>
-    <meta property="og:image" content="/public/images/pic2.jpeg">
-    <meta property="fb:app_id" content="781066922265598" />
-    <meta property="fb:admins" content="Choi.Anderson"/>
-    <link href="/public/images/favicon/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180">
-    <link href="/public/images/favicon/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png">
-    <link href="/public/images/favicon/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png">
-    <link href="https://fonts.googleapis.com/css?family=Dosis:400,500" rel="stylesheet">
-    <link href="https://fonts.googleapis.com/css?family=Great+Vibes" rel="stylesheet">
-    <link href="/public/css/ekko-lightbox.css" rel="stylesheet">
-    <link href="/public/styles/main.css" rel="stylesheet">
-    <link href="https://fonts.googleapis.com/css?family=Gamja+Flower|Gugi|Noto+Serif+KR|Stylish|Sunflower:300"
-          rel="stylesheet">
-    <script src="https://code.jquery.com/jquery-2.2.1.js"></script>
-
-
-    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
-    <script src="https://cdn.emailjs.com/sdk/2.3.2/email.min.js" type="text/javascript"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.js" type="text/javascript"></script>
-
-
-    <script type="text/javascript">
-        function sendMail() {
-
-            (function () {
-                emailjs.init("user_yjLL5xG0A3kkOCH5BGIDh");
-                emailjs.send("wedding-mail", "gift_send", {
-                    name: $("#sender-name").value,
-                    gift: $("#gift-name").text(),
-                    message: $("#sender-message").value
-                }).then(function (response) {
-                    console.log("SUCCESS. status=%d, text=%s", response.status, response.text);
-                }, function (err) {
-                    console.log("FAILED. error=", err);
-                });
-            })();
-        }
-
-        function findGetParameter(parameterName) {
-            var result = null,
-                tmp = [];
-            location.search
-                .substr(1)
-                .split("&")
-                .forEach(function (item) {
-                  tmp = item.split("=");
-                  if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
-                });
-            return result;
-        }
-
-        $(document).ready(function () {
-
-            function getText(){
-                var result = null;
-                $.ajax( { url: "https://raw.githubusercontent.com/AndersonChoi/wedding-card/master/README.md",
-                        type: 'get',
-                        dataType: 'html',
-                        async: false,
-                        success: function(data) { result = data; }
-                    }
-                );
-                FileReady = true;
-                return result;
-            }
-            var markdown_source = getText();
-            var comment_contents = markdown_source.split("축하의 말")[1];
-
-            var md = new Remarkable();
-            $("#comments").append(md.render(comment_contents));
-
-            
-            if(findGetParameter('gift')=='false'){
-                $('#gifts').hide();
-            }
-        });
-
-
-
-
-    </script>
-</head>
-
-<body id="top">
-<header></header>
-<div id="fb-root"></div>
-<script async defer crossorigin="anonymous" src="https://connect.facebook.net/ko_KR/sdk.js#xfbml=1&version=v3.2"></script>
-<div class="page-content">
-    <div class="div">
-        <div class="ww-home-page" id="home">
-            <div class="ww-wedding-announcement d-flex align-items-center justify-content-start">
-                <div class="container ww-announcement-container">
-                    <p class="ww-couple-name ww-title" style="font-size:4.0em">Wonyoung & Somin</p>
-                    <p class="h2 mt-5 ww-title" style="font-family: 'Gugi', cursive; font-size:1.0em">
-                        | WE ARE GETTING MARRIED |
-                    </p>
-                    <p class="h2 mt-5 ww-title"
-                       style="font-family: 'Noto Serif KR', serif; font-size:1.0em; letter-spacing:-1px">
-                        <b style="font-size:1.4em;">2019. 05. 18. SAT PM 02:30</b>
-                        <br>부산 해운대 센텀시티 센텀사이언스파크 23층
-                    </p>
-                </div>
-            </div>
-        </div>
-        <div class="ww-nav-bar sticky-top bg-light">
-            <nav class="navbar navbar-expand-lg navbar-light">
-                <div class="container">
-                    <button aria-controls="ww-navbarNav" aria-expanded="false" aria-label="Toggle navigation"
-                            class="navbar-toggler"
-                            data-target="#ww-navbarNav" data-toggle="collapse" type="button">
-                        <span class="navbar-toggler-icon"></span>
-                    </button>
-                    <div class="collapse navbar-collapse text-uppercase" id="ww-navbarNav">
-                        <ul class="navbar-nav ml-auto">
-                            <li class="nav-item"><a class="nav-link smooth-scroll" href="#home">Home</a></li>
-                            <li class="nav-item"><a class="nav-link smooth-scroll" href="#couple">Couple</a></li>
-                            <li class="nav-item"><a class="nav-link smooth-scroll" href="#events">Events</a></li>
-                            <li class="nav-item"><a class="nav-link smooth-scroll" href="#gallery">Gallery</a></li>
-                        </ul>
-                    </div>
-                </div>
-            </nav>
-        </div>
-        <div class="ww-section" id="couple">
-            <div class="container">
-                <h2 class="h1 text-center pb-3 ww-title" style="font-family: 'Noto Serif KR', serif;">신랑 & 신부</h2>
-                <div class="row text-center">
-                    <div class="col-md-6">
-                        <div class="mt-3">
-                            <h3 class="h2 ww-title" style="font-family: 'Sunflower', sans-serif; font-size:1.5em">
-                                이소민</h3>
-                            <img alt="Groom" class="img-fluid" src="/public/images/pic8.jpeg"/>
-                        </div>
-                    </div>
-                    <div class="col-md-6">
-                        <div class="mt-3">
-                            <h3 class="h2 ww-title" style="font-family: 'Sunflower', sans-serif; font-size:1.5em">
-                                최원영</h3>
-                            <img alt="Bride" class="img-fluid" src="/public/images/pic9.jpeg"/>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="ww-section bg-light" id="events">
-            <div class="container ww-wedding-event">
-                <h2 class="h1 text-center pb-3 ww-title" style="font-family: 'Noto Serif KR', serif;">초대합니다</h2>
-                    <div class="col text-center mb-5">
-                        <h6 style="font-family: 'Noto Serif KR', serif;">
-                            1463<br>
-                            (만난지 4년+1일 되는날 결혼 = 1463일)
-                        </h6>
-                    </div>
-                <div class="row">
-                    <div class="col-md-7 col-sm-12">
-                        <div class="my-3">
-                            <div class="h4">웨딩 본식</div>
-                            <ul>
-                                <li>
-                                    <i class="text-muted fas fa-map-marker-alt"></i>
-                                    <span class="pl-2 text-muted">부산 해운대 우동 센텀사이언스 파크 23층</span>
-                                </li>
-                                <li class="pt-2">
-                                    <i class="text-muted far fa-calendar-alt"></i>
-                                    <span class="pl-2 text-muted">2019년 5월 18일, 2:30PM</span>
-                                </li>
-                            </ul>
-                        </div>
-                    </div>
-                    <div class="col-md-5 col-sm-12">
-                        <div class="my-3">
-                            <img alt="Wedding Party" class="img-fluid" src="/public/images/wedding-party.jpg"/>
-                        </div>
-                    </div>
-                </div>
-                <div class="row">
-                    <div class="col-md-7 col-sm-12">
-                        <div class="my-3">
-                            <div class="h4">식사</div>
-                            <ul>
-                                <li>
-                                    <i class="text-muted fas fa-map-marker-alt "></i>
-                                    <span class="pl-2 text-muted">부산 해운대 우동 센텀사이언스 파크 지하 1층 더파티 센텀점</span>
-                                </li>
-                                <li class="pt-2">
-                                    <i class="text-muted far fa-calendar-alt "></i>
-                                    <span class="pl-2 text-muted">2019년 5월 18일, 2:30PM - 4:30PM</span>
-                                </li>
-                            </ul>
-                        </div>
-                    </div>
-                    <div class="col-md-5 col-sm-12">
-                        <div class="my-3"><img alt="Reception" class="img-fluid" src="/public/images/reception.jpg"/></div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="ww-section" id="gallery">
-            <div class="ww-photo-gallery">
-                <div class="container">
-                    <h2 class="h1 text-center pb-3 ww-title" style="font-family: 'Noto Serif KR', serif;">포토 갤러리</h2>
-                    <div class="ww-gallery">
-                        <div class="card-columns">
-                            <div class="card" data-groups="[&quot;party&quot;,&quot;wedding&quot;]">
-                                <a data-gallery="ww-gallery" data-toggle="lightbox">
-                                    <img alt="Gallery Pic 2" class="img-fluid" src="/public/images/pic2.jpeg"/>
-                                </a>
-                            </div>
-                            <div class="card" data-groups="[&quot;vacation&quot;]">
-                                <a data-gallery="ww-gallery" data-toggle="lightbox">
-                                    <img alt="Gallery Pic 3" class="img-fluid" src="/public/images/pic3.jpeg"/>
-                                </a>
-                            </div>
-                            <div class="card" data-groups="[&quot;party&quot;,&quot;vacation&quot;]">
-                                <a data-gallery="ww-gallery" data-toggle="lightbox">
-                                    <img alt="Gallery Pic 4" class="img-fluid" src="/public/images/pic4.jpeg"/>
-                                </a>
-                            </div>
-                            <div class="card" data-groups="[&quot;vacation&quot;]">
-                                <a data-gallery="ww-gallery" data-toggle="lightbox">
-                                    <img alt="Gallery Pic 5" class="img-fluid" src="/public/images/pic6.jpeg"/>
-                                </a>
-                            </div>
-                            <div class="card"
-                                 data-groups="[&quot;wedding&quot;,&quot;ceremony&quot;,&quot;party&quot;]">
-                                <a data-gallery="ww-gallery" data-toggle="lightbox">
-                                    <img alt="Gallery Pic 6" class="img-fluid" src="/public/images/pic7.jpeg"/>
-                                </a>
-                            </div>
-                            <div class="card" data-groups="[&quot;vacation&quot;]">
-                                <a data-gallery="ww-gallery" data-toggle="lightbox">
-                                    <img alt="Gallery Pic 7" class="img-fluid" src="/public/images/pic5.jpeg"/>
-                                </a>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-       <div class="ww-section parallax-window  text-white" data-parallax="scroll" data-image-src="/public/images/gift/gift-background.jpg" id="gifts">
-            <div class="ww-gift-section">
-                <div class="container">
-                    <h2 class="h1 text-center pb-3 ww-title" style="font-family: 'Noto Serif KR', serif;">Gift for our
-                        wedding</h2>
-                    <div class="col text-center mb-5">
-                        <h6 style="font-family: 'Noto Serif KR', serif;">
-                            저희 부부가 앞으로 살아나갈 일상에<br>
-                            오래도록 특별한 기억을 선물하고 싶으신가요?<br>
-                            그렇다면 고민하는 대신 아래 목록을 참고해 주세요.<br>
-                            저희가 필요로 하는 물건들을 정리해 두었습니다.<br>
-                            애정어린 마음으로 보내주신 선물은<br>
-                            가까이 두어 오래도록 아껴 쓰고,<br>
-                            소중하게 간직하겠습니다.
-                            <br><br>
-                            (아래 선물버튼을 눌러 신랑, 신부에게 예약메시지를 보내세요!)
-                        </h6>
-                    </div>
-                    <div class="ww-gift">
-                        <div class="gift-columns">
-                            <div class="gift">
-                                <img alt="와인셀러" class="img-fluid gift-img gift-selected" src="/public/images/gift/wineceller.png"/>
-                                <div class="btn-group gift-btn-group" role="group">
-                                    <button class="btn btn-default gift-btn"
-                                            onclick="window.open('https://smartstore.naver.com/dhk00840/products/4311205513')">
-                                        <i class="fa fa-search"></i></button>
-                                    <button class="btn btn-default gift-btn gift-send" data-name="와인셀러"
-                                            onclick="alert('다른분에게 예약된 선물입니다.');"><i
-                                            class="fa fa-gift"></i></button>
+<!doctype html>
+<html class="tui-bg-blue-black">
+
+    <head>
+        <title> sign in </title>
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+    </head>
+
+    <body>
+        <div class="container">
+            <div class="row">
+              <div class="col s12 m12 l12">sign in</div>
+            </div>
+            <div class="row">
+                <div class="col s12 m12 l12">
+                    <div class="tui-window tui-scroll-white">
+                        <fieldset class="tui-fieldset tui-border-double">
+                            <legend>sign in</legend>
+                            <fieldset class="tui-fieldset tui-border-dotted">
+                                <div>
+                                    <input class="tui-input purple-255" type='text' id='user-id'/>
+                                    <label for='user-id'>Enter ID</label>
                                 </div>
-                            </div>
-                            <div class="gift">
-                                <img alt="전동클렌저" class="img-fluid gift-img gift-selected"
-                                     src="/public/images/gift/philips_clenser.png"/>
-                                <div class="btn-group gift-btn-group" role="group">
-                                    <button class="btn btn-default gift-btn"
-                                            onclick="window.open('https://www.philips.co.kr/c-p/BSC111_06/visapure-mini-facial-cleanser')">
-                                        <i class="fa fa-search"></i></button>
-                                    <button class="btn btn-default gift-btn gift-send" data-name="전동클렌저"
-                                            onclick="alert('다른분에게 예약된 선물입니다.');"><i
-                                            class="fa fa-gift"></i></button>
-                                </div>
-                            </div>
-                            <div class="gift">
-                                <img alt="드라이기" class="img-fluid gift-img gift-selected" src="/public/images/gift/dyson.png"/>
-                                <div class="btn-group gift-btn-group" role="group">
-                                    <button class="btn btn-default gift-btn"
-                                            onclick="window.open('https://www.kr.dyson.com/products/hair-care/dyson-supersonic-hair-dryer')">
-                                        <i class="fa fa-search"></i></button>
-                                    <button  class="btn btn-default gift-btn gift-send" data-name="드라이기"
-                                             onclick="alert('다른분에게 예약된 선물입니다.');"><i
-                                            class="fa fa-gift"></i></button>
-                                </div>
-                            </div>
-                            <div class="gift">
-                                <img alt="믹서기" class="img-fluid gift-img gift-selected" src="/public/images/gift/blender.png"/>
-                                <div class="btn-group gift-btn-group" role="group">
-                                    <button class="btn btn-default gift-btn"
-                                            onclick="window.open('http://jenniferoom.co.kr/product/detail.html?product_no=85&cate_no=24&display_group=1')">
-                                        <i class="fa fa-search"></i></button>
-                                    <button  class="btn btn-default gift-btn gift-send" data-name="믹서기"
-                                             onclick="alert('다른분에게 예약된 선물입니다.');"><i
-                                            class="fa fa-gift"></i></button>
+                            </fieldset>
+                            <fieldset class="tui-fieldset tui-border-dotted">
+                                <div>
+                                    <input class="tui-input purple-255" type='password' id='user-pw'/>
+                                    <label for='user-pw'>Enter Password</label>
                                 </div>
+                            </fieldset>
+            
+                            <br/>
+                            <div>
+                                <input class="tui-button" type="button" onclick="userSignin()" value="user login">
                             </div>
-                            <div class="gift">
-                                <img alt="레고" class="img-fluid gift-img gift-selected" src="/public/images/gift/lego.png"/>
-                                <div class="btn-group gift-btn-group" role="group">
-                                    <button class="btn btn-default gift-btn"
-                                            onclick="window.open('https://shop.lego.com/ko-KR/product/10232')"><i
-                                            class="fa fa-search"></i></button>
-                                    <button class="btn btn-default gift-btn gift-send" data-name="레고"
-                                            
-                                             onclick="alert('다른분에게 예약된 선물입니다.');"><i
-                                            class="fa fa-gift"></i></button>
-                                </div>
-                            </div>
-                            <div class="gift">
-                                <img alt="전기레인지" class="img-fluid gift-img gift-selected" src="/public/images/gift/range.png"/>
-                                <div class="btn-group gift-btn-group" role="group">
-                                    <button class="btn btn-default gift-btn"
-                                            onclick="window.open('https://www.lge.co.kr/lgekor/product/kitchen/electricRange/productDetail.do?cateId=4410&prdId=EPRD.333447')">
-                                        <i class="fa fa-search"></i></button>
-                                    <button class="btn btn-default gift-btn gift-send" data-name="전기레인지"
-                                            
-                                             onclick="alert('다른분에게 예약된 선물입니다.');"><i
-                                            class="fa fa-gift"></i></button>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="ww-section ww-rsvp-detail" id="map">
-            <div class="container">
-                <div class="col text-center">
-                    <h2 class="h1 text-center pb-3 ww-title" style="font-family: 'Noto Serif KR', serif;">오시는 길</h2>
-                    <div>
-                        <h5 style="font-family: 'Noto Serif KR', serif;">센텀사이언스파크웨딩홀 23층 스카이홀</h5>
-                        <h6 style="font-family: 'Noto Serif KR', serif;">(부산 해운대구 센텀중앙로 79)</h6>
-                    </div>
-                </div>
-
-                <div class="form-group">
-                    <div class="col-md-12">
-                        <div class="my-3 text-center">
-                            <a href="http://naver.me/5pTy3HCa">
-                                <img alt="naver-map" class="map-icon" id="naver-map"
-                                     src="/public/images/map/naver-map.png"/>
-                            </a>
-                            <a href="http://dmaps.kr/2bms8">
-                                <img alt="kakao-map" class="map-icon" id="kakao-map"
-                                     src="/public/images/map/kakao-map.png"/>
-                            </a>
-                            <a href="https://maps.app.goo.gl/jfDxw">
-                                <img alt="google-map" class="map-icon" id="google-map"
-                                     src="/public/images/map/google-map.png"/>
-                            </a>
-                        </div>
-                        <div class="col text-center">
-                            <label style="font-family: 'Noto Serif KR', serif; font-size: 15px;">
-                                셔틀버스 - 센텀시티역 4번출구앞에서 15분 간격으로 운행
-                            </label>
-                        </div>
-                        <div class="my-3">
-                            <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3261.297439052569!2d129.1238775160104!3d35.1741384652207!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x356892c2513ecf5d%3A0x7d362ece2091e2f8!2z7IS87YWA7IKs7J207Ja47Iqk7YyM7YGsIOy7qOuypOyFmO2ZgA!5e0!3m2!1sko!2skr!4v1554092125630!5m2!1sko!2skr" width="100%" height="400" frameborder="0" style="border:0" allowfullscreen></iframe>
-                        </div>
-                    </div>
-                </div>
-
-
-            </div>
-        </div>
-
-        <div class="ww-section bg-light" id="comment">
-            <div class="ww-photo-gallery">
-                <div class="container">
-                    <div class="col text-center">
-                        <h2 class="h1 text-center pb-3 ww-title" style="font-family: 'Noto Serif KR', serif;">축하메시지</h2><br>
-                        <div id="comments"></div>
-                        <br>
-                        <div class="row">
-                            <div class="col text-center"><form action="https://github.com/AndersonChoi/wedding-card/blob/master/README.md">
-                                <button class="btn btn-primary btn-submit" type="submit">메시지 남기러 가기</button></form>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-    </div>
-</div>
-</div>
-<div aria-hidden="true" aria-labelledby="exampleModalLabel" class="modal fade" id="giftMailModal" role="dialog"
-     tabindex="-1">
-    <div class="modal-dialog modal-dialog-centered" role="document">
-        <div class="modal-content">
-            <div class="modal-header">
-                <h5 class="modal-title" id="exampleModalLongTitle">선물하기 - <span id="gift-name"></span></h5>
-                <button aria-label="Close" class="close" data-dismiss="modal" type="button">
-                    <span aria-hidden="true">&times;</span>
-                </button>
-            </div>
-            <div class="modal-body">
-                <div class="input-group mb-3">
-                    <div class="input-group-prepend">
-                        <span class="input-group-text">보내는 분 성함</span>
+            
+                        </fieldset>
                     </div>
-                    <input aria-describedby="basic-addon3" class="form-control" id="sender-name" type="text">
-                </div>
-                <div class="input-group">
-                    <textarea aria-label="With textarea" class="form-control" id="sender-message"
-                              placeholder="신랑, 신부에게 선물 예약과 함께 보낼 메시지를 입력해주세요. 이 메시지는 신랑, 신부에게 발송됩니다." rows=4></textarea>
                 </div>
             </div>
-            <div class="modal-footer">
-                <button class="btn btn-primary" id="reserveGiftButton" type="button">예약</button>
-            </div>
         </div>
-    </div>
-</div>
-<footer></footer>
-<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
-<script src="/public/js/aos.js"></script>
-<script src="/public/js/parallax.min.js"></script>
-<script src="/public/js/ekko-lightbox.min.js"></script>
-<script src="/public/scripts/main.js"></script>
-
-<div class="bottom_right"><i class="fa fa-arrow-up fa-2x" id="go-to-top"></i>
-</div>
 
-<div class="bottom_left">
-    <audio id="player" src="/public/mus.mp3"></audio>
-    <div>
-        <i class="fa fa-music fa-2x" onclick="document.getElementById('player').play()"></i>
-    </div>
-</div>
+        <script src="/public/js/common.js"></script>
+    </body>
 
-</body>
 </html>
-{{ end }}
+{{ end }}
\ No newline at end of file