Skip to content

Commit f78e47c

Browse files
committed
added pagination to site and started tracking connection requests
1 parent a8638f1 commit f78e47c

File tree

14 files changed

+330
-12
lines changed

14 files changed

+330
-12
lines changed

api/handlers/server/server.go

+76
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,22 @@ func Connect(c *gin.Context) {
270270
}
271271
}
272272

273+
var con models.Connection
274+
con.UserID = userID.(uint)
275+
con.ServerID = server.ID
276+
con.ServerCountry = server.Country
277+
if err := con.Create(); err != nil {
278+
logger.Log(logger.Fields{
279+
Loc: "/server/connect/:id - Connect()",
280+
Code: errors.InternalServerError.Code,
281+
Extra: map[string]interface{}{
282+
"UserID": con.UserID,
283+
"Detail": "Could not add connection request to db",
284+
},
285+
Err: err.Error(),
286+
})
287+
}
288+
273289
c.JSON(http.StatusOK, gin.H{
274290
"status": 200,
275291
"data": gin.H{
@@ -282,6 +298,66 @@ func Connect(c *gin.Context) {
282298

283299
}
284300

301+
// FreeConnect returns a username and password for the server
302+
func FreeConnect(c *gin.Context) {
303+
serverID, _ := strconv.ParseUint(c.Param("id"), 10, 64)
304+
var server models.Server
305+
server.ID = uint(serverID)
306+
if err := server.Find(); err != nil {
307+
logger.Log(logger.Fields{
308+
Loc: "/server/:id - Server()",
309+
Code: errors.ServerNotFound.Code,
310+
Extra: map[string]interface{}{"ConnID": c.Param("id")},
311+
Err: err.Error(),
312+
})
313+
c.AbortWithStatusJSON(errors.ServerNotFound.Status, errors.ServerNotFound)
314+
return
315+
}
316+
317+
c.JSON(http.StatusOK, gin.H{
318+
"status": 200,
319+
"data": gin.H{
320+
"username": server.Username,
321+
"password": server.Password,
322+
"port": server.Port,
323+
"ip": server.IP,
324+
},
325+
})
326+
327+
}
328+
329+
// Connections returns an array of all server connections
330+
func Connections(c *gin.Context) {
331+
offset, _ := strconv.Atoi(c.Query("offset"))
332+
var connections models.AllConnections
333+
if err := connections.FindAll(offset); err != nil {
334+
logger.Log(logger.Fields{
335+
Loc: "/servers - Connections()",
336+
Code: errors.InternalServerError.Code,
337+
Err: err.Error(),
338+
})
339+
c.AbortWithStatusJSON(errors.InternalServerError.Status, errors.InternalServerError)
340+
}
341+
342+
count, err := connections.Count()
343+
if err != nil {
344+
logger.Log(logger.Fields{
345+
Loc: "/servers - Connections()",
346+
Code: errors.InternalServerError.Code,
347+
Err: err.Error(),
348+
})
349+
c.AbortWithStatusJSON(errors.InternalServerError.Status, errors.InternalServerError)
350+
}
351+
352+
c.JSON(http.StatusOK, gin.H{
353+
"status": 200,
354+
"data": gin.H{
355+
"count": count,
356+
"connections": connections,
357+
},
358+
})
359+
}
360+
285361
// AllServers returns an array of all available servers
286362
func AllServers(c *gin.Context) {
287363
var servers models.AllServers

api/handlers/user/user.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,9 @@ func SignUpUser(c *gin.Context) {
470470

471471
// AllUsers returns an array of all user
472472
func AllUsers(c *gin.Context) {
473+
offset, _ := strconv.Atoi(c.Query("offset"))
473474
var users models.AllUsers
474-
475-
if err := users.FindAll(); err != nil {
475+
if err := users.FindAll(offset); err != nil {
476476
logger.Log(logger.Fields{
477477
Loc: "/plans - AllUsers()",
478478
Code: errors.InternalServerError.Code,
@@ -487,9 +487,20 @@ func AllUsers(c *gin.Context) {
487487
users[i] = u
488488
}
489489

490+
count, err := users.Count()
491+
if err != nil {
492+
logger.Log(logger.Fields{
493+
Loc: "/servers - Connections()",
494+
Code: errors.InternalServerError.Code,
495+
Err: err.Error(),
496+
})
497+
c.AbortWithStatusJSON(errors.InternalServerError.Status, errors.InternalServerError)
498+
}
499+
490500
c.JSON(http.StatusOK, gin.H{
491501
"status": 200,
492502
"data": gin.H{
503+
"count": count,
493504
"users": users,
494505
},
495506
})

api/models/connection.go

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package models
2+
3+
import (
4+
"time"
5+
6+
"github.com/jinzhu/gorm"
7+
)
8+
9+
type AllConnections []Connection
10+
11+
// Connections contains the email confirmation tokens with a one to one mapping
12+
// to the user
13+
type Connection struct {
14+
BaseModel
15+
UserID uint `json:"user_id"`
16+
ServerID uint `json:"server_id"`
17+
ServerCountry string `json:"server_country"`
18+
}
19+
20+
func (c *Connection) Find() error {
21+
if err := db().Where(&c).First(&c).Error; err != nil {
22+
return err
23+
}
24+
return nil
25+
}
26+
27+
func (c *Connection) GetUser() (*User, error) {
28+
var user User
29+
if err := db().Model(&user).Related(&c).Error; err != nil {
30+
return nil, err
31+
}
32+
return &user, nil
33+
}
34+
35+
func (c *Connection) Create() error {
36+
if err := db().Create(&c).Error; err != nil {
37+
return err
38+
}
39+
return nil
40+
}
41+
42+
func (c *Connection) Save() error {
43+
if err := db().Save(&c).Error; err != nil {
44+
return err
45+
}
46+
return nil
47+
}
48+
49+
func (c *Connection) Delete() error {
50+
if err := db().Delete(&c).Error; err != nil {
51+
return err
52+
}
53+
return nil
54+
}
55+
56+
func (ac *AllConnections) FindAll(offset int) error {
57+
limit := 20
58+
if err := db().Order("created_at desc").Limit(limit).Offset(offset).Find(&ac).Error; err != nil {
59+
return err
60+
}
61+
return nil
62+
}
63+
64+
func (ac *AllConnections) Count() (*int, error) {
65+
var count int
66+
if err := db().Model(&AllConnections{}).Count(&count).Error; err != nil {
67+
return nil, err
68+
}
69+
return &count, nil
70+
}
71+
72+
// BeforeCreate sets the CreatedAt column to the current time
73+
func (c *Connection) BeforeCreate(scope *gorm.Scope) error {
74+
scope.SetColumn("CreatedAt", time.Now())
75+
return nil
76+
}
77+
78+
// BeforeUpdate sets the UpdatedAt column to the current time
79+
func (c *Connection) BeforeUpdate(scope *gorm.Scope) error {
80+
scope.SetColumn("UpdatedAt", time.Now())
81+
return nil
82+
}

api/models/models.go

+1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ func Get() []interface{} {
2626
&Server{},
2727
&EmailToken{},
2828
&ForgotPassword{},
29+
&Connection{},
2930
}
3031
}

api/models/user.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,22 @@ func (u *User) CreateStripeCustomer() (*stripego.Customer, error) {
6262
return stripe.CreateCustomer(u.Email, u.FirstName, u.LastName, u.ID)
6363
}
6464

65-
func (au *AllUsers) FindAll() error {
66-
if err := db().Find(&au).Error; err != nil {
65+
func (au *AllUsers) FindAll(offset int) error {
66+
limit := 20
67+
if err := db().Order("created_at desc").Limit(limit).Offset(offset).Find(&au).Error; err != nil {
6768
return err
6869
}
6970
return nil
7071
}
7172

73+
func (au *AllUsers) Count() (*int, error) {
74+
var count int
75+
if err := db().Model(&AllUsers{}).Count(&count).Error; err != nil {
76+
return nil, err
77+
}
78+
return &count, nil
79+
}
80+
7281
// BeforeCreate sets the CreatedAt column to the current time
7382
// and encrypts the users password
7483
func (u *User) BeforeCreate(scope *gorm.Scope) error {

api/router/router.go

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func Init(logging bool) *gin.Engine {
9494
protected.POST("/servers/create", server.CreateServer)
9595
protected.PUT("/servers/update/:id", server.UpdateServer)
9696
protected.DELETE("/servers/delete/:id", server.DeleteServer)
97+
protected.GET("/server_connections", server.Connections)
9798
private.GET("/servers/connect/:id", server.Connect)
9899
private.GET("/servers", server.AllServers)
99100

site/components/Pagination.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Pagination from 'react-bootstrap/Pagination';
2+
import { useState } from 'react';
3+
4+
interface PaginationProps {
5+
count: number;
6+
pageLimit: number;
7+
handlePagination: (page_number: number) => void;
8+
}
9+
10+
const Pages: React.FC<PaginationProps> = ({ count, handlePagination, pageLimit }): JSX.Element => {
11+
const [activePage, setActivePage] = useState(1);
12+
const handleClick = (page: number) => {
13+
setActivePage(page);
14+
handlePagination(page);
15+
};
16+
const num_pages = Math.ceil(count / pageLimit);
17+
let items = [];
18+
for (let i = 1; i <= num_pages; i++) {
19+
items.push(
20+
<Pagination.Item onClick={() => handleClick(i)} key={i} active={i === activePage}>
21+
{i}
22+
</Pagination.Item>
23+
);
24+
}
25+
return <Pagination>{items}</Pagination>;
26+
};
27+
28+
export default Pages;

site/components/admin/AdminSidePanel.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ export default function AdminSidePanel(): JSX.Element {
2525
<a>Servers</a>
2626
</Link>
2727
</li>
28+
<li>
29+
<Link href="/admin/connections">
30+
<a>Connections</a>
31+
</Link>
32+
</li>
2833
<li>
2934
<Link href="/admin/settings">
3035
<a>Settings</a>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import Table from 'react-bootstrap/Table';
3+
import Connection from '../../../interfaces/connection';
4+
import dayjs from 'dayjs';
5+
import Router from 'next/router';
6+
7+
interface ConnTableProps {
8+
connections: Connection[];
9+
show: boolean;
10+
}
11+
12+
const ConnectionsTable: React.FC<ConnTableProps> = ({ connections, show }) => {
13+
if (!show) {
14+
return <div />;
15+
}
16+
return (
17+
<Table striped bordered hover responsive size="sm">
18+
<thead>
19+
<tr>
20+
<th>#</th>
21+
<th>Created</th>
22+
<th>User ID</th>
23+
<th>Server ID</th>
24+
<th>Country</th>
25+
</tr>
26+
</thead>
27+
<tbody className="table-admin-list">
28+
{connections.map(c => (
29+
<tr key={c.id}>
30+
<td>{c.id}</td>
31+
<td>
32+
{dayjs(c.createdAt)
33+
.format('DD-MM-YYYY H:mm')
34+
.toString()}
35+
</td>
36+
<td>{c.user_id}</td>
37+
<td>{c.server_id}</td>
38+
<td>{c.server_country}</td>
39+
</tr>
40+
))}
41+
</tbody>
42+
</Table>
43+
);
44+
};
45+
46+
export default ConnectionsTable;

site/hooks/useAsync.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const fetchError: Error = {
1313
detail: 'Something Went Wrong'
1414
};
1515

16-
export default function useAsync(makeRequestFunc: MakeRequestFunc) {
16+
export default function useAsync<T>(makeRequestFunc: MakeRequestFunc, dependency?: T[]) {
1717
const controller = new AbortController();
1818
const [data, setData] = useState();
1919
const [error, setError] = useState();
@@ -35,9 +35,15 @@ export default function useAsync(makeRequestFunc: MakeRequestFunc) {
3535
setloading(false);
3636
}
3737
}
38-
useEffect(() => {
39-
asyncCall();
40-
}, []);
38+
if (dependency) {
39+
useEffect(() => {
40+
asyncCall();
41+
}, [...dependency]);
42+
} else {
43+
useEffect(() => {
44+
asyncCall();
45+
}, []);
46+
}
4147

4248
return { data, loading, error };
4349
}

site/interfaces/connection.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default interface Connection {
2+
id: string;
3+
createdAt: string;
4+
updatedAt: string;
5+
server_id: number;
6+
user_id: number;
7+
server_country: string;
8+
}

0 commit comments

Comments
 (0)