https://github.com/victoriayotka/poll
simple polling application with Phoenix LiveView
https://github.com/victoriayotka/poll
chartjs elixir phoenix phoenix-liveview phx-hook rwd
Last synced: over 1 year ago
JSON representation
simple polling application with Phoenix LiveView
- Host: GitHub
- URL: https://github.com/victoriayotka/poll
- Owner: VictoriaYotka
- Created: 2024-11-08T13:52:32.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-15T09:30:47.000Z (over 1 year ago)
- Last Synced: 2025-02-01T13:41:42.054Z (over 1 year ago)
- Topics: chartjs, elixir, phoenix, phoenix-liveview, phx-hook, rwd
- Language: Elixir
- Homepage: https://poll-divine-violet-5969.fly.dev/
- Size: 305 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Elixir LiveView Poll Application
## Overview
This is a simple polling application built with **Phoenix LiveView**. It allows users to create polls, vote on them, and see real-time updates on poll results. The app is mobile-friendly (designed with a mobile-first approach) and uses **Tailwind CSS** for styling and **Chart.js** for dynamic chart visualizations of poll results.
The solution includes a Dockerized PostgreSQL database for persistent storage of users, polls, and votes, and all functionality runs locally with `mix phx.server`.
## Deployment
The application is deployed on [Fly.io](https://poll-divine-violet-5969.fly.dev/).
Visit the deployed page here:
👉 **[Fly.io](https://poll-divine-violet-5969.fly.dev/)**
## Features
- **User Registration**: Users can register by entering a username.
- **Create Polls**: Registered users can create new polls.
- **Vote in Polls**: Users can vote in any existing poll and see instant, real-time results.
- **One Vote per Poll**: Each user can only vote once in each poll.
- **Real-Time Updates**: LiveView provides real-time poll result updates without refreshing the page.
- **Mobile-First, Responsive Design**: The UI adapts for both mobile and desktop, using Tailwind CSS.
- **Data Visualization with Chart.js**: Poll results are visualized with responsive charts.
- **JS Hooks**: JavaScript hooks are used for finer client-side interactivity.
- **Phoenix PubSub for Broadcasts**: PubSub ensures that vote updates are broadcasted in real-time to all connected clients.
- **Infinite Scroll**: The polling results and polls are dynamically loaded with infinite scroll. As the user scrolls, new poll items are fetched automatically, improving the user experience without page reloads.
## Prerequisites
- **Docker & Docker Compose**: Ensure Docker is installed to run the database container.
- **Elixir and Phoenix**: The app was developed using Elixir and the Phoenix framework.
## Setup Instructions
### 1. Clone the Repository
```bash
git clone https://github.com/VictoriaYotka/poll.git
cd poll
```
### 2. Database Setup with Docker
This project includes a docker-compose.yml file to simplify database setup.
Start the Database:
```bash
docker-compose up -d
```
Run Database Migrations and Seed Data:
```bash
mix ecto.setup
```
### 3. Install Dependencies
Install Elixir and JavaScript dependencies:
```bash
mix deps.get
cd assets && npm install
```
### 4. Run the Server
Start the Phoenix server (from the root directory):
```bash
mix phx.server
```
The application will be available at [http://localhost:4000](http://localhost:4000).
## Application Usage
1. **Register** by entering a username on the home page.
2. **Create Polls** by navigating to the "New Poll" page.
3. **Vote in Polls** by selecting an option in any poll.
4. **View Real-Time Results** which are updated instantly using LiveView and Phoenix PubSub.
5. **View Poll Results in Charts** rendered by Chart.js.
## Key Design and Implementation Details
### JavaScript Hooks
- **Real-Time Chart Updates**: JS hooks work with LiveView to trigger Chart.js updates dynamically as poll results change.
- **Custom Interactivity**: JavaScript hooks enhance interactivity, adding custom client-side behavior for animations and chart updates.
### Responsive Design (Mobile-First)
- **Tailwind CSS**: A mobile-first approach with Tailwind CSS ensures that the app is responsive and adapts well to different screen sizes.
### Chart.js Integration
- **Poll Result Visualization**: Chart.js visualizes poll results in dynamic, real-time bar charts, enhancing the user experience and making data interpretation easy.
### Phoenix PubSub for Real-Time Updates
- **Broadcasting Poll Updates**: Phoenix PubSub is used to broadcast new votes in real-time. When a user submits a vote, a message is sent to all connected clients, updating poll results instantly.
- **Seamless Client Syncing**: Using PubSub with LiveView means clients see live updates as votes are cast, without requiring full-page reloads.
### Dockerization
- **Persistent Database Setup**: The PostgreSQL database runs in a Docker container, isolated from your local environment for ease of use.
- **Automated Database Initialization**: `docker-compose` along with `mix ecto` commands handle migrations and seed data setup, streamlining project setup.
## Project Structure
- **Phoenix Contexts** organize the code for polls, users, and votes into manageable, modular components.
- **Ecto Schemas** handle data persistence for users, polls, and votes with validations to enforce business rules.
- **JS Hooks and LiveView Components** manage real-time updates and user interactions, optimizing the front-end experience.
## Testing
Core functionality, such as poll creation, voting, and result display, is covered by unit tests. To run tests:
```bash
mix test
```
## Design Decisions & Trade-Offs
- **LiveView Over Traditional SPA**: LiveView was chosen for real-time updates without requiring a full SPA framework like React or Vue. This reduces complexity and keeps the application server-rendered.
- **Chart.js for Visualization**: Chart.js was used for simplicity and responsive chart rendering, although other libraries could offer more customization.
- **Single Vote Limit**: The application limits each user to a single vote per poll. This was enforced at the database level for consistency.
- **Sorting and Filtering with Ecto**: Sorting and filtering are implemented using efficient **Ecto queries**, ensuring that the database does the heavy lifting and reduces the memory footprint on the server side. This makes fetching polls and results faster, even as the data grows.
- **Shared Layout for All Pages**: The application uses a shared layout to ensure a consistent user interface across all pages. This layout includes common elements like header, minimizing redundancy and making it easier to maintain the application as it grows.
## Dependencies
The project uses the following dependencies:
- **Elixir**: "~> 1.16.0"
- **Phoenix**: "~> 1.7.12"
- **Phoenix Live View**: "~> 0.20.2"
- **Chart.js**: "^4.4.6" for rendering dynamic poll result charts
## License
This project is licensed under the MIT License.