social bookmarking for atproto

[web] add more pages, flesh out some stuff

penny c24c8a80 648cb4d2

+184 -29
+6
frontend/astro.config.mts
··· 1 + /* 2 + * clippr: a social bookmarking service for the AT Protocol 3 + * Copyright (c) 2025 clippr contributors. 4 + * SPDX-License-Identifier: AGPL-3.0-only 5 + */ 6 + 1 7 // @ts-check 2 8 import { defineConfig } from 'astro/config'; 3 9
+3
frontend/pnpm-workspace.yaml
··· 1 + onlyBuiltDependencies: 2 + - esbuild 3 + - sharp
frontend/public/images/404.png

This is a binary file and will not be displayed.

+2 -2
frontend/src/components/Clip.astro
··· 1 1 --- 2 2 import TagList from "./TagList.astro"; 3 - const { title, tagList, link, description, originalClipper } = Astro.props; 3 + const { title, tagList, link, description, originalClipper, firstClipDate } = Astro.props; 4 4 --- 5 5 <div class="clip"> 6 6 <div class="clip-head"> ··· 13 13 <a href="#">clip</a> 14 14 <a href="#">respond</a> 15 15 <a href="#">hide</a> 16 - <span class="original-clipper">[first clipped by <a href="#">@{originalClipper}</a>]</span> 16 + <span class="original-clipper">[first clipped by <a href="#">@{originalClipper}</a> {firstClipDate} ago]</span> 17 17 </div> 18 18 </div>
+5
frontend/src/layouts/Base.astro
··· 3 3 import '../styles/main.css'; 4 4 --- 5 5 <!doctype html> 6 + <!-- 7 + * clippr: a social bookmarking service for the AT Protocol 8 + * Copyright (c) 2025 clippr contributors. 9 + * SPDX-License-Identifier: AGPL-3.0-only 10 + --> 6 11 <html lang="en"> 7 12 <head> 8 13 <meta charset="UTF-8"/>
+13
frontend/src/layouts/Footer.astro
··· 5 5 shoutout popbob! | © 2025 clippr contributors | <a href="https://tangled.sh/@noob.quest/clippr">source code</a> 6 6 </small> 7 7 </footer> 8 + 9 + <style> 10 + footer { 11 + background-color: #ddd; 12 + padding: 1em 0; 13 + color: black; 14 + text-align: center; 15 + 16 + a { 17 + color: revert; 18 + } 19 + } 20 + </style>
+32
frontend/src/pages/404.astro
··· 1 + --- 2 + import Base from "../layouts/Base.astro"; 3 + import Header from "../layouts/Header.astro"; 4 + import Footer from "../layouts/Footer.astro"; 5 + --- 6 + <Base title="404"> 7 + <Header/> 8 + <main class="404-page"> 9 + <h2>404 | page not found</h2> 10 + <p>the party seems to be over...</p> 11 + <a href="/">« go home</a> 12 + </main> 13 + <Footer/> 14 + </Base> 15 + 16 + <style> 17 + main { 18 + display: flex !important; 19 + flex-direction: column !important; 20 + gap: 0.1rem; 21 + align-items: center; 22 + justify-content: center; 23 + } 24 + 25 + h2, p { 26 + margin: 0.5rem 0; 27 + } 28 + 29 + a { 30 + color: revert; 31 + } 32 + </style>
+12
frontend/src/pages/about.astro
··· 1 + --- 2 + import Base from "../layouts/Base.astro"; 3 + import Header from "../layouts/Header.astro"; 4 + import Footer from "../layouts/Footer.astro"; 5 + --- 6 + <Base title="about"> 7 + <Header/> 8 + <main> 9 + <p>Fill in later!</p> 10 + </main> 11 + <Footer/> 12 + </Base>
+2 -1
frontend/src/pages/index.astro
··· 12 12 <div id="clip-list"> 13 13 <Clip title="google" link="https://google.com" tagList="technology,search,google" 14 14 description="tests woah" 15 - originalClipper="popbob.com"/> 15 + originalClipper="popbob.com" firstClipDate="30m"/> 16 16 </div> 17 17 </div> 18 18 <div id="sidebar"> ··· 20 20 <p>clippr is a bookmarking site that doubles as a news aggregator.</p> 21 21 <p>using your bookmarks (or "clips") and their associated tags, a constantly updated news feed is 22 22 created based on what users are clipping to their collection.</p> 23 + <a href="/about">learn more »</a> 23 24 </SidebarItem> 24 25 <SidebarItem title="stats"> 25 26 <h3>clips</h3>
+85 -2
frontend/src/pages/login.astro
··· 6 6 <Base title="login"> 7 7 <Header/> 8 8 <main> 9 - 9 + <div id="oauth-login"> 10 + <h2>log in</h2> 11 + <p>Enter your Bluesky handle.</p> 12 + <form> 13 + <label for="handle">handle</label> 14 + <input type="text" id="handle" name="handle" placeholder="handle"> 15 + <input type="submit" value="Authenticate"> 16 + </form> 17 + </div> 18 + <!--<p id="or">or...</p>--> 19 + <!--<div id="bluesky-login">--> 20 + <!-- <h2>use your bluesky account</h2>--> 21 + <!-- <button id="bluesky-login-button">login to bluesky</button>--> 22 + <!--</div>--> 10 23 </main> 11 24 <Footer/> 12 - </Base> 25 + </Base> 26 + 27 + <style> 28 + main { 29 + display: flex !important; 30 + flex-direction: column; 31 + align-items: center; 32 + justify-content: center; 33 + gap: 1rem; 34 + } 35 + 36 + form { 37 + display: flex; 38 + flex-direction: column; 39 + justify-content: center; 40 + 41 + label { 42 + text-align: center; 43 + font-weight: bold; 44 + margin-bottom: 0.5rem; 45 + } 46 + 47 + input[type="submit"] { 48 + margin: 1rem 0 0 0; 49 + padding: 0.5rem 0; 50 + width: 50%; 51 + align-self: center; 52 + } 53 + } 54 + 55 + a { 56 + color: revert; 57 + } 58 + 59 + #or { 60 + border: 2px black solid; 61 + padding: 0.5rem 2rem; 62 + margin: 0; 63 + font-weight: bold; 64 + } 65 + 66 + h2 { 67 + text-align: center; 68 + } 69 + 70 + #bluesky-login { 71 + display: flex; 72 + flex-direction: column; 73 + justify-content: center; 74 + align-items: center; 75 + 76 + h2 { 77 + margin: 1rem 0; 78 + margin-top: 0; 79 + } 80 + } 81 + 82 + #bluesky-login-button { 83 + background: linear-gradient(deepskyblue, lightskyblue); 84 + border: none; 85 + border-radius: 10px; 86 + font-weight: bold; 87 + padding: 1rem 2rem; 88 + } 89 + 90 + #bluesky-login-button:hover { 91 + cursor: pointer; 92 + filter: brightness(90%); 93 + transition: filter 0.3s ease-in-out; 94 + } 95 + </style>
+24 -24
frontend/src/styles/main.css
··· 112 112 } 113 113 114 114 .clip-tags * { 115 - background: #adc6ff !important; 115 + background: linear-gradient(#ffe076, #fff0cb) !important; 116 116 padding: 0.25rem; 117 117 margin: 0 0.25rem !important; 118 118 border-radius: 0.34rem; ··· 138 138 margin: 0 1rem; 139 139 } 140 140 141 - .sidebar-item { 142 - padding: 0.5rem 0; 143 - 144 - h2 { 145 - margin: 0.5rem 0; 146 - } 147 - } 148 - 149 - .sidebar-item:first-of-type { 150 - padding-top: 0; 151 - 152 - h2 { 153 - margin-top: 0; 154 - } 155 - } 156 - 157 - 158 141 .sidebar-content { 159 142 background-color: #bbbbbb; 160 143 display: flex; ··· 171 154 } 172 155 } 173 156 157 + .sidebar-item { 158 + padding: 0.5rem 0; 174 159 175 - footer { 176 - background-color: #ddd; 177 - padding: 1em 0; 178 - color: black; 179 - text-align: center; 160 + h2 { 161 + margin: 0.5rem 0; 162 + } 180 163 181 164 a { 165 + align-self: start; 182 166 color: revert; 167 + padding: 0.5rem 0.5rem; 183 168 } 184 - } 169 + 170 + a:hover { 171 + font-style: revert; 172 + text-decoration: underline; 173 + } 174 + } 175 + 176 + .sidebar-item:first-of-type { 177 + padding-top: 0; 178 + 179 + h2 { 180 + margin-top: 0; 181 + } 182 + } 183 + 184 +