Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkInBio template with LaunchDarkly integration #272

Merged
merged 12 commits into from
Oct 22, 2024
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"main"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we ignore this file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or delete it even?

]
}
6 changes: 6 additions & 0 deletions linkinbio/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.db
*.py[cod]
.env
.web
__pycache__/
assets/external/
90 changes: 90 additions & 0 deletions linkinbio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Link in Bio App
This application is built using Reflex.dev, a powerful framework for creating interactive web applications using pure Python. This app allows you to showcase your online presence with a customizable link in bio page.

## Features

- **Customizable Links**: Easily add links to your personal website, Twitter, GitHub, LinkedIn, and more.
- **Responsive Design**: The app is designed to look great on both desktop and mobile devices.
- **Stylish UI**: Uses a vibrant gradient background and modern UI components.

## Installation

To get started with this project follow these steps:

### Prerequisites

- Python 3.7 or higher
- pip (Python package manager)

### Steps

1. **Clone the Repository**

Clone the repository to your local machine using the following command:

```bash
git clone https://github.com/reflex-dev/reflex-examples
cd reflex-examples/linkinbio
```
2. **Install Dependencies**

Install the required Python packages using pip:

```bash
pip install -r requirements.txt
```

The `requirements.txt` file specifies the necessary Reflex version:
```plaintext:linkinbio/requirements.txt
startLine: 1
endLine: 2
```



3. **Run the Application**

Start the application using the following command:
```bash
reflex run
```

The app will be accessible at `http://localhost:3000` by default.

## Project Structure

- **linkinbio.py**: Contains the main application logic, including the `link_button` and `index` functions.
```python:linkinbio/linkinbio/linkinbio.py
startLine: 1
endLine: 57
```

- **style.py**: Defines the styling for the app components, including buttons, links, and layout.
```python:linkinbio/linkinbio/style.py
startLine: 1
endLine: 55
```

- **rxconfig.py**: Configuration file for the Reflex app.
```python:linkinbio/rxconfig.py
startLine: 1
endLine: 5
```

- **.gitignore**: Specifies files and directories to be ignored by Git.
```plaintext:linkinbio/.gitignore
startLine: 1
endLine: 6
```

## Customization

You can customize the links and personal information by editing the `index` function in `linkinbio.py`. Update the `name`, `bio`, `avatar_url`, and `links` list to reflect your personal details.

## Contributing

Contributions are welcome! Please fork the repository and submit a pull request for any improvements or bug fixes.

## Contact

This template was created by @erinmikailstaples (https://github.com/erinmikailstaples). Feel free to reach out for any quesitons, feedback, or collaboration opportunities.
Binary file added linkinbio/assets/favicon.ico
Binary file not shown.
Empty file added linkinbio/linkinbio/__init__.py
Empty file.
202 changes: 202 additions & 0 deletions linkinbio/linkinbio/linkinbio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import reflex as rx
from linkinbio.style import *

# add launchdarkly imports
import ldclient
from ldclient.config import Config
from ldclient import Context, LDClient
import os

# Initialize LD client (this should be done once, typically at app startup)
SDK_KEY: str | None = os.getenv("LD_SDK_KEY", None)

LD_CLIENT: LDClient | None = None
LD_CONTEXT: Context | None = None
if SDK_KEY is not None:
ldclient.set_config(Config(SDK_KEY))
LD_CLIENT = ldclient.get()

COUNTER = 0

class State(rx.State):

# Create a LaunchDarkly context (formerly known as "user")
ld_context_set: bool = False
updating: bool = False

def build_ld_context(
self,
context_key: str = "context-key-abc-123",
context_name: str = "linkinbio-app",
) -> None:
global LD_CONTEXT
if LD_CLIENT is None:
return

LD_CONTEXT = (
Context.builder(
context_key,
)
.name(
context_name,
)
.build()
)
self.ld_context_set = True

@rx.var
def get_feature_flag_bool(
self,
feature_flag_key: str = "toggle-bio",
) -> bool:
global COUNTER
if not self.ld_context_set:
return False

flag_value: bool = LD_CLIENT.variation(
key=feature_flag_key,
context=LD_CONTEXT,
default=False,
)
COUNTER += 1
return flag_value

def on_update(self, date: str,):
print(f"{COUNTER} :: {date}")


def link_button(
name: str,
url: str,
icon: str,
) -> rx.Component:
icon_map = {
"globe": "globe",
"twitter": "twitter",
"github": "github",
"linkedin": "linkedin",
}
icon_tag = icon_map.get(
icon.lower(),
"link",
)
return rx.link(
rx.button(
rx.icon(
tag=icon_tag,
),
name,
width="100%",
),
href=url,
is_external=True,
)


def index_content(
name: str,
pronouns: str,
bio: str,
avatar_url: str,
links: list[dict[str, str]],
background: str,
):
return rx.center(
rx.vstack(
rx.avatar(
src=avatar_url,
size="2xl",
),
rx.heading(
name,
size="lg",
),
rx.text(
pronouns,
font_size="sm",
),
rx.text(bio),
rx.vstack(
rx.foreach(
links,
lambda link: link_button(link["name"], link["url"], link["icon"]),
),
width="100%",
spacing="2",
),
padding="4",
max_width="400px",
width="100%",
spacing="3",
),
width="100%",
height="100vh",
background=background,
)


def index() -> rx.Component:
return rx.fragment(
rx.cond(
State.get_feature_flag_bool,
index_content(
name="Bio Page if True",
pronouns="dub.link/pronouns",
bio="insert bio here",
avatar_url="https://avatars.githubusercontent.com/<your_username_here>",
links=[
{"name": "Website", "url": "https://www.google.com"},
{"name": "Upcoming Events", "url": "lu.ma/launchdarkly"},
{"name": "Instagram", "url": "https://instagram.com/qtotherescue"},
{
"name": "Another Link here",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
},
],
background="linear-gradient(45deg, #FFD700, #FF8C00, #FF4500)",
),
index_content(
name="Bio Page if False",
pronouns="dub.link/pronouns",
bio="< insert bio here >",
avatar_url="https://avatars.githubusercontent.com/<your_username_here>",
links=[
{
"name": "Website",
"url": "https://reflex.dev",
"icon": "globe",
},
{
"name": "Twitter",
"url": "https://twitter.com/getreflex",
"icon": "twitter",
},
{
"name": "GitHub",
"url": "https://github.com/reflex-dev/reflex-examples",
"icon": "github",
},
{
"name": "LinkedIn",
"url": "https://www.linkedin.com/company/reflex-dev",
"icon": "linkedin",
},
],
background="radial-gradient(circle, var(--chakra-colors-purple-100), var(--chakra-colors-blue-100))",
),
),
rx.moment(
interval=3000,
on_change=State.on_update,
format="HH:mm:ss",
),
)


app = rx.App(
style=style,
)
app.add_page(
index,
on_load=State.build_ld_context,
)
56 changes: 56 additions & 0 deletions linkinbio/linkinbio/style.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import reflex as rx

# Define a vibrant gradient background
background_gradient = "linear-gradient(45deg, #FF6B6B, #4ECDC4, #45B7D1, #7E57C2)"

style = {
"font_family": "Inter, sans-serif",
"background": background_gradient,
"min_height": "100vh", # Ensure the gradient covers the full height of the viewport
rx.avatar: {
"border": "4px solid white",
"box_shadow": "lg",
"margin_top": "0.25em",
},
rx.button: {
"width": "100%",
"height": "3em",
"padding": "0.5em 1em",
"border_radius": "full",
"color": "white",
"background_color": "rgba(0, 0, 0, 0.5)", # Semi-transparent black
"backdrop_filter": "blur(10px)",
"white_space": "nowrap",
"box_shadow": "0 4px 6px rgba(0, 0, 0, 0.1)",
"transition": "all 0.3s ease",
"_hover": {
"transform": "translateY(-2px)",
"box_shadow": "0 6px 8px rgba(0, 0, 0, 0.15)",
"background_color": "rgba(0, 0, 0, 0.7)", # Darker on hover
},
},
rx.link: {
"text_decoration": "none",
"_hover": {
"text_decoration": "none",
},
},
rx.vstack: {
"background": "rgba(255, 255, 255, 0.9)",
"backdrop_filter": "blur(20px)",
"border_radius": "20px",
"padding": "1em",
"box_shadow": "0 4px 16px rgba(0, 0, 0, 0.1)",
"color": "black",
"align_items": "center",
"text_align": "center",
},
rx.heading: {
"color": "black",
"margin_bottom": "0.25em",
},
rx.text: {
"color": "black",
"margin_bottom": "0.5em",
},
}
2 changes: 2 additions & 0 deletions linkinbio/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
reflex==0.6.2.post1
launchdarkly-server-sdk==9.8.0
5 changes: 5 additions & 0 deletions linkinbio/rxconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import reflex as rx

config = rx.Config(
app_name="linkinbio",
)
Loading