Self-hosted, federated location sharing app and server that prioritizes user privacy and security
end-to-end-encryption
location-sharing
privacy
self-hosted
federated
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <script type="module" src="./home.ts"></script>
6 <link rel="stylesheet" href="../app.css" />
7 </head>
8
9 <body>
10 <div class="app" x-data="homePageState">
11 <!-- Header -->
12 <header style="justify-content: space-between">
13 <strong>PrivacyPin</strong>
14 <div>
15 <button class="icon-btn" @click="updateServer()">
16 <img
17 class="svg-icon"
18 src="/src/assets/paperplane.svg"
19 alt="Paperplane Flying Icon"
20 />
21 </button>
22 <button class="icon-btn" @click="addFriend()">
23 <img
24 class="svg-icon"
25 src="/src/assets/user+.svg"
26 alt="Friend Add Icon"
27 />
28 </button>
29 <button class="icon-btn" @click="openSettings()">
30 <img
31 class="svg-icon"
32 src="/src/assets/setting.svg"
33 alt="Settings Icon"
34 />
35 </button>
36 </div>
37 </header>
38
39 <!-- Status -->
40 <div class="status">
41 <span>Last ping sent:</span>
42 <!-- later, figure out how to update this cleanly when we will have the actual data -->
43 <span x-text="timeAgo()"></span>
44 </div>
45
46 <!-- Friends -->
47 <div class="content">
48 <div class="friends-header">
49 <h2 style="font-size: 1rem; margin: 0">Friends</h2>
50 <span style="color: #6b7280; font-size: 0.9rem"
51 >(<span x-text="friends.length"></span>)</span
52 >
53 </div>
54 <!--TODO idk why but sometimes when i launch the app I see the stuff when you have no friends for a split second before I see them appear, even tho we get them in init -->
55 <template x-if="friends.length > 0">
56 <div>
57 <template x-for="friend in friends" :key="friend.id">
58 <div class="friend-card">
59 <strong x-text="friend.name"></strong>
60 <div class="friend-actions">
61 <button
62 class="view-btn"
63 @click="viewLocation(friend.id)"
64 >
65 <img
66 class="svg-icon"
67 src="/src/assets/pin-location.svg"
68 alt="Pin Icon"
69 />View
70 </button>
71
72 <button
73 class="icon-btn"
74 style="
75 margin-bottom: auto;
76 padding-right: 0px;
77 "
78 @click="friendOptions(friend.id)"
79 >
80 <img
81 class="svg-icon"
82 style="size: 16px"
83 src="/src/assets/ellipsis-vertical.svg"
84 alt="Multiple Users Icon"
85 />
86 </button>
87 </div>
88 </div>
89 </template>
90 </div>
91 </template>
92
93 <template x-if="friends.length === 0">
94 <div class="empty-state">
95 <img
96 class="svg-icon"
97 src="/src/assets/user-multiple.svg"
98 alt="Go Back Icon"
99 />
100 <h3>No friends yet</h3>
101 <p>Add friends to start sharing locations</p>
102 <button
103 class="primary"
104 style="width: auto"
105 @click="addFriend()"
106 >
107 Add Friend
108 </button>
109 </div>
110 </template>
111 </div>
112
113 <!-- Admin -->
114 <div x-show="is_admin">
115 <div class="content" style="text-align: center">
116 <h4>Admin Controls:</h4>
117 <div style="display: flex; justify-content: center">
118 <button
119 class="secondary"
120 style="width: auto"
121 @click="generateSignupKey()"
122 >
123 Generate signup key
124 </button>
125 </div>
126 <div
127 style="display: flex; justify-content: center"
128 x-show="newSignupKey != ''"
129 >
130 <p style="margin-top: 2.5%">
131 New signup key: <a x-text="newSignupKey"></a>
132 </p>
133 </div>
134 </div>
135 </div>
136 </div>
137 </body>
138</html>