giseldo commited on
Commit
2372f0c
·
1 Parent(s): 5b74322
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Usa uma imagem Python como base
2
+ FROM python:3.9
3
+
4
+ # Define o diretório de trabalho dentro do contêiner
5
+ WORKDIR /app
6
+
7
+ # Copia os arquivos do projeto para o contêiner
8
+ COPY . /app
9
+
10
+ # Instala as dependências
11
+ RUN pip install -r requirements.txt
12
+
13
+ # Expõe a porta do Flask
14
+ EXPOSE 5000
15
+
16
+ # Comando para rodar o app
17
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, jsonify
2
+ import json
3
+
4
+ app = Flask(__name__)
5
+
6
+ @app.route('/')
7
+ def index():
8
+ return render_template('index.html')
9
+
10
+ @app.route('/api/events')
11
+ def get_events():
12
+ with open('data/events.json') as f:
13
+ events = json.load(f)
14
+ return jsonify(events)
15
+
16
+ if __name__ == "__main__":
17
+ app.run(host="0.0.0.0", port=7860)
data/events.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "ITS 2025",
4
+ "full_name": "International Conference on Intelligent Tutoring Systems 2025",
5
+ "dates": "September 17-21, 2025",
6
+ "location": "Alexandroupolis, Greece",
7
+ "abstract_deadline": "March 01, 2025",
8
+ "submission_deadline": "March 01, 2025",
9
+ "tags": ["tutoring-systems"],
10
+ "link": "https://iis-international.org/its2025-generative-systems/"
11
+ },
12
+ {
13
+ "name": "CSBC 2025",
14
+ "full_name": "Congresso da Sociedade Brasileira de Computação 2025",
15
+ "dates": "July 20-24, 2025",
16
+ "location": "Maceio, Alagoas",
17
+ "abstract_deadline": "March 24, 2025",
18
+ "submission_deadline": "March 24, 2025",
19
+ "tags": ["software engeniring", "computer science"],
20
+ "link": "https://csbc.sbc.org.br/2025/"
21
+ }
22
+ ]
requirement.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ flask
static/css/styles.css ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ background-color: #f4f4f4;
4
+ margin: 0;
5
+ padding: 0;
6
+ }
7
+
8
+ .container {
9
+ width: 80%;
10
+ margin: auto;
11
+ overflow: hidden;
12
+ }
13
+
14
+ h1 {
15
+ text-align: center;
16
+ margin-top: 20px;
17
+ }
18
+
19
+ .filters {
20
+ text-align: center;
21
+ margin-bottom: 20px;
22
+ }
23
+
24
+ .events-grid {
25
+ display: flex;
26
+ flex-wrap: wrap;
27
+ justify-content: space-around;
28
+ }
29
+
30
+ .event-card {
31
+ background: white;
32
+ border: 1px solid #ddd;
33
+ border-radius: 5px;
34
+ margin: 10px;
35
+ padding: 20px;
36
+ width: 30%;
37
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
38
+ }
39
+
40
+ .event-card h2 {
41
+ margin-top: 0;
42
+ }
43
+
44
+ .event-card p {
45
+ margin: 5px 0;
46
+ }
47
+
48
+ .event-card .tags {
49
+ margin-top: 10px;
50
+ }
51
+
52
+ .event-card .tag {
53
+ display: inline-block;
54
+ background: #007bff;
55
+ color: white;
56
+ padding: 5px 10px;
57
+ border-radius: 3px;
58
+ margin-right: 5px;
59
+ }
60
+
61
+ .event-card .time-remaining {
62
+ color: red;
63
+ font-weight: bold;
64
+ }
65
+
66
+ .modal {
67
+ display: none;
68
+ position: fixed;
69
+ z-index: 1;
70
+ left: 0;
71
+ top: 0;
72
+ width: 100%;
73
+ height: 100%;
74
+ overflow: auto;
75
+ background-color: rgb(0,0,0);
76
+ background-color: rgba(0,0,0,0.4);
77
+ padding-top: 60px;
78
+ }
79
+
80
+ .modal-content {
81
+ background-color: #fefefe;
82
+ margin: 5% auto;
83
+ padding: 20px;
84
+ border: 1px solid #888;
85
+ width: 80%;
86
+ max-width: 600px;
87
+ border-radius: 10px;
88
+ }
89
+
90
+ .close-button {
91
+ color: #aaa;
92
+ float: right;
93
+ font-size: 28px;
94
+ font-weight: bold;
95
+ }
96
+
97
+ .close-button:hover,
98
+ .close-button:focus {
99
+ color: black;
100
+ text-decoration: none;
101
+ cursor: pointer;
102
+ }
static/js/scripts.js ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ fetch('/api/events')
3
+ .then(response => response.json())
4
+ .then(events => {
5
+ const eventsGrid = document.getElementById('events-grid');
6
+ events.forEach(event => {
7
+ const eventCard = document.createElement('div');
8
+ eventCard.className = 'event-card';
9
+
10
+ const timeRemaining = calculateTimeRemaining(event.submission_deadline);
11
+
12
+ eventCard.innerHTML = `
13
+ <h2>${event.name}</h2>
14
+ <p><strong>Dates:</strong> ${event.dates}</p>
15
+ <p><strong>Location:</strong> ${event.location}</p>
16
+ <p><strong>Abstract Deadline:</strong> ${event.abstract_deadline}</p>
17
+ <p><strong>Submission Deadline:</strong> ${event.submission_deadline}</p>
18
+ <p class="time-remaining">${timeRemaining}</p>
19
+ <div class="tags">
20
+ ${event.tags.map(tag => `<span class="tag">${tag}</span>`).join('')}
21
+ </div>
22
+ `;
23
+ eventCard.addEventListener('click', () => openModal(event, timeRemaining));
24
+ eventsGrid.appendChild(eventCard);
25
+ });
26
+ });
27
+
28
+ const modal = document.getElementById('event-modal');
29
+ const closeButton = document.querySelector('.close-button');
30
+
31
+ closeButton.addEventListener('click', () => {
32
+ modal.style.display = 'none';
33
+ });
34
+
35
+ window.addEventListener('click', (event) => {
36
+ if (event.target == modal) {
37
+ modal.style.display = 'none';
38
+ }
39
+ });
40
+ });
41
+
42
+ function calculateTimeRemaining(deadline) {
43
+ const deadlineDate = new Date(deadline);
44
+ const now = new Date();
45
+ const timeDiff = deadlineDate - now;
46
+
47
+ if (timeDiff <= 0) {
48
+ return 'Deadline passed';
49
+ }
50
+
51
+ const hours = Math.floor(timeDiff / (1000 * 60 * 60));
52
+ const minutes = Math.floor((timeDiff % (1000 * 60 * 60)) / (1000 * 60));
53
+ const seconds = Math.floor((timeDiff % (1000 * 60)) / 1000);
54
+
55
+ return `in about ${hours} hours, ${minutes} minutes, and ${seconds} seconds`;
56
+ }
57
+
58
+ function openModal(event, timeRemaining) {
59
+ document.getElementById('modal-event-name').innerText = event.name;
60
+ document.getElementById('modal-event-full-name').innerText = event.full_name; // Add this line
61
+ document.getElementById('modal-event-dates').innerText = event.dates;
62
+ document.getElementById('modal-event-location').innerText = event.location;
63
+ document.getElementById('modal-event-abstract-deadline').innerText = event.abstract_deadline;
64
+ document.getElementById('modal-event-submission-deadline').innerText = event.submission_deadline;
65
+ document.getElementById('modal-event-time-remaining').innerText = timeRemaining;
66
+ document.getElementById('modal-event-tags').innerHTML = event.tags.map(tag => `<span class="tag">${tag}</span>`).join('');
67
+ document.getElementById('modal-event-link').href = event.link;
68
+
69
+ const modal = document.getElementById('event-modal');
70
+ modal.style.display = 'block';
71
+ }
templates/index.html ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Conference Deadlines</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <h1>AI Conference Deadlines</h1>
12
+ <div class="filters">
13
+ <!-- ...existing code for filters... -->
14
+ </div>
15
+ <div class="events-grid" id="events-grid">
16
+ <!-- Events will be loaded here by JavaScript -->
17
+ </div>
18
+ </div>
19
+ <div id="event-modal" class="modal">
20
+ <div class="modal-content">
21
+ <span class="close-button">&times;</span>
22
+ <h2 id="modal-event-name"></h2>
23
+ <p><strong>Full Name:</strong> <span id="modal-event-full-name"></span></p>
24
+ <p><strong><i class="fa fa-calendar"></i> Dates:</strong> <span id="modal-event-dates"></span></p>
25
+ <p><strong><i class="fa fa-map-marker"></i> Location:</strong> <span id="modal-event-location"></span></p>
26
+ <p><strong>Abstract Deadline:</strong> <span id="modal-event-abstract-deadline"></span></p>
27
+ <p><strong>Submission Deadline:</strong> <span id="modal-event-submission-deadline"></span></p>
28
+ <p><strong>Time Remaining:</strong> <span id="modal-event-time-remaining"></span></p>
29
+ <p><strong>Tags:</strong> <div class="tags" id="modal-event-tags"></div></span></p>
30
+ <p><a id="modal-event-link" href="#" target="_blank">Visit website</a></p>
31
+ </div>
32
+ </div>
33
+ <script src="{{ url_for('static', filename='js/scripts.js') }}"></script>
34
+ <footer style="text-align: center;">
35
+ <p>by Giseldo Neo</p>
36
+ </footer>
37
+ </body>
38
+ </html>