Saved your changes before starting work

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 5e584ab0-c340-4432-97ef-1972582b60e9
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 6d4dbe7c-69e4-4510-bd62-638ff9c78d5c
This commit is contained in:
abhiramtx
2025-11-08 22:13:45 +00:00
parent c8cb73cd14
commit befc3160be
64 changed files with 2588 additions and 1707 deletions

168
templates/admin/base.html Normal file
View File

@@ -0,0 +1,168 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Admin Panel{% endblock %} - Technical Turbulence</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
background: #000;
color: #fff;
line-height: 1.5;
}
.admin-container {
display: flex;
min-height: 100vh;
}
.admin-sidebar {
width: 250px;
background: #1a1a1a;
border-right: 1px solid #333;
position: fixed;
top: 0;
left: 0;
height: 100vh;
overflow-y: auto;
z-index: 1000;
display: flex;
flex-direction: column;
}
.admin-logo {
font-size: 18px;
font-weight: 700;
color: #fff;
text-align: center;
padding: 32px 24px;
border-bottom: 1px solid #333;
}
.admin-nav {
flex: 1;
padding: 24px 16px;
}
.admin-nav a {
display: block;
padding: 12px 16px;
margin-bottom: 4px;
color: #999;
text-decoration: none;
border-radius: 6px;
font-size: 14px;
transition: all 0.15s ease;
}
.admin-nav a:hover {
background: #252525;
color: #fff;
}
.admin-nav a.active {
background: #3b82f6;
color: #fff;
}
.admin-logout {
padding: 16px;
border-top: 1px solid #333;
}
.admin-logout a {
display: block;
padding: 12px 16px;
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.2);
color: #ef4444;
text-decoration: none;
border-radius: 6px;
text-align: center;
font-size: 14px;
transition: all 0.15s ease;
}
.admin-logout a:hover {
background: rgba(239, 68, 68, 0.2);
}
.admin-content {
margin-left: 250px;
flex: 1;
padding: 40px;
min-height: 100vh;
}
.admin-header {
font-size: 32px;
font-weight: 700;
color: #fff;
margin-bottom: 32px;
}
.flash-message {
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 24px;
font-size: 14px;
}
.flash-message.success {
background: rgba(34, 197, 94, 0.1);
border: 1px solid rgba(34, 197, 94, 0.3);
color: #22c55e;
}
.flash-message.error {
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
color: #ef4444;
}
@media (max-width: 768px) {
.admin-sidebar {
width: 200px;
}
.admin-content {
margin-left: 200px;
padding: 24px;
}
}
</style>
{% block extra_styles %}{% endblock %}
</head>
<body>
<div class="admin-container">
<div class="admin-sidebar">
<div class="admin-logo">Admin Panel</div>
<nav class="admin-nav">
<a href="{{ url_for('admin_stats') }}" class="{% if request.endpoint == 'admin_stats' %}active{% endif %}">Stats</a>
<a href="{{ url_for('admin_members') }}" class="{% if request.endpoint == 'admin_members' %}active{% endif %}">Members/Mentors</a>
<a href="{{ url_for('admin_competitions') }}" class="{% if request.endpoint == 'admin_competitions' %}active{% endif %}">Competitions</a>
<a href="{{ url_for('admin_sponsors') }}" class="{% if request.endpoint == 'admin_sponsors' %}active{% endif %}">Sponsors</a>
</nav>
<div class="admin-logout">
<a href="{{ url_for('admin_logout') }}">Logout</a>
</div>
</div>
<div class="admin-content">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="flash-message {{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,195 @@
{% extends "admin/base.html" %}
{% block title %}Competitions Management{% endblock %}
{% block extra_styles %}
<style>
.section {
margin-bottom: 48px;
}
.section-title {
font-family: var(--font-display);
font-size: 28px;
color: var(--white);
margin-bottom: 24px;
}
.add-form {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 24px;
margin-bottom: 32px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 16px;
}
.form-group {
margin-bottom: 16px;
}
.form-label {
display: block;
color: var(--gray-300);
margin-bottom: 6px;
font-family: var(--font-body);
font-size: 14px;
}
.form-input, .form-select, .form-textarea {
width: 100%;
padding: 10px 12px;
background: #0d0d0d;
border: 1px solid #333;
border-radius: 8px;
color: #fff;
font-size: 14px;
}
.form-textarea {
min-height: 100px;
resize: vertical;
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
outline: none;
border-color: var(--blue);
}
.competitions-list {
display: flex;
flex-direction: column;
gap: 20px;
}
.comp-card {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 24px;
}
.comp-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 16px;
}
.comp-title {
font-family: var(--font-display);
font-size: 22px;
color: var(--white);
margin-bottom: 4px;
}
.comp-meta {
color: var(--gray-400);
font-family: var(--font-body);
font-size: 14px;
}
.comp-description {
color: var(--gray-300);
font-family: var(--font-body);
margin-bottom: 12px;
line-height: 1.6;
}
.comp-awards {
color: var(--gray-400);
font-family: var(--font-body);
font-size: 14px;
}
.btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
font-family: var(--font-body);
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background: var(--blue);
color: var(--white);
}
.btn-primary:hover {
background: var(--blue-light);
transform: translateY(-2px);
}
.btn-danger {
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
}
.btn-danger:hover {
background: rgba(239, 68, 68, 0.3);
}
.info-text {
color: var(--gray-400);
font-family: var(--font-body);
font-size: 13px;
margin-top: 4px;
}
</style>
{% endblock %}
{% block content %}
<h1 class="admin-header">Competitions Management</h1>
<div class="section">
<h2 class="section-title">Add New Competition</h2>
<div class="add-form">
<form method="POST" action="{{ url_for('add_competition') }}" enctype="multipart/form-data">
<div class="form-row">
<div class="form-group">
<label class="form-label">Season</label>
<input type="text" name="season" class="form-input" placeholder="e.g., Into The Deep" list="seasons" required>
<datalist id="seasons">
{% for season in seasons %}
<option value="{{ season }}">
{% endfor %}
</datalist>
</div>
<div class="form-group">
<label class="form-label">Event Name</label>
<input type="text" name="event_name" class="form-input" required>
</div>
</div>
<div class="form-group">
<label class="form-label">Date</label>
<input type="text" name="date" class="form-input" placeholder="e.g., 06/19/2025 or 11/11/23 - 01/06/24" required>
</div>
<div class="form-group">
<label class="form-label">Description</label>
<textarea name="description" class="form-textarea" required></textarea>
</div>
<div class="form-group">
<label class="form-label">Awards (optional)</label>
<textarea name="awards" class="form-textarea" placeholder="One award per line"></textarea>
<p class="info-text">Enter each award on a new line</p>
</div>
<div class="form-group">
<label class="form-label">Competition Image (optional)</label>
<input type="file" name="image" class="form-input" accept="image/*">
</div>
<button type="submit" class="btn btn-primary">Add Competition</button>
</form>
</div>
</div>
<div class="section">
<h2 class="section-title">Existing Competitions</h2>
<div class="competitions-list">
{% for comp in competitions %}
<div class="comp-card">
<div class="comp-header">
<div>
<h3 class="comp-title">{{ comp.event_name }}</h3>
<p class="comp-meta">{{ comp.season }} · {{ comp.date }}</p>
</div>
<form method="POST" action="{{ url_for('delete_competition') }}">
<input type="hidden" name="id" value="{{ comp.id }}">
<button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</div>
<p class="comp-description">{{ comp.description }}</p>
{% if comp.awards %}
<p class="comp-awards">🏆 {{ comp.awards|replace('|', ' · ') }}</p>
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endblock %}

110
templates/admin/login.html Normal file
View File

@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Login - Technical Turbulence</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
background: #000;
color: #fff;
}
.login-container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #000;
}
.login-box {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 20px;
padding: 48px;
width: 90%;
max-width: 400px;
}
.login-title {
font-size: 32px;
font-weight: 700;
color: #fff;
margin-bottom: 32px;
text-align: center;
}
.form-group {
margin-bottom: 24px;
}
.form-label {
display: block;
color: #999;
margin-bottom: 8px;
font-size: 14px;
}
.form-input {
width: 100%;
padding: 12px 16px;
background: #0d0d0d;
border: 1px solid #333;
border-radius: 8px;
color: #fff;
font-size: 16px;
}
.form-input:focus {
outline: none;
border-color: #3b82f6;
}
.login-button {
width: 100%;
padding: 14px;
background: #3b82f6;
color: #fff;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
.login-button:hover {
background: #60a5fa;
transform: translateY(-2px);
}
.error-message {
background: rgba(239, 68, 68, 0.1);
border: 1px solid rgba(239, 68, 68, 0.3);
color: #ef4444;
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 24px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-box">
<h1 class="login-title">Admin Login</h1>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="error-message">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST">
<div class="form-group">
<label class="form-label">Password</label>
<input type="password" name="password" class="form-input" required autofocus>
</div>
<button type="submit" class="login-button">Login</button>
</form>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,259 @@
{% extends "admin/base.html" %}
{% block title %}Members & Mentors Management{% endblock %}
{% block extra_styles %}
<style>
.section {
margin-bottom: 48px;
}
.section-title {
font-family: var(--font-display);
font-size: 28px;
color: var(--white);
margin-bottom: 24px;
}
.add-form {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 24px;
margin-bottom: 32px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 16px;
}
.form-group {
margin-bottom: 16px;
}
.form-label {
display: block;
color: var(--gray-300);
margin-bottom: 6px;
font-family: var(--font-body);
font-size: 14px;
}
.form-input, .form-select {
width: 100%;
padding: 10px 12px;
background: #0d0d0d;
border: 1px solid #333;
border-radius: 8px;
color: #fff;
font-size: 14px;
}
.form-input:focus, .form-select:focus {
outline: none;
border-color: #3b82f6;
}
.members-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.member-card-admin {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 20px;
}
.member-image-admin {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 12px;
margin-bottom: 16px;
}
.member-name-admin {
font-family: var(--font-display);
font-size: 20px;
color: var(--white);
margin-bottom: 8px;
}
.member-role-admin {
color: var(--gray-400);
font-family: var(--font-body);
font-size: 14px;
margin-bottom: 16px;
}
.btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
font-family: var(--font-body);
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
margin-right: 8px;
}
.btn-primary {
background: var(--blue);
color: var(--white);
}
.btn-primary:hover {
background: var(--blue-light);
transform: translateY(-2px);
}
.btn-danger {
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
}
.btn-danger:hover {
background: rgba(239, 68, 68, 0.3);
}
.btn-edit {
background: rgba(59, 130, 246, 0.2);
color: var(--blue);
}
.btn-edit:hover {
background: rgba(59, 130, 246, 0.3);
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal.active {
display: flex;
}
.modal-content {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 32px;
max-width: 500px;
width: 90%;
}
.modal-close {
float: right;
font-size: 28px;
cursor: pointer;
color: var(--gray-400);
}
.modal-close:hover {
color: var(--white);
}
</style>
{% endblock %}
{% block content %}
<h1 class="admin-header">Members & Mentors Management</h1>
<div class="section">
<h2 class="section-title">Add New Member/Mentor</h2>
<div class="add-form">
<form method="POST" action="{{ url_for('add_member') }}" enctype="multipart/form-data">
<div class="form-row">
<div class="form-group">
<label class="form-label">Name</label>
<input type="text" name="name" class="form-input" required>
</div>
<div class="form-group">
<label class="form-label">Role</label>
<input type="text" name="role" class="form-input" placeholder="e.g., SOFTWARE, HARDWARE" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">Type</label>
<select name="type" class="form-select" required>
<option value="member">Team Member</option>
<option value="mentor">Mentor</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Profile Image</label>
<input type="file" name="image" class="form-input" accept="image/*">
</div>
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
</div>
<div class="section">
<h2 class="section-title">Mentors</h2>
<div class="members-grid">
{% for mentor in mentors %}
<div class="member-card-admin">
<img src="{{ url_for('static', filename=mentor.image_path) }}" class="member-image-admin" alt="{{ mentor.name }}">
<h3 class="member-name-admin">{{ mentor.name }}</h3>
<p class="member-role-admin">{{ mentor.role }}</p>
<button onclick="openEditModal('mentor', {{ mentor.id }}, '{{ mentor.name }}', '{{ mentor.role }}')" class="btn btn-edit">Edit</button>
<form method="POST" action="{{ url_for('delete_member') }}" style="display: inline;">
<input type="hidden" name="id" value="{{ mentor.id }}">
<input type="hidden" name="type" value="mentor">
<button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</div>
{% endfor %}
</div>
</div>
<div class="section">
<h2 class="section-title">Team Members</h2>
<div class="members-grid">
{% for member in members %}
<div class="member-card-admin">
<img src="{{ url_for('static', filename=member.image_path) }}" class="member-image-admin" alt="{{ member.name }}">
<h3 class="member-name-admin">{{ member.name }}</h3>
<p class="member-role-admin">{{ member.role }}</p>
<button onclick="openEditModal('member', {{ member.id }}, '{{ member.name }}', '{{ member.role }}')" class="btn btn-edit">Edit</button>
<form method="POST" action="{{ url_for('delete_member') }}" style="display: inline;">
<input type="hidden" name="id" value="{{ member.id }}">
<input type="hidden" name="type" value="member">
<button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</div>
{% endfor %}
</div>
</div>
<div id="editModal" class="modal">
<div class="modal-content">
<span class="modal-close" onclick="closeEditModal()">&times;</span>
<h2 class="section-title">Edit Member</h2>
<form method="POST" action="{{ url_for('update_member') }}" enctype="multipart/form-data">
<input type="hidden" name="id" id="edit-id">
<input type="hidden" name="type" id="edit-type">
<div class="form-group">
<label class="form-label">Name</label>
<input type="text" name="name" id="edit-name" class="form-input" required>
</div>
<div class="form-group">
<label class="form-label">Role</label>
<input type="text" name="role" id="edit-role" class="form-input" required>
</div>
<div class="form-group">
<label class="form-label">Profile Image (optional)</label>
<input type="file" name="image" class="form-input" accept="image/*">
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
</div>
</div>
<script>
function openEditModal(type, id, name, role) {
document.getElementById('edit-id').value = id;
document.getElementById('edit-type').value = type;
document.getElementById('edit-name').value = name;
document.getElementById('edit-role').value = role;
document.getElementById('editModal').classList.add('active');
}
function closeEditModal() {
document.getElementById('editModal').classList.remove('active');
}
</script>
{% endblock %}

View File

@@ -0,0 +1,163 @@
{% extends "admin/base.html" %}
{% block title %}Sponsors Management{% endblock %}
{% block extra_styles %}
<style>
.section {
margin-bottom: 48px;
}
.section-title {
font-family: var(--font-display);
font-size: 28px;
color: var(--white);
margin-bottom: 24px;
}
.add-form {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 24px;
margin-bottom: 32px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 16px;
}
.form-group {
margin-bottom: 16px;
}
.form-label {
display: block;
color: var(--gray-300);
margin-bottom: 6px;
font-family: var(--font-body);
font-size: 14px;
}
.form-input {
width: 100%;
padding: 10px 12px;
background: #0d0d0d;
border: 1px solid #333;
border-radius: 8px;
color: #fff;
font-size: 14px;
}
.form-input:focus {
outline: none;
border-color: #3b82f6;
}
.sponsors-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.sponsor-card-admin {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 24px;
}
.sponsor-logo-admin {
width: 100%;
height: 150px;
object-fit: contain;
margin-bottom: 16px;
background: #0d0d0d;
border-radius: 12px;
padding: 16px;
}
.sponsor-name-admin {
font-family: var(--font-display);
font-size: 20px;
color: var(--white);
margin-bottom: 8px;
}
.sponsor-url-admin {
color: var(--blue);
font-family: var(--font-body);
font-size: 14px;
margin-bottom: 16px;
word-break: break-all;
text-decoration: none;
}
.sponsor-url-admin:hover {
text-decoration: underline;
}
.btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
font-family: var(--font-body);
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background: var(--blue);
color: var(--white);
}
.btn-primary:hover {
background: var(--blue-light);
transform: translateY(-2px);
}
.btn-danger {
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
width: 100%;
}
.btn-danger:hover {
background: rgba(239, 68, 68, 0.3);
}
</style>
{% endblock %}
{% block content %}
<h1 class="admin-header">Sponsors Management</h1>
<div class="section">
<h2 class="section-title">Add New Sponsor</h2>
<div class="add-form">
<form method="POST" action="{{ url_for('add_sponsor') }}" enctype="multipart/form-data">
<div class="form-row">
<div class="form-group">
<label class="form-label">Sponsor Name</label>
<input type="text" name="name" class="form-input" required>
</div>
<div class="form-group">
<label class="form-label">Website URL</label>
<input type="url" name="website_url" class="form-input" placeholder="https://example.com" required>
</div>
</div>
<div class="form-group">
<label class="form-label">Logo Image</label>
<input type="file" name="logo" class="form-input" accept="image/*" required>
</div>
<button type="submit" class="btn btn-primary">Add Sponsor</button>
</form>
</div>
</div>
<div class="section">
<h2 class="section-title">Existing Sponsors</h2>
<div class="sponsors-grid">
{% for sponsor in sponsors %}
<div class="sponsor-card-admin">
{% if sponsor.logo_path %}
<img src="{{ url_for('static', filename=sponsor.logo_path) }}" class="sponsor-logo-admin" alt="{{ sponsor.name }}">
{% endif %}
<h3 class="sponsor-name-admin">{{ sponsor.name }}</h3>
{% if sponsor.website_url %}
<a href="{{ sponsor.website_url }}" class="sponsor-url-admin" target="_blank">{{ sponsor.website_url }}</a>
{% endif %}
<form method="POST" action="{{ url_for('delete_sponsor') }}">
<input type="hidden" name="id" value="{{ sponsor.id }}">
<button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,89 @@
{% extends "admin/base.html" %}
{% block title %}Stats Management{% endblock %}
{% block extra_styles %}
<style>
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
}
.stat-card {
background: #1a1a1a;
border: 1px solid #333;
border-radius: 16px;
padding: 24px;
}
.stat-card-header {
font-family: var(--font-display);
font-size: 20px;
color: var(--white);
margin-bottom: 16px;
}
.form-group {
margin-bottom: 16px;
}
.form-label {
display: block;
color: var(--gray-300);
margin-bottom: 6px;
font-family: var(--font-body);
font-size: 14px;
}
.form-input {
width: 100%;
padding: 10px 12px;
background: #0d0d0d;
border: 1px solid #333;
border-radius: 8px;
color: #fff;
font-size: 14px;
}
.form-input:focus {
outline: none;
border-color: #3b82f6;
}
.btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
font-family: var(--font-body);
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background: var(--blue);
color: var(--white);
}
.btn-primary:hover {
background: var(--blue-light);
transform: translateY(-2px);
}
</style>
{% endblock %}
{% block content %}
<h1 class="admin-header">Stats Management</h1>
<div class="stats-grid">
{% for stat in stats %}
<div class="stat-card">
<h3 class="stat-card-header">{{ stat.key }}</h3>
<form method="POST" action="{{ url_for('update_stat') }}">
<input type="hidden" name="id" value="{{ stat.id }}">
<div class="form-group">
<label class="form-label">Value</label>
<input type="text" name="value" class="form-input" value="{{ stat.value }}" required>
</div>
<div class="form-group">
<label class="form-label">Label</label>
<input type="text" name="label" class="form-input" value="{{ stat.label }}" required>
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -30,12 +30,6 @@
<li class="nav-item-center">
<a href="/sponsors">Sponsors</a>
</li>
<!-- <li class="nav-item-center">
<a href="/robots">Robots</a>
</li>
<li class="nav-item-center">
<a href="/contact">Outreach</a>
</li> -->
<li class="nav-item-center">
<a href="/contact">Contact</a>
</li>

View File

@@ -4,156 +4,57 @@
{% block content %}
<body>
<div class="competitions">
<div class="competitions">
<div class="sidebar">
<div class="sidebar-content">
<a href="#2023">2023</a>
<a href="#2024">2024</a>
{% for season in competitions_by_season.keys() %}
<a href="#{{ season.replace(' ', '') }}">{{ season }}</a>
{% endfor %}
</div>
</div>
<div class="competitions-container">
<div class="competitions-inner">
<h1 class="heading" id="comp"><span class="emoji competitions">Competition log</span></h1>
<hr>
<h1 class="heading" id="comp">Competition log</h1>
<hr id="comp-hr">
<h1 id="2024" class="competition-year">2024</h1>
{% for season, comps in competitions_by_season.items() %}
<h1 id="{{ season.replace(' ', '') }}" class="competition-year">{{ season }}</h1>
{% for comp in comps %}
<div class="competition-card">
<!-- <div class="competition-card-img">
<img src="{{ url_for('static', filename='images/earlybird.png') }}">
</div> -->
{% if comp.image_path %}
<div class="competition-card-img">
<img src="{{ url_for('static', filename=comp.image_path) }}">
</div>
{% endif %}
<div class="competition-header">
<p class="competition-name">FiT-North Early Bird Scrimmage</p>
<p class="competition-name">{{ comp.event_name }}</p>
<p class="middle-dot">·</p>
<p class="competition-date">10/6/2024</p>
<p class="competition-date">{{ comp.date }}</p>
</div>
<p class="competition-subtitle">Description</p>
<p class="competition-description">We participated in the FiT-North Early Bird Scrimmage where we
won two recognitions.</p>
<p class="competition-description">{{ comp.description }}</p>
{% if comp.awards %}
<p class="competition-subtitle">Awards</p>
<ul class="competition-awards">
<li>Innovate Award sponsored by RTX</li>
<li>Design Award 2nd Place</li>
</ul>
</div>
<h1 id="2023" class="competition-year">2023</h1>
<div class="competition-card">
<div class="competition-header">
<p class="competition-name">FiT-North F-League Meets (3)</p>
<p class="middle-dot">·</p>
<p class="competition-date">11/11/23 - 01/06/24</p>
</div>
<p class="competition-subtitle">Description</p>
<p class="competition-description">Consisted of 3 qualification meets: FiT-North F-League Meet 1,
FiT-North F-League Meet 2, and FiT-North F-League Meet 3.</p>
<p class="competition-subtitle">Awards</p>
<ul class="competition-awards">
<li>Accumulated 10 wins</li>
</ul>
</div>
<div class="competition-card">
<div class="competition-header">
<p class="competition-name">FiT-North E&F Tournament</p>
<p class="middle-dot">·</p>
<p class="competition-date">01/20/24</p>
</div>
<p class="competition-subtitle">Description</p>
<p class="competition-description">We got 4 wins, and got Rank 3 out of 24 going into the playoffs.
We were the 1st Team Selected by Rank 2 Team 13072. We had 2 wins in the Semi-Finals and 2 wins
in the Finals. We won 3 awards and advanced straight to North Area Championship for Texas FiT
Region.</p>
<p class="competition-subtitle">Awards</p>
<ul class="competition-awards">
<li>Design Award 3rd Place</li>
<li>Innovate Award sponsored by RTX 2nd Place</li>
<li>Winning Alliance - 1st Team Selected</li>
</ul>
</div>
<div class="competition-card">
<div class="competition-header">
<p class="competition-name">FiT-North Area Championship</p>
<p class="middle-dot">·</p>
<p class="competition-date">02/24/24</p>
</div>
<p class="competition-subtitle">Description</p>
<p class="competition-description">We won our first match [But Expansion and Control hubs were
tweaking the whole time :( ]. We ended at Rank 37 of 41, and did not get picked for playoffs. We
won 1 award and advanced to the Texas State Championship.</p>
<p class="competition-subtitle">Awards</p>
<ul class="competition-awards">
<li>Innovate Award sponsored by RTX 2nd Place</li>
</ul>
</div>
<div class="competition-card">
<div class="competition-header">
<p class="competition-name">Texas FTC State Championship - Johnson Division</p>
<p class="middle-dot">·</p>
<p class="competition-date">03/21/24 - 03/23/24</p>
</div>
<p class="competition-subtitle">Description</p>
<p class="competition-description">We got 3 wins and got Rank 12 of 36 going into playoffs. We were
the 1st Team Selected by Rank 4 Team 16226. We got 2 wins in the Semi-Finals and 1 win in the
Finals. We won 1 award, but did not advance to the State Finals nor the World Championship.</p>
<p class="competition-subtitle">Awards</p>
<ul class="competition-awards">
<li>Johnson Division Finalist Alliance - 1st Team Selected</li>
</ul>
</div>
<div class="competition-card">
<div class="competition-header">
<p class="competition-name">Buc Days 2024 Robotics Rodeo (Off-season Tournament)</p>
<p class="middle-dot">·</p>
<p class="competition-date">05/04/24</p>
</div>
<p class="competition-subtitle">Description</p>
<p class="competition-description">We got 4 wins and were Rank 8 of 41 going into playoffs. We were
the st Team Selected by Rank 3 Team 16458. We got 2 wins in the Semi-Finals and 1 win in the
Finals. We won 1 award.</p>
<p class="competition-subtitle">Awards</p>
<ul class="competition-awards">
<li>Finalist Alliance - 1st Team Selected</li>
{% for award in comp.awards.split('|') %}
<li>{{ award }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</body>
{% endblock %}
{% endblock %}

View File

@@ -1,41 +0,0 @@
{% extends "base.html" %}
{% block title %}Communication{% endblock %}
{% block content %}
<body>
<div class="contact">
<div class="header-container">
<div class="line"></div>
<h1 class="header">CONTACT US</h1>
<div class="line"></div>
</div>
<p class="info">you can find us on several platforms.</p>
<div class="contact-container">
<div class="contact-card">
<img class="card-img" src="{{ url_for('static', filename='images/insta4.png') }}">
<div class="card-txt-container">
<p class="card-txt"><a class="link" target="_blank" href="https://www.instagram.com/technicalturbulence23344/"> Follow Our Instagram </a></p>
</div>
</div>
<div class="contact-card">
<img class="card-img" src="{{ url_for('static', filename='images/yt2.png') }}">
<div class="card-txt-container">
<p class="card-txt"><a class="link" target="_blank" href="https://youtube.com/@TechnicalTurbulenceFTC"> Find Us On YT </a></p>
</div>
</div>
<div class="contact-card">
<img class="card-img" src="{{ url_for('static', filename='images/g3.jpg') }}">
<div class="card-txt-container">
<p class="card-txt"><a class="link" target="_blank" href="mailto:technicalturbulence@gmail.com"> Email Us </a></p>
</div>
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -4,8 +4,8 @@
{% block content %}
<body>
<div class="contact">
<div class="contact">
<br>
<h1 class="heading" id="spon"><span class="emoji contact">Contact</span></h1>
<hr>
<p class="info">🌐 you can find us on several platforms! 🌐</p>
@@ -29,6 +29,5 @@
</div>
</div>
</div>
</body>
{% endblock %}

View File

@@ -4,24 +4,23 @@
{% block content %}
<body>
<div class="contributors">
<div class="team-info">
<div class="stats-container" id="stats2">
<div class="contributors">
<!-- <div class="team-info"> -->
<!-- <div class="stats-container" id="stats2">
<h1 class="heading"><span class="emoji stats">Our stats</span></h1>
<hr>
<div class="stats-cards">
<div class="stats-card">
<h1 class="stats-card-header">2</h1>
<p class="stats-card-info">year of robotics</p>
<p class="stats-card-info">seasons of robotics</p>
</div>
<div class="stats-card">
<h1 class="stats-card-header">2</h1>
<h1 class="stats-card-header">6</h1>
<p class="stats-card-info">awards this season</p>
</div>
<div class="stats-card">
<h1 class="stats-card-header">7</h1>
<h1 class="stats-card-header">11</h1>
<p class="stats-card-info">total awards won</p>
</div>
<div class="stats-card">
@@ -32,124 +31,39 @@
<button class="stats-button" onclick="window.location.href = '{{ url_for('competitions') }}' ; ">View
our log</button>
</div>
</div>
</div> -->
<!-- </div> -->
<br>
<h1 class="heading"><span class="emoji sponsors" id="team">Our mentor and coach</span></h1>
<h1 class="heading"><span class="emoji sponsors" id="team">Our mentors and coaches</span></h1>
<hr>
<p class="info">❤️ meet our amazing coach and mentor! ❤️</p>
<p class="info">❤️ meet our amazing coach and mentors! ❤️</p>
<div class="members-container">
{% for mentor in mentors %}
<div class="member-card">
<img class="member-image" src="{{ url_for('static', filename='images/default.jpg') }}">
<h2 class="member-name">Mr. Kruger</h2>
<p class="member-role">COACH / MENTOR</p>
{% if mentor.image_path %}
<img class="member-image" src="{{ url_for('static', filename=mentor.image_path) }}">
{% endif %}
<h2 class="member-name">{{ mentor.name }}</h2>
<p class="member-role">{{ mentor.role }}</p>
</div>
{% endfor %}
</div>
<h1 class="heading"><span class="emoji team" id="team">Our team</span></h1>
<hr>
<p class="info">⭐ meet our amazing team! ⭐</p>
<div class="members-container">
<div class="member-card" id="hardware">
<img class="member-image" src="{{ url_for('static', filename='images/default.jpg') }}">
<h2 class="member-name">Samuel</h2>
<p class="member-role">HARDWARE</p>
{% for member in members %}
<div class="member-card">
{% if member.image_path %}
<img class="member-image" src="{{ url_for('static', filename=member.image_path) }}">
{% endif %}
<h2 class="member-name">{{ member.name }}</h2>
<p class="member-role">{{ member.role }}</p>
</div>
<div class="member-card" id="hardware">
<img class="member-image" src="{{ url_for('static', filename='images/anish.png') }}">
<h2 class="member-name">Anish</h2>
<p class="member-role">HARDWARE</p>
</div>
<div class="member-card" id="hardware">
<img class="member-image" src="{{ url_for('static', filename='images/default.jpg') }}">
<h2 class="member-name">Daniel</h2>
<p class="member-role">HARDWARE</p>
</div>
<div class="member-card" id="hardware">
<img class="member-image" src="{{ url_for('static', filename='images/default.jpg') }}">
<h2 class="member-name">Stephen</h2>
<p class="member-role">HARDWARE</p>
</div>
<div class="member-card" id="software">
<img class="member-image" src="{{ url_for('static', filename='images/new-keshav.png') }}">
<h2 class="member-name">Keshav</h2>
<p class="member-role">SOFTWARE</p>
</div>
<div class="member-card" id="software">
<img class="member-image" src="{{ url_for('static', filename='images/sujay.png') }}">
<h2 class="member-name">Sujay</h2>
<p class="member-role">SOFTWARE</p>
</div>
<div class="member-card" id="software">
<img class="member-image" src="{{ url_for('static', filename='images/abhi.png') }}">
<h2 class="member-name">Abhiram</h2>
<p class="member-role">SOFTWARE</p>
</div>
<div class="member-card" id="hardware">
<img class="member-image" src="{{ url_for('static', filename='images/default.jpg') }}">
<h2 class="member-name">Caitlin</h2>
<p class="member-role">ALUMNI; HARDWARE</p>
</div>
<div class="member-card" id="software">
<img class="member-image" src="{{ url_for('static', filename='images/default.jpg') }}">
<h2 class="member-name">Krith</h2>
<p class="member-role">OUTREACH</p>
</div>
{% endfor %}
</div>
</div>
<script>
function createConfetti(emoji, originX, originY) {
const confettiCount = 40;
for (let i = 0; i < confettiCount; i++) {
let confetti = document.createElement("div");
confetti.innerHTML = emoji;
confetti.style.position = "fixed";
confetti.style.left = `${originX}px`;
confetti.style.top = `${originY}px`;
confetti.style.fontSize = `${Math.random() * 2 + 1.5}rem`;
confetti.style.pointerEvents = "none";
confetti.style.opacity = "0";
document.body.appendChild(confetti);
let angle = Math.random() * Math.PI * 2;
let velocityX = Math.cos(angle) * (Math.random() * window.innerWidth * 0.5);
let velocityY = -Math.abs(Math.sin(angle) * (Math.random() * window.innerHeight * 0.5));
let fallX = velocityX * 1.2;
let fallY = window.innerHeight;
confetti.animate([
{ transform: `translate(0, 0) scale(1)`, opacity: 0 },
{ transform: `translate(${velocityX}px, ${velocityY}px) scale(1.2)`, opacity: 1, offset: 0.2 },
{ transform: `translate(${fallX}px, ${fallY}px) scale(0.8)`, opacity: 0, offset: 1 }
], {
duration: 6000 + Math.random() * 1000,
easing: "cubic-bezier(0.2, 0.8, 0.2, 1)"
});
setTimeout(() => confetti.remove(), 7000);
}
}
document.querySelectorAll("#software, #hardware").forEach(card => {
card.addEventListener("mouseenter", (event) => {
let emoji = card.id === "software" ? "😊" : "💩";
let rect = card.getBoundingClientRect();
let originX = event.clientX;
let originY = event.clientY;
createConfetti(emoji, originX, originY);
});
});
</script>
</body>
{% endblock %}

View File

@@ -4,61 +4,51 @@
{% block content %}
<body>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<div class="home">
<div class="bg">
<img src="{{ url_for('static', filename='images/techturb.gif') }}">
<div class="buttons">
<button onclick="window.open('https://www.instagram.com/technicalturbulence23344/', '_blank');">
<i data-feather="instagram"></i>
</button>
<button onclick="window.open('mailto:technicalturbulence@gmail.com', '_blank');"> <i data-feather="mail"></i>
</button>
<button onclick="window.open('https://youtube.com/@TechnicalTurbulenceFTC', '_blank');"> <i data-feather="youtube"></i></button>
</div>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<div class="home">
<div class="bg">
<div class="overlay-container">
<img class="base" src="{{ url_for('static', filename='images/michiana.png') }}">
<img class="overlay" src="{{ url_for('static', filename='images/techturb.gif') }}">
</div>
<div class="footer-text">FTC #23344 <br><button class="home-but" onclick="window.open('https://www.instagram.com/technicalturbulence23344/', '_blank');"><i data-feather="instagram"></i>
</button> <button class="home-but" onclick="window.open('mailto:technicalturbulence@gmail.com', '_blank');">
<i data-feather="mail"></i>
</button> <button class="home-but" onclick="window.open('https://youtube.com/@TechnicalTurbulenceFTC', '_blank');">
<i data-feather="youtube"></i>
</button></div>
<div class="border-triangle"></div>
</div>
<h1 class="heading"><span class="emoji about">About</span></h1>
<hr>
<!-- <h1 class="heading"><span class="emoji about">About</span></h1>
<hr> -->
<div class="home-info">
<h1 class="sub-header" id="cool-font">👋 We are Technical Turbulence.</h1>
<div class="about-section-imgp">
<div class="about-sec-img">
<img src="{{ url_for('static', filename='images/teeaam.png') }}">
<div class="hero-image-section">
<img src="{{ url_for('static', filename='images/teeaam.png') }}" class="hero-team-image">
<div class="hero-overlay"></div>
<div class="hero-text-container">
<h1 class="hero-title">👋 We are Technical Turbulence.</h1>
<p class="hero-description">Team 23344, Technical Turbulence, is a community-based returning team situated
around Plano and Frisco Texas, comprising nine members primarily consisting of sophomores from
different high schools. Our rookie year was 2023 and we hope to learn much more in the years to
come. We want to grow our numbers and increase our outreach towards different communities so we can
be the best that we can.</p>
<p class="hero-description">Since we are designated as veterans this year, our members bring substantial
experience from their involvement with FTC 12900 Quantum Claw and 22201 The Edge Robotics. Operating
from our dedicated garage workshop, we uphold the fundamental values of FIRST, integrating Gracious
Professionalism into our daily endeavors.</p>
</div>
<p class="sub-content">Team 23344, Technical Turbulence, is a community-based returning team situated
around Plano and Frisco Texas, comprising nine members primarily consisting of sophomores from
different high schools. Our rookie year was 2023 and we hope to learn much more in the years to
come. We want to grow our numbers and increase our outreach towards different communities so we can
be the best that we can.</p>
</div>
<div class="about-section-imgp">
<!-- <div class="about-sec-img">
<img src="{{ url_for('static', filename='images/robo.png') }}">
</div> -->
<p class="sub-content">Since we are designated as veterans this year, our members bring substantial
experience from their involvement with FTC 12900 Quantum Claw and 22201 The Edge Robotics. Operating
from our dedicated garage workshop, we uphold the fundamental values of FIRST, integrating Gracious
Professionalism into our daily endeavors. </p>
</div>
<div class="stats-container">
<h1 class="heading"><span class="emoji stats">Our stats</span></h1>
<hr>
<div class="stats-cards">
{% for stat in stats %}
<div class="stats-card">
<h1 class="stats-card-header">2</h1>
<p class="stats-card-info">year of robotics</p>
</div>
<div class="stats-card">
<h1 class="stats-card-header">2</h1>
<p class="stats-card-info">awards this season</p>
</div>
<div class="stats-card">
<h1 class="stats-card-header">7</h1>
<p class="stats-card-info">total awards won</p>
<h1 class="stats-card-header">{{ stat.value }}</h1>
<p class="stats-card-info">{{ stat.label }}</p>
</div>
{% endfor %}
</div>
<button class="stats-button" onclick="window.location.href = '{{ url_for('competitions') }}' ; ">View
@@ -89,19 +79,19 @@
<hr>
<div class="home-info">
<h1 class="sub-header">❤️ We couldn't have done it without...</h1>
<p class="sub-content">We, FTC team Technical Turbulence, want to inspire the next generation by sharing our
journey in robotics and the exciting world of FTC. By demonstrating our robot and showcasing the
engineering behind it, we hope to spark curiosity in young minds about STEM fields.
journey in robotics and the exciting world of FTC. By showcasing the
engineering behind our robot, and with the help of our sponsors, we hope to spark curiosity in young minds about STEM fields.
</p>
<h1 class="sub-header">❤️ And we couldn't have done it without...</h1>
<div class="sponsors-container" id="sponnnnn">
<img class="sponsors-card" src="{{ url_for('static', filename='images/ray.png') }}">
<img class="sponsors-card" src="{{ url_for('static', filename='images/cen3.png') }}">
<img class="sponsors-card" src="{{ url_for('static', filename='images/ti.png') }}">
<img class="sponsors-card" src="{{ url_for('static', filename='images/twc.png') }}">
<img src="{{ url_for('static', filename='images/fw.png') }}" alt="Image 3">
<img class="sponsors-card" src="{{ url_for('static', filename='images/fw.png') }}">
</div>
<div class="sponsors-more-container">
@@ -117,7 +107,5 @@
<script>
feather.replace({ width: "40", height: "40" });
</script>
</body>
{% endblock %}

View File

@@ -4,43 +4,24 @@
{% block content %}
<body>
<div class="sponsors">
<div class="sponsors">
<br>
<h1 class="heading" id="spon"><span class="emoji sponsors">Sponsors</span></h1>
<hr>
<p class="info">❤️ companies of various sizes sponsor our initiatives. ❤️</p>
<div class="sponsors-container">
<div class="card-container">
<a href="https://www.rtx.com/" target="_blank" class="card-sponsors">
{% for sponsor in sponsors %}
<a href="{{ sponsor.website_url }}" target="_blank" class="card-sponsors">
<div class="card-content-sponsors">
<img src="{{ url_for('static', filename='images/ray.png') }}" alt="Image 1">
</div>
</a>
<a href="https://www.smilesinfrisco.com/" target="_blank" class="card-sponsors">
<div class="card-content-sponsors">
<img src="{{ url_for('static', filename='images/cen3.png') }}" alt="Image 2">
</div>
</a>
<a href="https://www.ti.com/" target="_blank" class="card-sponsors">
<div class="card-content-sponsors">
<img src="{{ url_for('static', filename='images/ti.png') }}" alt="Image 3">
</div>
</a>
<a href="https://www.twc.texas.gov/" target="_blank" class="card-sponsors">
<div class="card-content-sponsors">
<img src="{{ url_for('static', filename='images/twc.png') }}" alt="Image 3">
</div>
</a>
<a href="https://www.fabworks.com/" target="_blank" class="card-sponsors">
<div class="card-content-sponsors">
<img src="{{ url_for('static', filename='images/fw.png') }}" alt="Image 3">
<img src="{{ url_for('static', filename=sponsor.logo_path) }}" alt="{{ sponsor.name }}">
</div>
</a>
{% endfor %}
</div>
</div>
</div>
</body>
{% endblock %}
{% endblock %}