Compare commits
7 Commits
63585e31f6
...
05db85eca1
Author | SHA1 | Date | |
---|---|---|---|
05db85eca1 | |||
f39c000e5d | |||
d16793c01c | |||
1971169e2f | |||
0e7b9d8c20 | |||
0f0c896065 | |||
c8b032236b |
@ -403,6 +403,7 @@ func (app *application) VirtualTerminalPaymentSucceeded(w http.ResponseWriter, r
|
|||||||
_, err = app.SaveTransaction(txn)
|
_, err = app.SaveTransaction(txn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.badRequest(w, r, err)
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.writeJSON(w, http.StatusOK, txn)
|
app.writeJSON(w, http.StatusOK, txn)
|
||||||
@ -522,12 +523,20 @@ func (app *application) AllSales(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
err := app.readJSON(w, r, &payload)
|
err := app.readJSON(w, r, &payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
app.badRequest(w, r, err)
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
allSales, lastPage, totalRecords, err := app.DB.GetAllOrdersPaginated(false, 2, 1)
|
allSales, lastPage, totalRecords, err := app.DB.GetAllOrdersPaginated(
|
||||||
|
false,
|
||||||
|
payload.PageSize,
|
||||||
|
payload.CurrentPage,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
app.badRequest(w, r, err)
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp struct {
|
var resp struct {
|
||||||
@ -538,7 +547,7 @@ func (app *application) AllSales(w http.ResponseWriter, r *http.Request) {
|
|||||||
Orders []*models.Order `json:"orders"`
|
Orders []*models.Order `json:"orders"`
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.CurrentPage = 1
|
resp.CurrentPage = payload.CurrentPage
|
||||||
resp.PageSize = payload.PageSize
|
resp.PageSize = payload.PageSize
|
||||||
resp.LastPage = lastPage
|
resp.LastPage = lastPage
|
||||||
resp.TotalRecords = totalRecords
|
resp.TotalRecords = totalRecords
|
||||||
@ -548,11 +557,43 @@ func (app *application) AllSales(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *application) AllSubscriptions(w http.ResponseWriter, r *http.Request) {
|
func (app *application) AllSubscriptions(w http.ResponseWriter, r *http.Request) {
|
||||||
allSubscriptions, err := app.DB.GetAllOrders(true)
|
var payload struct {
|
||||||
if err != nil {
|
PageSize int `json:"page_size"`
|
||||||
app.badRequest(w, r, err)
|
CurrentPage int `json:"page"`
|
||||||
}
|
}
|
||||||
app.writeJSON(w, http.StatusOK, allSubscriptions)
|
err := app.readJSON(w, r, &payload)
|
||||||
|
if err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
allSales, lastPage, totalRecords, err := app.DB.GetAllOrdersPaginated(
|
||||||
|
true,
|
||||||
|
payload.PageSize,
|
||||||
|
payload.CurrentPage,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp struct {
|
||||||
|
CurrentPage int `json:"current_page"`
|
||||||
|
PageSize int `json:"page_size"`
|
||||||
|
LastPage int `json:"last_page"`
|
||||||
|
TotalRecords int `json:"total_records"`
|
||||||
|
Orders []*models.Order `json:"orders"`
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.CurrentPage = payload.CurrentPage
|
||||||
|
resp.PageSize = payload.PageSize
|
||||||
|
resp.LastPage = lastPage
|
||||||
|
resp.TotalRecords = totalRecords
|
||||||
|
resp.Orders = allSales
|
||||||
|
|
||||||
|
app.writeJSON(w, http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *application) GetSale(w http.ResponseWriter, r *http.Request) {
|
func (app *application) GetSale(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -562,6 +603,7 @@ func (app *application) GetSale(w http.ResponseWriter, r *http.Request) {
|
|||||||
order, err := app.DB.GetOrderByID(orderID)
|
order, err := app.DB.GetOrderByID(orderID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.badRequest(w, r, err)
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
app.writeJSON(w, http.StatusOK, order)
|
app.writeJSON(w, http.StatusOK, order)
|
||||||
}
|
}
|
||||||
@ -660,3 +702,13 @@ func (app *application) CancelSubscription(w http.ResponseWriter, r *http.Reques
|
|||||||
|
|
||||||
app.writeJSON(w, http.StatusOK, resp)
|
app.writeJSON(w, http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *application) AllUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
allUsers, err := app.DB.GetAllUsers()
|
||||||
|
if err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
|
app.badRequest(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
app.writeJSON(w, http.StatusOK, allUsers)
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ func (app *application) routes() http.Handler {
|
|||||||
mux.Post("/get-sale/{id}", app.GetSale)
|
mux.Post("/get-sale/{id}", app.GetSale)
|
||||||
mux.Post("/refund", app.RefundCharge)
|
mux.Post("/refund", app.RefundCharge)
|
||||||
mux.Post("/cancel-subscription", app.CancelSubscription)
|
mux.Post("/cancel-subscription", app.CancelSubscription)
|
||||||
|
mux.Post("/all-users", app.AllUsers)
|
||||||
})
|
})
|
||||||
mux.Post("/api/forgot-password", app.SendPasswordResetEmail)
|
mux.Post("/api/forgot-password", app.SendPasswordResetEmail)
|
||||||
mux.Post("/api/reset-password", app.ResetPassword)
|
mux.Post("/api/reset-password", app.ResetPassword)
|
||||||
|
@ -417,3 +417,15 @@ func (app *application) ShowSubscriptions(w http.ResponseWriter, r *http.Request
|
|||||||
app.errorLog.Println(err)
|
app.errorLog.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *application) AllUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if err := app.renderTemplate(w, r, "all-users", &templateData{}); err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *application) OneUser(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if err := app.renderTemplate(w, r, "one-user", &templateData{}); err != nil {
|
||||||
|
app.errorLog.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,6 +19,8 @@ func (app *application) routes() http.Handler {
|
|||||||
mux.Get("/all-subscriptions", app.AllSubscriptions)
|
mux.Get("/all-subscriptions", app.AllSubscriptions)
|
||||||
mux.Get("/sales/{id}", app.ShowSale)
|
mux.Get("/sales/{id}", app.ShowSale)
|
||||||
mux.Get("/subscriptions/{id}", app.ShowSubscriptions)
|
mux.Get("/subscriptions/{id}", app.ShowSubscriptions)
|
||||||
|
mux.Get("/all-users", app.AllUsers)
|
||||||
|
mux.Get("/all-users/{id}", app.OneUser)
|
||||||
})
|
})
|
||||||
|
|
||||||
// mux.Post("/virtual-terminal-payment-succeeded", app.VirtualTerminalPaymentSucceeded)
|
// mux.Post("/virtual-terminal-payment-succeeded", app.VirtualTerminalPaymentSucceeded)
|
||||||
|
@ -18,10 +18,21 @@ All Sales
|
|||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<nav>
|
||||||
|
<ul id="paginator" class="pagination">
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ define "js" }}
|
{{ define "js" }}
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import {showTable} from "/static/js/all-sales.js"
|
import {pageSize} from "/static/js/common.js"
|
||||||
showTable({{.API}});
|
import {showTable, currentPage} from "/static/js/all-sales.js"
|
||||||
|
|
||||||
|
let curPage = currentPage;
|
||||||
|
if (sessionStorage.getItem("cur-page") !== null) {
|
||||||
|
curPage = sessionStorage.getItem("cur-page");
|
||||||
|
sessionStorage.removeItem("cur-page");
|
||||||
|
}
|
||||||
|
showTable({{.API}}, pageSize, curPage);
|
||||||
</script>
|
</script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -20,11 +20,22 @@ All Subscriptions
|
|||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<nav>
|
||||||
|
<ul id="paginator" class="pagination">
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "js"}}
|
{{define "js"}}
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import {showTable} from "/static/js/all-subscriptions.js"
|
import {pageSize} from "/static/js/common.js"
|
||||||
showTable({{.API}});
|
import {showTable, currentPage} from "/static/js/all-subscriptions.js"
|
||||||
|
|
||||||
|
let curPage = currentPage;
|
||||||
|
if (sessionStorage.getItem("cur-page") !== null) {
|
||||||
|
curPage = sessionStorage.getItem("cur-page");
|
||||||
|
sessionStorage.removeItem("cur-page");
|
||||||
|
}
|
||||||
|
showTable({{.API}}, pageSize, curPage);
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
28
cmd/web/templates/all-users.page.gohtml
Normal file
28
cmd/web/templates/all-users.page.gohtml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{{ template "base". }}
|
||||||
|
{{ define "title" }}
|
||||||
|
All Users
|
||||||
|
{{ end }}
|
||||||
|
{{ define "content" }}
|
||||||
|
<h2 class="mt-5">All Admin users</h2>
|
||||||
|
<hr>
|
||||||
|
<div class="float-end">
|
||||||
|
<a class="btn btn-outline-secondary" href="/admin/all-users/0">Add User</a>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<table id="user-table" class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Email</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{ end }}
|
||||||
|
{{ define "js" }}
|
||||||
|
<script type="module">
|
||||||
|
import {showUsers} from "/static/js/all-users.js"
|
||||||
|
showUsers({{.API}});
|
||||||
|
</script>
|
||||||
|
{{ end }}
|
@ -70,6 +70,12 @@
|
|||||||
<li>
|
<li>
|
||||||
<hr class="dropdown-divider">
|
<hr class="dropdown-divider">
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="/admin/all-users">All Users</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<hr class="dropdown-divider">
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" href="/logout">Logout</a>
|
<a class="dropdown-item" href="/logout">Logout</a>
|
||||||
</li>
|
</li>
|
||||||
|
11
cmd/web/templates/one-user.page.gohtml
Normal file
11
cmd/web/templates/one-user.page.gohtml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{ template "base". }}
|
||||||
|
{{ define "title" }}
|
||||||
|
Admin User
|
||||||
|
{{ end }}
|
||||||
|
{{ define "content" }}
|
||||||
|
<h2 class="mt-5">Admin user</h2>
|
||||||
|
<hr>
|
||||||
|
{{ end }}
|
||||||
|
{{ define "js" }}
|
||||||
|
{{ end }}
|
||||||
|
|
@ -150,7 +150,7 @@ func (m *DBModel) InsertTransaction(txn Transaction) (int, error) {
|
|||||||
(amount, currency, last_four, expiry_month, expiry_year,
|
(amount, currency, last_four, expiry_month, expiry_year,
|
||||||
payment_intent, payment_method, bank_return_code,
|
payment_intent, payment_method, bank_return_code,
|
||||||
transaction_status_id, created_at, updated_at)
|
transaction_status_id, created_at, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
|
||||||
|
|
||||||
result, err := m.DB.ExecContext(ctx, stmt,
|
result, err := m.DB.ExecContext(ctx, stmt,
|
||||||
txn.Amount,
|
txn.Amount,
|
||||||
@ -183,7 +183,7 @@ func (m *DBModel) InsertOrder(order Order) (int, error) {
|
|||||||
stmt := `INSERT INTO orders
|
stmt := `INSERT INTO orders
|
||||||
(widget_id, transaction_id, customer_id, status_id, quantity,
|
(widget_id, transaction_id, customer_id, status_id, quantity,
|
||||||
amount, created_at, updated_at)
|
amount, created_at, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?);`
|
||||||
|
|
||||||
result, err := m.DB.ExecContext(ctx, stmt,
|
result, err := m.DB.ExecContext(ctx, stmt,
|
||||||
order.WidgetID,
|
order.WidgetID,
|
||||||
@ -212,7 +212,7 @@ func (m *DBModel) InsertCustomer(customer Customer) (int, error) {
|
|||||||
|
|
||||||
stmt := `INSERT INTO customers
|
stmt := `INSERT INTO customers
|
||||||
(first_name, last_name, email, created_at, updated_at)
|
(first_name, last_name, email, created_at, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?)`
|
VALUES (?, ?, ?, ?, ?);`
|
||||||
|
|
||||||
result, err := m.DB.ExecContext(ctx, stmt,
|
result, err := m.DB.ExecContext(ctx, stmt,
|
||||||
customer.FirstName,
|
customer.FirstName,
|
||||||
@ -241,7 +241,7 @@ func (m *DBModel) GetUserByEmail(email string) (User, error) {
|
|||||||
|
|
||||||
query := `SELECT id, first_name, last_name, email, password, created_at, updated_at
|
query := `SELECT id, first_name, last_name, email, password, created_at, updated_at
|
||||||
FROM users
|
FROM users
|
||||||
WHERE email = ?`
|
WHERE email = ?;`
|
||||||
|
|
||||||
row := m.DB.QueryRowContext(ctx, query, email)
|
row := m.DB.QueryRowContext(ctx, query, email)
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ func (m *DBModel) Authenticate(email, password string) (int, error) {
|
|||||||
var id int
|
var id int
|
||||||
var hashedPassword string
|
var hashedPassword string
|
||||||
|
|
||||||
row := m.DB.QueryRowContext(ctx, "SELECT id, password from users WHERE email = ?", email)
|
row := m.DB.QueryRowContext(ctx, "SELECT id, password from users WHERE email = ?;", email)
|
||||||
err := row.Scan(&id, &hashedPassword)
|
err := row.Scan(&id, &hashedPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -288,7 +288,7 @@ func (m *DBModel) UpdatePasswordForUser(u User, hash string) error {
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
stmt := `UPDATE users SET password = ? where id = ?`
|
stmt := `UPDATE users SET password = ? where id = ?;`
|
||||||
|
|
||||||
_, err := m.DB.ExecContext(ctx, stmt, hash, u.ID)
|
_, err := m.DB.ExecContext(ctx, stmt, hash, u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -317,7 +317,7 @@ func (m *DBModel) GetAllOrders(isRecurring bool) ([]*Order, error) {
|
|||||||
WHERE
|
WHERE
|
||||||
w.is_recurring = ?
|
w.is_recurring = ?
|
||||||
ORDER BY
|
ORDER BY
|
||||||
o.created_at DESC
|
o.created_at DESC;
|
||||||
`
|
`
|
||||||
|
|
||||||
rows, err := m.DB.QueryContext(ctx, query, isRecurring)
|
rows, err := m.DB.QueryContext(ctx, query, isRecurring)
|
||||||
@ -387,7 +387,7 @@ func (m *DBModel) GetAllOrdersPaginated(
|
|||||||
w.is_recurring = ?
|
w.is_recurring = ?
|
||||||
ORDER BY
|
ORDER BY
|
||||||
o.created_at DESC
|
o.created_at DESC
|
||||||
LIMIT ? OFFSET ?
|
LIMIT ? OFFSET ?;
|
||||||
`
|
`
|
||||||
|
|
||||||
rows, err := m.DB.QueryContext(ctx, query, isRecurring, pageSize, offset)
|
rows, err := m.DB.QueryContext(ctx, query, isRecurring, pageSize, offset)
|
||||||
@ -433,7 +433,7 @@ func (m *DBModel) GetAllOrdersPaginated(
|
|||||||
SELECT COUNT(o.id)
|
SELECT COUNT(o.id)
|
||||||
FROM orders o
|
FROM orders o
|
||||||
LEFT JOIN widgets w on (o.widget_id = w.id)
|
LEFT JOIN widgets w on (o.widget_id = w.id)
|
||||||
WHERE w.is_recurring = ?
|
WHERE w.is_recurring = ?;
|
||||||
`
|
`
|
||||||
|
|
||||||
var totalRecords int
|
var totalRecords int
|
||||||
@ -444,6 +444,9 @@ func (m *DBModel) GetAllOrdersPaginated(
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastPage := totalRecords / pageSize
|
lastPage := totalRecords / pageSize
|
||||||
|
if totalRecords%pageSize != 0 {
|
||||||
|
lastPage++
|
||||||
|
}
|
||||||
|
|
||||||
return orders, lastPage, totalRecords, nil
|
return orders, lastPage, totalRecords, nil
|
||||||
}
|
}
|
||||||
@ -464,7 +467,7 @@ func (m *DBModel) GetOrderByID(ID int) (Order, error) {
|
|||||||
LEFT JOIN transactions t on (o.transaction_id = t.id)
|
LEFT JOIN transactions t on (o.transaction_id = t.id)
|
||||||
LEFT JOIN customers c on (o.customer_id = c.id)
|
LEFT JOIN customers c on (o.customer_id = c.id)
|
||||||
WHERE
|
WHERE
|
||||||
o.id = ?
|
o.id = ?;
|
||||||
`
|
`
|
||||||
|
|
||||||
var o Order
|
var o Order
|
||||||
@ -513,3 +516,118 @@ func (m *DBModel) UpdateOrderStatus(id, statusID int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *DBModel) GetAllUsers() ([]*User, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var users []*User
|
||||||
|
query := `
|
||||||
|
SELECT id, last_name, first_name, email, created_at, updated_at
|
||||||
|
FROM users
|
||||||
|
ORDER BY last_name, first_name;
|
||||||
|
`
|
||||||
|
|
||||||
|
rows, err := m.DB.QueryContext(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var u User
|
||||||
|
err = rows.Scan(
|
||||||
|
&u.ID,
|
||||||
|
&u.LastName,
|
||||||
|
&u.FirstName,
|
||||||
|
&u.Email,
|
||||||
|
&u.CreatedAt,
|
||||||
|
&u.UpdatedAt,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
users = append(users, &u)
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DBModel) GetOneUser(id int) (User, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var u User
|
||||||
|
query := `
|
||||||
|
SELECT id, last_name, first_name, email, created_at, updated_at
|
||||||
|
FROM users
|
||||||
|
WHERE id = ?;
|
||||||
|
`
|
||||||
|
|
||||||
|
row := m.DB.QueryRowContext(ctx, query, id)
|
||||||
|
|
||||||
|
err := row.Scan(
|
||||||
|
&u.ID,
|
||||||
|
&u.LastName,
|
||||||
|
&u.FirstName,
|
||||||
|
&u.Email,
|
||||||
|
&u.CreatedAt,
|
||||||
|
&u.UpdatedAt,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return u, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DBModel) EditUser(u User) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
stmt := `
|
||||||
|
UPDATE users
|
||||||
|
SET last_name = ?, first_name = ?, email = ?, updated_at = ?
|
||||||
|
WHERE id = ?;
|
||||||
|
`
|
||||||
|
|
||||||
|
_, err := m.DB.ExecContext(ctx, stmt, u.LastName, u.FirstName, u.Email, time.Now(), u.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DBModel) AddUser(u User, hash string) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
stmt := `
|
||||||
|
INSERT INTO users
|
||||||
|
(last_name, first_name, email, password, created_at, updated_at)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?);
|
||||||
|
`
|
||||||
|
|
||||||
|
_, err := m.DB.ExecContext(ctx, stmt,
|
||||||
|
u.LastName, u.FirstName, u.Email, hash, time.Now(), time.Now())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *DBModel) DeleteUser(id int) error {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
stmt := `
|
||||||
|
DELETE FROM users
|
||||||
|
WHERE id = ?;
|
||||||
|
`
|
||||||
|
|
||||||
|
_, err := m.DB.ExecContext(ctx, stmt, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
import { formatCurrency } from "./common.js"
|
import { formatCurrency, paginator } from "./common.js"
|
||||||
|
|
||||||
export function showTable(api) {
|
//TODO: This should be put into the localStorage if we click into a sale and
|
||||||
let token = localStorage.getItem("token");
|
//get back, we may want to stay at the same page before.
|
||||||
let tbody = document.getElementById("sales-table").getElementsByTagName("tbody")[0];
|
export let currentPage = 1;
|
||||||
|
|
||||||
|
export function showTable(api, ps, cp) {
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
const tbody = document.getElementById("sales-table").getElementsByTagName("tbody")[0];
|
||||||
|
|
||||||
|
// reset tbody
|
||||||
|
tbody.innerHTML = ``
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
page_size: parseInt(ps, 10),
|
||||||
|
page: parseInt(cp, 10),
|
||||||
|
};
|
||||||
|
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@ -11,17 +23,25 @@ export function showTable(api) {
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': 'Bearer ' + token,
|
'Authorization': 'Bearer ' + token,
|
||||||
},
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(api + "/api/admin/all-sales", requestOptions)
|
fetch(api + "/api/admin/all-sales", requestOptions)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
if (data) {
|
if (data.orders) {
|
||||||
data.forEach(function (i) {
|
data.orders.forEach(function (i) {
|
||||||
let newRow = tbody.insertRow();
|
let newRow = tbody.insertRow();
|
||||||
let newCell = newRow.insertCell();
|
let newCell = newRow.insertCell();
|
||||||
|
|
||||||
newCell.innerHTML = `<a href="/admin/sales/${i.id}">Order ${i.id}</a>`;
|
newCell.innerHTML = `<a href="#!">Order ${i.id}</a>`;
|
||||||
|
newCell.addEventListener("click", function (evt) {
|
||||||
|
// put the current_page into sessionStorage
|
||||||
|
sessionStorage.setItem("cur-page", data.current_page);
|
||||||
|
|
||||||
|
// redirect
|
||||||
|
location.href = `/admin/sales/${i.id}`;
|
||||||
|
});
|
||||||
|
|
||||||
newCell = newRow.insertCell();
|
newCell = newRow.insertCell();
|
||||||
let item = document.createTextNode(i.customer.last_name + ", " + i.customer.first_name);
|
let item = document.createTextNode(i.customer.last_name + ", " + i.customer.first_name);
|
||||||
@ -42,12 +62,14 @@ export function showTable(api) {
|
|||||||
} else {
|
} else {
|
||||||
newCell.innerHTML = `<span class="badge bg-success">Charged</span>`
|
newCell.innerHTML = `<span class="badge bg-success">Charged</span>`
|
||||||
}
|
}
|
||||||
|
paginator(api, data.last_page, data.current_page, showTable)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let newRow = tbody.insertRow();
|
let newRow = tbody.insertRow();
|
||||||
let newCell = newRow.insertCell();
|
let newCell = newRow.insertCell();
|
||||||
newCell.setAttribute("colspan", "4");
|
newCell.setAttribute("colspan", "5");
|
||||||
newCell.innerHTML = "No data available";
|
newCell.innerHTML = "No data available";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
import { formatCurrency } from "./common.js"
|
import { formatCurrency, paginator } from "./common.js"
|
||||||
|
|
||||||
export function showTable(api) {
|
export let currentPage = 1;
|
||||||
|
|
||||||
|
export function showTable(api, ps, cp) {
|
||||||
let token = localStorage.getItem("token");
|
let token = localStorage.getItem("token");
|
||||||
let tbody = document.getElementById("subscriptions-table").getElementsByTagName("tbody")[0];
|
let tbody = document.getElementById("subscriptions-table").getElementsByTagName("tbody")[0];
|
||||||
|
|
||||||
|
// reset tbody
|
||||||
|
tbody.innerHTML = ``
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
page_size: parseInt(ps, 10),
|
||||||
|
page: parseInt(cp, 10),
|
||||||
|
};
|
||||||
|
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: {
|
headers: {
|
||||||
@ -11,17 +21,25 @@ export function showTable(api) {
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': 'Bearer ' + token,
|
'Authorization': 'Bearer ' + token,
|
||||||
},
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(api + "/api/admin/all-subscriptions", requestOptions)
|
fetch(api + "/api/admin/all-subscriptions", requestOptions)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
if (data) {
|
if (data.orders) {
|
||||||
data.forEach(function (i) {
|
data.orders.forEach(function (i) {
|
||||||
let newRow = tbody.insertRow();
|
let newRow = tbody.insertRow();
|
||||||
let newCell = newRow.insertCell();
|
let newCell = newRow.insertCell();
|
||||||
|
|
||||||
newCell.innerHTML = `<a href="/admin/subscriptions/${i.id}">Order ${i.id}</a>`;
|
newCell.innerHTML = `<a href="#!">Order ${i.id}</a>`;
|
||||||
|
newCell.addEventListener("click", function (evt) {
|
||||||
|
// put the current_page into sessionStorage
|
||||||
|
sessionStorage.setItem("cur-page", data.current_page);
|
||||||
|
|
||||||
|
// redirect
|
||||||
|
location.href = `/admin/subscriptions/${i.id}`;
|
||||||
|
});
|
||||||
|
|
||||||
newCell = newRow.insertCell();
|
newCell = newRow.insertCell();
|
||||||
let item = document.createTextNode(i.customer.last_name + ", " + i.customer.first_name);
|
let item = document.createTextNode(i.customer.last_name + ", " + i.customer.first_name);
|
||||||
@ -42,6 +60,7 @@ export function showTable(api) {
|
|||||||
} else {
|
} else {
|
||||||
newCell.innerHTML = `<span class="badge bg-success">Charged</span>`
|
newCell.innerHTML = `<span class="badge bg-success">Charged</span>`
|
||||||
}
|
}
|
||||||
|
paginator(api, data.last_page, data.current_page, showTable)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let newRow = tbody.insertRow();
|
let newRow = tbody.insertRow();
|
||||||
|
36
static/js/all-users.js
Normal file
36
static/js/all-users.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
export function showUsers(api) {
|
||||||
|
const tbody = document.getElementById("user-table").getElementsByTagName("tbody")[0];
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
'Accept': `application/json`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer ' + token,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch(api + "/api/admin/all-users", requestOptions)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(function (data) {
|
||||||
|
if (data) {
|
||||||
|
data.forEach(i => {
|
||||||
|
let newRow = tbody.insertRow();
|
||||||
|
let newCell = newRow.insertCell();
|
||||||
|
|
||||||
|
newCell.innerHTML = `<a href="/admin/all-users/${i.id}">${i.last_name}, ${i.first_name}</a>`;
|
||||||
|
|
||||||
|
newCell = newRow.insertCell();
|
||||||
|
let item = document.createTextNode(i.email);
|
||||||
|
newCell.appendChild(item);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let newRow = tbody.insertRow();
|
||||||
|
let newCell = newRow.insertCell();
|
||||||
|
newCell.setAttribute("colspan", "2");
|
||||||
|
newCell.innerHTML = "no data available";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -3,6 +3,8 @@ export let stripe;
|
|||||||
const payButton = document.getElementById("pay-button");
|
const payButton = document.getElementById("pay-button");
|
||||||
export const processing = document.getElementById("processing-payment");
|
export const processing = document.getElementById("processing-payment");
|
||||||
|
|
||||||
|
export let pageSize = 2;
|
||||||
|
|
||||||
export function hidePayButton() {
|
export function hidePayButton() {
|
||||||
payButton.classList.add("d-none");
|
payButton.classList.add("d-none");
|
||||||
processing.classList.remove("d-none");
|
processing.classList.remove("d-none");
|
||||||
@ -98,3 +100,38 @@ export function formatCurrency(amount) {
|
|||||||
currency: "EUR",
|
currency: "EUR",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function paginator(api, pages, curPage, showTable) {
|
||||||
|
// Check the border case
|
||||||
|
if (curPage >= pages) {
|
||||||
|
curPage = pages
|
||||||
|
}
|
||||||
|
|
||||||
|
const p = document.getElementById("paginator")
|
||||||
|
let html = `<li class="page-item"><a href="#!" class="page-link pager" data-page="${curPage - 1}"><</a></li>`;
|
||||||
|
|
||||||
|
for (var i = 0; i < pages; i++) {
|
||||||
|
if (i + 1 == curPage) {
|
||||||
|
html += `<li class="page-item"><a href="#!" class="page-link pager active" data-page="${i + 1}">${i + 1}</a></li>`;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
html += `<li class="page-item"><a href="#!" class="page-link pager" data-page="${i + 1}">${i + 1}</a></li>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html += `<li class="page-item"><a href="#!" class="page-link pager" data-page="${curPage + 1}">></a></li>`;
|
||||||
|
|
||||||
|
p.innerHTML = html;
|
||||||
|
|
||||||
|
let pageBtns = document.getElementsByClassName("pager");
|
||||||
|
for (var j = 0; j < pageBtns.length; j++) {
|
||||||
|
pageBtns[j].addEventListener("click", function (evt) {
|
||||||
|
let desiredPage = evt.target.getAttribute("data-page");
|
||||||
|
if ((desiredPage > 0) && (desiredPage <= pages)) {
|
||||||
|
console.log("would go to page", desiredPage);
|
||||||
|
showTable(api, pageSize, desiredPage);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user