+34
app/.gitignore
+34
app/.gitignore
···
1
+
# dependencies (bun install)
2
+
node_modules
3
+
4
+
# output
5
+
out
6
+
dist
7
+
*.tgz
8
+
9
+
# code coverage
10
+
coverage
11
+
*.lcov
12
+
13
+
# logs
14
+
logs
15
+
_.log
16
+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
17
+
18
+
# dotenv environment variable files
19
+
.env
20
+
.env.development.local
21
+
.env.test.local
22
+
.env.production.local
23
+
.env.local
24
+
25
+
# caches
26
+
.eslintcache
27
+
.cache
28
+
*.tsbuildinfo
29
+
30
+
# IntelliJ based IDEs
31
+
.idea
32
+
33
+
# Finder (MacOS) folder config
34
+
.DS_Store
+15
app/README.md
+15
app/README.md
+116
app/src/settings-page/signup.css
+116
app/src/settings-page/signup.css
···
1
+
body {
2
+
font-family: system-ui, sans-serif;
3
+
background: #f9fafb;
4
+
display: flex;
5
+
align-items: center;
6
+
justify-content: center;
7
+
height: 100vh;
8
+
margin: 0;
9
+
}
10
+
11
+
.card {
12
+
max-width: 90%;
13
+
background: white;
14
+
border: 1px solid #d1d5db;
15
+
border-radius: 8px;
16
+
padding: 1.5rem;
17
+
box-sizing: border-box;
18
+
}
19
+
20
+
.header {
21
+
text-align: center;
22
+
margin-bottom: 1.5rem;
23
+
}
24
+
25
+
.icon-circle {
26
+
width: 64px;
27
+
height: 64px;
28
+
background: #dbeafe;
29
+
border-radius: 50%;
30
+
display: flex;
31
+
align-items: center;
32
+
justify-content: center;
33
+
margin: 0 auto 1rem;
34
+
}
35
+
36
+
.icon-circle img {
37
+
width: 32px;
38
+
height: 32px;
39
+
}
40
+
41
+
h1 {
42
+
font-size: 1.5rem;
43
+
}
44
+
45
+
p {
46
+
font-size: 0.9rem;
47
+
color: #6b7280;
48
+
}
49
+
50
+
.actions {
51
+
display: flex;
52
+
flex-direction: column;
53
+
gap: 1rem;
54
+
}
55
+
56
+
label {
57
+
display: block;
58
+
font-size: 0.85rem;
59
+
font-weight: 600;
60
+
margin-bottom: 0.25rem;
61
+
}
62
+
63
+
input {
64
+
width: 100%;
65
+
padding: 0.5rem 0.75rem;
66
+
border: 1px solid #d1d5db;
67
+
border-radius: 4px;
68
+
font-size: 0.95rem;
69
+
box-sizing: border-box;
70
+
}
71
+
72
+
input:focus {
73
+
outline: none;
74
+
border-color: #2563eb;
75
+
}
76
+
77
+
button {
78
+
width: 100%;
79
+
padding: 0.6rem;
80
+
font-size: 0.95rem;
81
+
border-radius: 4px;
82
+
cursor: pointer;
83
+
/*transition: background 0.2s ease;*/
84
+
display: flex;
85
+
align-items: center;
86
+
justify-content: center;
87
+
}
88
+
89
+
.btn-primary {
90
+
background: #2563eb;
91
+
color: white;
92
+
border: none;
93
+
}
94
+
95
+
.btn-primary:hover {
96
+
background: #1d4ed8;
97
+
}
98
+
99
+
.btn-qr {
100
+
background: white;
101
+
gap: 0.5rem;
102
+
border: 1px solid #d1d5db;
103
+
}
104
+
105
+
.btn-qr:hover {
106
+
background: #f3f4f6;
107
+
}
108
+
109
+
.btn-qr img {
110
+
width: 16px;
111
+
height: 16px;
112
+
}
113
+
114
+
.hint {
115
+
font-size: 0.75rem;
116
+
}
+42
app/src/settings-page/signup.html
+42
app/src/settings-page/signup.html
···
1
+
<!doctype html>
2
+
<html lang="en">
3
+
<head>
4
+
<meta charset="UTF-8" />
5
+
<script type="module" src="./signup.ts"></script>
6
+
<link rel="stylesheet" href="./signup.css" />
7
+
</head>
8
+
9
+
<body>
10
+
<div class="card">
11
+
<div class="header">
12
+
<div class="icon-circle">
13
+
<img src="/src/assets/pin.svg" alt="Pin Icon" />
14
+
</div>
15
+
<h1>PrivacyPin</h1>
16
+
<p>Connect with a server to start sharing</p>
17
+
</div>
18
+
19
+
<!-- x-data connects this element to the signupPageState Alpine component, enabling its data (serverAddress and signupKey) and functions (signup and scanQR) to work within it :) -->
20
+
<!-- TODO: make this a form instead? -->
21
+
<div class="actions" x-data="signupPageState">
22
+
<div>
23
+
<label for="server">Server Address</label>
24
+
<input id="server" type="url" placeholder="https://your-server.com" x-model="serverAddress" required />
25
+
</div>
26
+
27
+
<div>
28
+
<label for="key">Signup Key</label>
29
+
<input id="key" type="password" placeholder="Enter your signup key" x-model="signupKey" required />
30
+
</div>
31
+
32
+
<p class="hint">Scan a QR code to automatically fill both server address and signup key</p>
33
+
<button type="button" x-bind:disabled="isDoingStuff" class="btn-qr" @click="await scanQR()">
34
+
<img src="/src/assets/qr.svg" alt="QR Icon" />
35
+
Scan QR Code
36
+
</button>
37
+
38
+
<button class="btn-primary" x-bind:disabled="isDoingStuff" @click="await signup()"><span x-show="isDoingStuff">Connecting...</span> <span x-show="!isDoingStuff">Connect</span></button>
39
+
</div>
40
+
</div>
41
+
</body>
42
+
</html>
+11
app/src/settings-page/signup.ts
+11
app/src/settings-page/signup.ts