Skip to content

Commit 15764e2

Browse files
committed
ui changes for calendar export
1 parent 49734fb commit 15764e2

File tree

16 files changed

+174
-73
lines changed

16 files changed

+174
-73
lines changed

backend/.dockerignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Python / project
2+
__pycache__
3+
*.pyc
4+
*.pyo
5+
*.pyd
6+
.Python
7+
env/
8+
venv/
9+
.venv/
10+
11+
# git/artifacts
12+
.git
13+
.gitignore
14+
15+
# local IDE/editor
16+
.vscode
17+
.idea
18+
19+
# build artifacts / node_modules
20+
dist/
21+
build/
22+
node_modules/
23+
24+
# tests / docs
25+
tests/
26+
docs/
27+
28+
# docker files (so build context is smaller)
29+
*.egg-info

backend/Dockerfile

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
1-
FROM python:3.10-slim
1+
# Use official Python runtime as base image
2+
FROM python:3.11-slim
23

34
# Set environment variables
4-
ENV PYTHONDONTWRITEBYTECODE=1
5-
ENV PYTHONUNBUFFERED=1
5+
ENV PYTHONUNBUFFERED=1 \
6+
PYTHONDONTWRITEBYTECODE=1
67

78
# Set work directory
89
WORKDIR /app
910

10-
# Install system dependencies
11-
RUN apt-get update \
12-
&& apt-get install -y --no-install-recommends \
13-
gcc \
14-
g++ \
15-
&& rm -rf /var/lib/apt/lists/*
11+
# Copy requirements files and wheels directory
12+
COPY requirements.txt .
13+
COPY wheels/ ./wheels/
1614

1715
# Install Python dependencies
18-
COPY requirements.txt .
19-
RUN pip install --no-cache-dir -r requirements.txt
16+
RUN pip install --upgrade pip
17+
RUN pip install -r requirements.txt
2018

21-
# Copy project
19+
# Copy project files
2220
COPY . .
2321

24-
# Collect static files
25-
RUN python manage.py collectstatic --noinput
22+
# Copy and set up entrypoint script
23+
COPY docker-entrypoint.sh /usr/local/bin/
24+
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
25+
26+
# Expose port
27+
EXPOSE 8000
28+
29+
# Use entrypoint script
30+
ENTRYPOINT ["docker-entrypoint.sh"]
2631

27-
# Run the application
28-
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "my_django_project.wsgi:application"]

backend/api/settings.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@
2727
)
2828
DEBUG = os.getenv("PRODUCTION") != "1" # Fixed the DEBUG logic
2929

30-
ALLOWED_HOSTS = ["localhost", "127.0.0.1", ".vercel.app"]
30+
ALLOWED_HOSTS = [
31+
"localhost",
32+
"127.0.0.1",
33+
".vercel.app",
34+
".elasticbeanstalk.com",
35+
".elb.amazonaws.com",
36+
"*", # Temporary - allows any host. Replace with specific IP/domain in production
37+
]
3138

3239
INSTALLED_APPS = [
3340
"django.contrib.admin",

backend/docker-entrypoint.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "Running database migrations..."
5+
python manage.py migrate --noinput
6+
7+
echo "Collecting static files..."
8+
python manage.py collectstatic --noinput
9+
10+
echo "Starting gunicorn..."
11+
exec gunicorn --bind 0.0.0.0:8000 --workers 4 --timeout 120 api.wsgi:app
12+

backend/scraping/get_static_events.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ def main():
7575
)
7676
logging.info(f"Writing to {output_path}...")
7777
with output_path.open("w", encoding="utf-8") as f:
78+
# Write the last updated timestamp
79+
current_time = datetime.now().isoformat()
7880
f.write('import { Event } from "@/hooks/useEvents";\n\n')
81+
f.write(f'export const LAST_UPDATED = "{current_time}";\n\n')
7982
f.write("export const staticEventsData = new Map<string, Event>([\n")
8083
for i, event in enumerate(events):
8184
event_id = str(event["id"])

frontend/public/test1.svg

Lines changed: 37 additions & 36 deletions
Loading

frontend/src/components/EventLegend.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const EventLegend: React.FC = () => {
55
const clubTypes = getAllClubTypes();
66

77
return (
8-
<div className="flex flex-wrap items-center justify-center gap-6 mt-6 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
8+
<div className="flex flex-wrap items-center justify-center gap-6 mt-6 p-4 bg-gray-50 dark:bg-gray-800 rounded-md">
99
{clubTypes.map((clubType, index) => (
1010
<div key={index} className="flex items-center gap-2">
1111
<div

frontend/src/components/EventsCalendar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const EventPopup: React.FC<{
6969
style: React.CSSProperties;
7070
}> = ({ event, onClose, style }) => (
7171
<div
72-
className="event-popup absolute bg-white dark:bg-gray-800 rounded-lg shadow-lg p-4 w-80 z-50 border border-gray-200 dark:border-gray-700"
72+
className="event-popup absolute bg-white dark:bg-gray-800 rounded-md shadow-lg p-4 w-80 z-50 border border-gray-200 dark:border-gray-700"
7373
style={style}
7474
onClick={(e) => e.stopPropagation()}
7575
>

frontend/src/components/EventsGrid.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const EventStatusBadge = ({ event }: { event: Event }) => {
6363
<img
6464
src={theme === "dark" ? "/test1-dark.svg" : "/test1.svg"}
6565
alt=""
66-
className="absolute top-0 right-0 z-10 w-13"
66+
className="absolute top-0 right-0 z-10 w-12"
6767
/>
6868
<Badge variant="live" className="absolute top-0 right-0 z-10">
6969
LIVE
@@ -118,7 +118,7 @@ const EventsGrid = memo(({ data, isSelectMode = false, selectedEvents = new Set(
118118
return (
119119
<Card
120120
key={event.id}
121-
className={`border-none relative p-0 hover:shadow-lg gap-0 h-full overflow-hidden ${isSelectMode ? 'cursor-pointer' : ''} ${isSelected ? 'ring-2 ring-blue-500' : ''}`}
121+
className={`border-none rounded-md relative p-0 hover:shadow-lg gap-0 h-full overflow-hidden ${isSelectMode ? 'cursor-pointer' : ''} ${isSelected ? 'ring-2 ring-blue-500' : ''}`}
122122
onMouseDown={() => isSelectMode && onToggleEvent?.(event.id)}
123123
>
124124
<EventStatusBadge event={event} />
@@ -162,7 +162,7 @@ const EventsGrid = memo(({ data, isSelectMode = false, selectedEvents = new Set(
162162
@{event.club_handle}
163163
</p>
164164
</CardHeader>
165-
<CardContent className="flex border-gray-200 dark:border-gray-700 flex-col border-b border-l rounded-b-xl border-r gap-1 h-full p-3.5 pt-2.5">
165+
<CardContent className="flex border-gray-200 dark:border-gray-700 flex-col border-b border-l rounded-b-md border-r gap-1 h-full p-3.5 pt-2.5">
166166
<div className="flex items-center space-x-2 text-xs text-gray-600 dark:text-gray-400">
167167
<Calendar className="h-3.5 w-3.5 flex-shrink-0" />
168168
<span className="truncate">{formatPrettyDate(event.date)}</span>

frontend/src/components/FloatingEventExportBar.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,18 @@ export default function FloatingEventExportBar({
3838
view !== "grid" || !isSelectMode || selectedEvents.size === 0
3939
}
4040
>
41-
<div className="bg-white dark:bg-gray-800 rounded-full shadow-lg border border-gray-200 dark:border-gray-700 px-6 py-3 flex items-center gap-4">
42-
<Button
43-
size="sm"
44-
onClick={() => onExportICalendar(data)}
45-
className="rounded-full"
46-
variant="default"
47-
>
48-
<SiApple className="h-4 w-4" />
49-
Export {selectedEvents.size} to iCalendar
50-
</Button>
41+
<div className="bg-white/80 dark:bg-gray-900/80 backdrop-blur-md rounded-full shadow-lg border border-gray-200/50 dark:border-gray-700/50 px-6 py-3 flex items-center gap-4">
42+
{selectedEvents.size > 0 && (
43+
<Button
44+
size="sm"
45+
onClick={() => onExportICalendar(data)}
46+
className="rounded-full"
47+
variant="default"
48+
>
49+
<SiApple className="h-4 w-4" />
50+
Export {selectedEvents.size} to iCalendar
51+
</Button>
52+
)}
5153
{selectedEvents.size === 1 && (
5254
<Button
5355
size="sm"

0 commit comments

Comments
 (0)