···44 * SPDX-License-Identifier: AGPL-3.0-only
55 */
6677-import { Header } from "../components/header.tsx";
88-import { Footer } from "../components/footer.tsx";
77+import { killSession, loginState } from "../components/loginForm.tsx";
98109const Home = () => {
1111- return (
1212- <>
1313- <Header />
1414- <main>
1515- <div id="main-headings">
1616- <h1>clippr</h1>
1717- <h2>social bookmarking for the AT Protocol</h2>
1818- </div>
1919-2020- <div id="content">
2121- <div id="main-content">
2222- <h3>what is clippr?</h3>
2323- <p>
2424- Clippr is an application based on the{" "}
2525- <a href="https://atproto.com">AT Protocol</a> that allows you to
2626- bookmark, organize and share links with your friends.
2727- </p>
2828- <h3>is this app ready yet?</h3>
2929- <p>
3030- While you can use it right now, the application is still in{" "}
3131- <i>heavy</i> development, and things will eventually break. We do
3232- not recommend using Clippr as your primary bookmarking tool until
3333- it is out of beta.
3434- </p>
3535- <h3>what is the AT Protocol?</h3>
3636- <p>
3737- The AT Protocol (or "ATproto" for short) is a decentralized social
3838- networking protocol designed to allow users to have a single,
3939- portable identity across multiple interoperable applications. It
4040- is used mainly by the microblogging app Bluesky, but anyone can
4141- build an application that uses the protocol, even if it isn't
4242- related to Bluesky.
4343- </p>
4444- <h3>
4545- what's different about clippr compared to [other social
4646- bookmarking app]?
4747- </h3>
4848- <p>
4949- The main difference between Clippr and other bookmarking
5050- application such as Pocket, Instapaper, Wallabag, Linkding or
5151- Pinboard is that your data isn't locked to a specific platform.
5252- Anyone can build an extension or application that is interoperable
5353- with Clippr's API and data structures (or any other application),
5454- and we encourage you to do so.
5555- <br />
5656- <br />
5757- All of our code is available as{" "}
5858- <a href="https://tangled.sh/@hexmani.ac/clippr">free software</a>,
5959- and we provide a{" "}
6060- <a href="https://www.npmjs.com/package/@clipprjs/lexicons">
6161- NPM package
6262- </a>{" "}
6363- to make it easier to develop with Clippr.
6464- </p>
6565- </div>
1010+ if (!loginState()) {
1111+ location.href = "/login";
1212+ }
66136767- <div id="sidebar">
6868- <div class="sidebar-item">
6969- <h3>log in</h3>
7070- <form>
7171- <label for="handle">Bluesky handle or DID</label>
7272- <input
7373- type="text"
7474- name="handle"
7575- id="handle"
7676- placeholder="clippr.social"
7777- />
7878- <button>log in</button>
7979- </form>
8080- <p>We can't create an account for you at the moment. Sorry :(</p>
8181- </div>
8282- <div class="sidebar-item">
8383- <h3>stats</h3>
8484- <h4>clips</h4>
8585- <p class="stat-counter">0</p>
8686- <h4>tags</h4>
8787- <p class="stat-counter">0</p>
8888- <h4>users</h4>
8989- <p class="stat-counter">0</p>
9090- </div>
9191- </div>
1414+ return (
1515+ <main>
1616+ <div id="content">
1717+ <div id="main-content" class="centered">
1818+ <h2>home</h2>
1919+ <p>OAuth!</p>
2020+ <button type="button" onClick={killSession}>
2121+ Log out
2222+ </button>
9223 </div>
9393- </main>
9494- <Footer />
9595- </>
2424+ </div>
2525+ </main>
9626 );
9727};
9828
+86
frontend/src/views/landingPage.tsx
···11+/*
22+ * clippr: a social bookmarking service for the AT Protocol
33+ * Copyright (c) 2025 clippr contributors.
44+ * SPDX-License-Identifier: AGPL-3.0-only
55+ */
66+77+import { LoginForm } from "../components/loginForm.tsx";
88+99+const LandingPage = () => {
1010+ return (
1111+ <>
1212+ <main>
1313+ <div id="main-headings">
1414+ <h1>clippr</h1>
1515+ <h2>social bookmarking for the AT Protocol</h2>
1616+ </div>
1717+1818+ <div id="content">
1919+ <div id="main-content">
2020+ <h3>what is clippr?</h3>
2121+ <p>
2222+ Clippr is an application based on the{" "}
2323+ <a href="https://atproto.com">AT Protocol</a> that allows you to
2424+ bookmark, organize and share links with your friends.
2525+ </p>
2626+ <h3>is this app ready yet?</h3>
2727+ <p>
2828+ While you can use it right now, the application is still in{" "}
2929+ <i>heavy</i> development, and things will eventually break. We do
3030+ not recommend using Clippr as your primary bookmarking tool until
3131+ it is out of beta.
3232+ </p>
3333+ <h3>what is the AT Protocol?</h3>
3434+ <p>
3535+ The AT Protocol (or "ATproto" for short) is a decentralized social
3636+ networking protocol designed to allow users to have a single,
3737+ portable identity across multiple interoperable applications. It
3838+ is used mainly by the microblogging app Bluesky, but anyone can
3939+ build an application that uses the protocol, even if it isn't
4040+ related to Bluesky.
4141+ </p>
4242+ <h3>
4343+ what's different about clippr compared to [other social
4444+ bookmarking app]?
4545+ </h3>
4646+ <p>
4747+ The main difference between Clippr and other bookmarking
4848+ application such as Pocket, Instapaper, Wallabag, Linkding or
4949+ Pinboard is that your data isn't locked to a specific platform.
5050+ Anyone can build an extension or application that is interoperable
5151+ with Clippr's API and data structures (or any other application),
5252+ and we encourage you to do so.
5353+ <br />
5454+ <br />
5555+ All of our code is available as{" "}
5656+ <a href="https://tangled.sh/@hexmani.ac/clippr">free software</a>,
5757+ and we provide a{" "}
5858+ <a href="https://www.npmjs.com/package/@clipprjs/lexicons">
5959+ NPM package
6060+ </a>{" "}
6161+ to make it easier to develop with Clippr.
6262+ </p>
6363+ </div>
6464+6565+ <div id="sidebar">
6666+ <div class="sidebar-item">
6767+ <h3>log in</h3>
6868+ <LoginForm />
6969+ </div>
7070+ <div class="sidebar-item">
7171+ <h3>stats</h3>
7272+ <h4>clips</h4>
7373+ <p class="stat-counter">0</p>
7474+ <h4>tags</h4>
7575+ <p class="stat-counter">0</p>
7676+ <h4>users</h4>
7777+ <p class="stat-counter">0</p>
7878+ </div>
7979+ </div>
8080+ </div>
8181+ </main>
8282+ </>
8383+ );
8484+};
8585+8686+export { LandingPage };
+29
frontend/src/views/login.tsx
···11+/*
22+ * clippr: a social bookmarking service for the AT Protocol
33+ * Copyright (c) 2025 clippr contributors.
44+ * SPDX-License-Identifier: AGPL-3.0-only
55+ */
66+77+import { LoginForm, loginState } from "../components/loginForm.tsx";
88+99+const Login = () => {
1010+ // TODO: Fix weird transition states
1111+ if (loginState()) {
1212+ location.href = "/home";
1313+ }
1414+1515+ return (
1616+ <>
1717+ <main>
1818+ <div id="content">
1919+ <div id="main-content" class="centered">
2020+ <h2>login</h2>
2121+ <LoginForm />
2222+ </div>
2323+ </div>
2424+ </main>
2525+ </>
2626+ );
2727+};
2828+2929+export { Login };
+25
frontend/src/views/notFound.tsx
···11+/*
22+ * clippr: a social bookmarking service for the AT Protocol
33+ * Copyright (c) 2025 clippr contributors.
44+ * SPDX-License-Identifier: AGPL-3.0-only
55+ */
66+77+const NotFound = () => {
88+ return (
99+ <>
1010+ <main>
1111+ <div id="content">
1212+ <div id="main-content" class="centered">
1313+ <h2>404 | page not found</h2>
1414+ <p>the party seems to be over...</p>
1515+ <a href="/">go home</a>
1616+ <br />
1717+ <br />
1818+ </div>
1919+ </div>
2020+ </main>
2121+ </>
2222+ );
2323+};
2424+2525+export { NotFound };
+17
frontend/src/vite-env.d.ts
···11+/*
22+ * clippr: a social bookmarking service for the AT Protocol
33+ * Copyright (c) 2025 clippr contributors.
44+ * SPDX-License-Identifier: AGPL-3.0-only
55+ */
66+77+interface ImportMetaEnv {
88+ readonly VITE_DEV_SERVER_PORT?: string;
99+ readonly VITE_CLIENT_URI: string;
1010+ readonly VITE_OAUTH_CLIENT_ID: string;
1111+ readonly VITE_OAUTH_REDIRECT_URI: string;
1212+ readonly VITE_OAUTH_SCOPE: string;
1313+}
1414+1515+interface ImportMeta {
1616+ readonly env: ImportMetaEnv;
1717+}