-
Notifications
You must be signed in to change notification settings - Fork 2
/
home.mustache
162 lines (150 loc) · 6.88 KB
/
home.mustache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Twitter cards -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@oteecodes">
<meta name="twitter:creator" content="@oteecodes">
<meta name="twitter:title" content="Twirl | Shorten your Links">
<meta name="twitter:description"
content="Create, shorten and share links using Twirl. Keep a track of the number of times a link is clicked.">
<meta name="twitter:image" content="https://otee.dev/assets/images/Twirl_url_shortener.png">
<!-- Twitter cards -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<title>Twirl | Home</title>
</head>
<body>
<div class="container">
<header class="navbar navbar-expand flex-column flex-md-row bd-navbar">
<a class="navbar-brand mr-0 mr-md-2" href="/" aria-label="Bootstrap"> Twirl
</a>
<div class="navbar-nav-scroll">
<ul class="navbar-nav bd-navbar-nav flex-row">
<li class="nav-item">
<a class="nav-link " href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/logout">Logout</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://otee.dev" target="_blank" rel="noopener">Blog</a>
</li>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
</ul>
<a class="btn btn-bd-download d-none d-lg-inline-block mb-3 mb-md-0 ml-md-3"
href="https://twitter.com/oteecodes">By @otee</a>
</header>
<div class="row pt-md-5 pb-md-5 bg-light">
<div class="col-sm-2"> </div>
<div class="col-sm-8">
<div class="card">
<div class="card-body">
<h5 class="card-title">Twirl Link Shortener</h5>
<h6 class="card-subtitle mb-2 text-muted" id="responseDiv">Welcome, {{ username }}! Enter a link
to see the magic!</h6>
<form onsubmit="createLink(event)">
<div class="form-group">
<input type="text" class="form-control" name="longLink" id="longLinkID"
placeholder="Enter Link">
</div>
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-sm-2"> </div>
</div>
<div class="row pt-md-5 pb-md-5">
<div class="col-sm-12">
<div id="responseDiv"></div>
<div id="analyticsDiv" class="table-responsive">
</div><br>
</div>
</div>
</div>
</body>
<script>
async function createLink(event, ...args) {
event.preventDefault();
let value = document.getElementById("longLinkID").value;
let requestObj = JSON.stringify({ originalLink: value });
let res = await fetch('/l/shorten', { method: 'POST', headers: { "content-type": "application/json" }, body: requestObj }).then(res => res.json());
if (res.status) {
document.getElementById("responseDiv").innerHTML = `
${longLinkHref(value)} has been shortened to ${shortLinkHref(res.shortLink)} <br>
`
}
else {
document.getElementById("responseDiv").innerHTML = `
${longLinkHref(value)} is an invalid URL.<br>`
}
await analyticsGenerator();
}
function generateTableRow(
currentUsername, role, { original_link, accessed_count, short_link, enabled, username }) {
let extraRow = role === "admin" ? `<td style="text-align:center">${username}</td>` : ``;
let toggleButton = `<a href="#" onclick="return updateStatus('${short_link}', ${enabled})">Toggle</a></td>`;
if (role === "admin" && username !== currentUsername) {
toggleButton = "";
}
return `
<tr>
${extraRow}
<td style="text-align:center">${longLinkHref(original_link)} </td>
<td style="text-align:center">${shortLinkHref(short_link)} </td>
<td style="text-align:center">${accessed_count}</td>
<td style="text-align:center"> ${enabled ? "Live" : "Disabled"}   
${toggleButton}
</tr>
`
}
function generateHeaderRow(role) {
let extraRow = role === "admin" ? `<th style="text-align:center" scope="col">User</th>` : "";
return `<tr>
${extraRow}
<th style="text-align:center" scope="col">Original Link</th>
<th style="text-align:center" scope="col">Short Link </th>
<th style="text-align:center" scope="col">Acccesed Count </th>
<th style="text-align:center" scope="col">Action </th>
</tr>`;
}
async function analyticsGenerator() {
let res = await fetch('/analytics', { method: "GET", headers: { "content-type": "application/json" } })
.then(res => res.json());
let resTable = res.data.map((row) => generateTableRow(res.userName, res.userRole, row)).join(' ');
let headerRow = generateHeaderRow(res.userRole);
document.getElementById("analyticsDiv").innerHTML = `<table class="table table-striped"> ${headerRow} ${resTable} </table>`
};
analyticsGenerator();
setInterval(analyticsGenerator, 30000);
function shortLinkHref(link) {
let finalLink = window.location.protocol + "//" + window.location.host + link;
return `<a href='${link}' target='_blank'> ${finalLink}<a/>`;
}
function longLinkHref(link) {
let truncatedLink = link;
if (link.length > 35) {
truncatedLink = link.substring(0, 32) + '...';
}
return `<a href='${link}' target='_blank'> ${truncatedLink}<a/>`
}
async function updateStatus(link, currentStatus) {
link = link.substring(3);
if (currentStatus) {
await fetch(`/l/disable/${link}`, { method: "POST" });
}
else {
await fetch(`/l/enable/${link}`, { method: "POST" });
}
await analyticsGenerator();
}
</script>
</html>