Skip to content

Commit 583511e

Browse files
committed
v3.4.0
1 parent eb8382f commit 583511e

6 files changed

Lines changed: 122 additions & 104 deletions

File tree

README.md

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### Your personal links hub
44

5-
[![Version](https://img.shields.io/badge/version-3.3.1-blue.svg)](https://github.com/paoloronco/Lynx)
5+
[![Version](https://img.shields.io/badge/version-3.4.0-blue.svg)](https://github.com/paoloronco/Lynx)
66

77
**Lynx** is an open-source, self-hosted link manager that helps you gather all your digital touchpoints in a single page, with secure authentication and a fully customizable design.
88

@@ -11,11 +11,11 @@
1111
# 📑 Table of Contents
1212

1313
1. [Lynx](#lynx)
14-
- [🧪 Demo](#-demo)
14+
- [🎥 Video](#-video)
15+
- [🧪 Demo](#-demo)
1516
- [✨ Features](#-features)
1617
- [🔒 Security Features](#-security-features)
1718
- [🛠 Tech Stack](#-tech-stack)
18-
- [🎥 Video](#-video)
1919
2. [🚀 Quick Start](#-quick-start)
2020
- [1. Clone, Install & Run](#1-clone-install--run)
2121
- [2. 🚀 Deploy on Railway](#2--deploy-on-railway)
@@ -25,6 +25,12 @@
2525
5. [👨‍💻 Developed With](#-developed-with)
2626
6. [📜 License](#-license)
2727

28+
---
29+
## 🎥 Video
30+
31+
#### Lynx Demo
32+
[![Watch the demo](./docs/demo.gif)](https://app.storylane.io/share/tjpm3tey6ven)
33+
2834
---
2935

3036
## 🧪 Demo
@@ -37,6 +43,7 @@
3743

3844
⚠️ The database resets automatically every 15 minutes.
3945

46+
---
4047

4148
## ✨ Features
4249

@@ -68,18 +75,11 @@
6875

6976
---
7077

71-
## 🎥 Video
72-
73-
#### Lynx Demo
74-
[![Watch the demo](./docs/demo.gif)](https://app.storylane.io/share/tjpm3tey6ven)
75-
76-
---
77-
7878
## 🚀 Quick Start
7979

8080
Credentials:
8181
User: `admin`
82-
Password: `ChangeMe123!`
82+
Password: `ChangeMe123!`
8383

8484
### 1. Clone, Install & Run
8585

@@ -95,8 +95,8 @@ Password: `ChangeMe123!`
9595
npm run start
9696
```
9797

98-
<p> Public → http://localhost:5173
99-
<p> Admin → http://localhost:5173/admin
98+
<p> Public → http://localhost:3001
99+
<p> Admin → http://localhost:3001/admin
100100

101101
### 2. 🚀 Deploy on Railway
102102

@@ -117,7 +117,7 @@ You can deploy **Lynx** on [Railway](https://railway.com) in a few steps:
117117

118118
### 3. 🚀 Other alternatives to deploy it:
119119

120-
- [Render] (https://render.com/)
120+
- [Render](https://render.com/)
121121
- [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform)
122122
- [Fly.io (Docker)](https://fly.io/docs/)
123123
- [Heroku (Container)](https://devcenter.heroku.com/articles/container-registry-and-runtime)
@@ -143,46 +143,38 @@ You can deploy **Lynx** on [Railway](https://railway.com) in a few steps:
143143

144144
## 📝 Changelog
145145

146-
### v3.3.1
146+
### v3.4.0
147147

148148
### 🔧 Admin
149-
- Updated title to: “Lynx – Your personal links hub”
150-
- **Profile**
151-
- Bio now supports **line breaks** (`whitespace-pre-line`)
149+
* Updated title to: “Lynx – Your personal links hub”
150+
* **Profile**
151+
* Bio now supports **line breaks** (`whitespace-pre-line`)
152152
- Empty bio is automatically hidden (no blank space left)
153153
- Social links are hidden when empty
154154
- Profile picture now displays correctly
155-
- **Links**
155+
* **Links**
156156
- Consistent text color applied across title, description, and URL
157157
- Improved Text Card rendering: Link name on the first line, URL on the second line (with horizontal scroll for long URLs)
158158
- Added support for image/emoji next to links
159+
- Added ability to insert either:
160+
* **Text Card** → full card with only text, entire card clickable via a single link
161+
* **Bulleted List** → list with a title and multiple links underneath
159162
- Option to export/import links as JSON
160163
- Bug fixes in rendering icons, removing cards, and updating links
161164
- Fixed bugs with icons, card removal, and link updates
162165
- Extended customization: choose font, size, and alignment for links
163-
- **Theme**
166+
* **Theme**
164167
- Removed duplicate “Content” tab (was redundant with name + bio)
165168
- Partially removed Typography tab → now integrated into Links and Profile sections for better UX
166169
- Export/Import now properly saves and restores themes
167-
- **UI**
170+
* **UI**
168171
- Updated footer to:
169172
`Powered by Lynx | Lynx - Your personal links hub`
170173

171-
172-
### 🚀 Demo
173-
- Demo is fully functional, but **password change is disabled**
174-
175-
176174
---
177175
## 📌 To-Do / Next Steps
178176

179177
### 🔧 Admin
180-
- **Links**
181-
- Bug fix: links fonts personalization (font type, dimensions, alignment)
182-
- Bug fix: Ability to center text and customize its alignment within cards
183-
- **Themes**
184-
- Further improvements to theme usability and customization
185-
- Enhanced personalization options for layouts, colors, and styles
186178
- **Code**
187179
- Code cleaning & refactoring: removing unnecessary parts, obsolete code, and unused dependencies (e.g., leftover Supabase or Firebase integrations).
188180

server/lynx.db-shm

0 Bytes
Binary file not shown.

server/lynx.db-wal

4.02 KB
Binary file not shown.

src/components/LinkManager.tsx

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useState } from "react";
22
import { Button } from "@/components/ui/button";
33
import { Card } from "@/components/ui/card";
4-
import { Plus, Link, Type, Upload, Download } from "lucide-react";
4+
import { Plus, Link, List, Type, Upload, Download } from "lucide-react";
55
import { LinkCard, LinkData } from "./LinkCard";
66
import { TextCard } from "./TextCard";
77
import { useToast } from "@/components/ui/use-toast";
@@ -56,6 +56,21 @@ export const LinkManager = ({ links, onLinksUpdate }: LinkManagerProps) => {
5656
setIsDirty(true);
5757
};
5858

59+
// Create a bulleted list text card (clickable list items)
60+
const addNewBulletedList = () => {
61+
const newListCard: LinkData = {
62+
id: Date.now().toString(),
63+
title: "New list",
64+
description: "",
65+
url: "",
66+
type: "text",
67+
textItems: [],
68+
};
69+
const updated = [...workingLinks, newListCard];
70+
setWorkingLinks(updated);
71+
setIsDirty(true);
72+
};
73+
5974
const updateLink = (updatedLink: LinkData) => {
6075
const updatedLinks = workingLinks.map(link =>
6176
String(link.id) === String(updatedLink.id) ? updatedLink : link
@@ -215,9 +230,8 @@ export const LinkManager = ({ links, onLinksUpdate }: LinkManagerProps) => {
215230

216231
return (
217232
<div className="space-y-4">
218-
<div className="flex items-center justify-between">
219-
<h2 className="text-xl font-semibold text-foreground">Your Content</h2>
220-
<div className="flex gap-2">
233+
<div className="flex flex-col gap-2">
234+
<div className="flex gap-2 justify-center flex-wrap">
221235
<Button
222236
onClick={addNewLink}
223237
variant="gradient"
@@ -226,14 +240,24 @@ export const LinkManager = ({ links, onLinksUpdate }: LinkManagerProps) => {
226240
<Link className="w-4 h-4" />
227241
Add Link
228242
</Button>
243+
<Button
244+
onClick={addNewBulletedList}
245+
variant="outline"
246+
className="gap-2"
247+
>
248+
<List className="w-4 h-4" />
249+
Add bulled list
250+
</Button>
229251
<Button
230252
onClick={addNewTextCard}
231253
variant="outline"
232254
className="gap-2"
233255
>
234256
<Type className="w-4 h-4" />
235-
Add Text
257+
Add Text Card
236258
</Button>
259+
</div>
260+
<div className="flex gap-2 justify-center flex-wrap">
237261
<Button onClick={handleSave} variant="default" className="gap-2" disabled={!isDirty || busy}>
238262
Save
239263
</Button>
@@ -261,9 +285,13 @@ export const LinkManager = ({ links, onLinksUpdate }: LinkManagerProps) => {
261285
<Link className="w-4 h-4 mr-2" />
262286
Add Link
263287
</Button>
288+
<Button onClick={addNewBulletedList} variant="outline">
289+
<List className="w-4 h-4 mr-2" />
290+
Add bulled list
291+
</Button>
264292
<Button onClick={addNewTextCard} variant="outline">
265293
<Type className="w-4 h-4 mr-2" />
266-
Add Text
294+
Add Text Card
267295
</Button>
268296
</div>
269297
</div>

src/components/PublicTextCard.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ export const PublicTextCard = ({ link }: PublicTextCardProps) => {
106106
<ul className="text-sm leading-relaxed space-y-2 mb-3" style={link.textColor ? { color: link.textColor } : undefined}>
107107
{link.textItems.map((item, index) => (
108108
<li key={index} className="flex">
109-
<span className="mr-2"></span>
109+
<span className="mr-2" style={{ color: item.textColor || link.textColor }}></span>
110110
<div className="flex-1 min-w-0">
111111
{/* Label on its own line */}
112-
<div>{item.text}</div>
112+
<div style={{ color: item.textColor || link.textColor, fontSize: item.fontSize || undefined, fontFamily: item.fontFamily || link.descriptionFontFamily || undefined }}>{item.text}</div>
113113
{/* URL on second indented line without wrapping */}
114114
{item.url && (
115115
<button
@@ -119,6 +119,7 @@ export const PublicTextCard = ({ link }: PublicTextCardProps) => {
119119
}}
120120
className="ml-6 block whitespace-nowrap overflow-x-auto hover:underline hover:text-primary transition-colors text-left"
121121
title={item.url}
122+
style={{ color: item.textColor || link.textColor }}
122123
>
123124
{item.url}
124125
</button>

0 commit comments

Comments
 (0)