forked from orson/bachemap
fixed crosshair and part of the dashboard displays
This commit is contained in:
parent
c99a897d92
commit
ee49adc084
6
app.py
6
app.py
@ -275,7 +275,8 @@ def create_app(config=Config):
|
|||||||
qr_update = mongo.db.users.update_one({'_id': ObjectId(current_user.id)}, {'$set': {'referral_code': invite_code}})
|
qr_update = mongo.db.users.update_one({'_id': ObjectId(current_user.id)}, {'$set': {'referral_code': invite_code}})
|
||||||
print(invite_code)
|
print(invite_code)
|
||||||
if not current_user.is_admin:
|
if not current_user.is_admin:
|
||||||
pins = list(mongo.db.pins.find({"added_by": current_user.id}))
|
pins = list(mongo.db.pins.find({"added_by": current_user.id}).sort("time", -1))
|
||||||
|
print(pins)
|
||||||
return render_template('dashboard.html', pins=pins, invite_code=invite_code)
|
return render_template('dashboard.html', pins=pins, invite_code=invite_code)
|
||||||
if current_user.is_admin:
|
if current_user.is_admin:
|
||||||
users = list(mongo.db.users.find())
|
users = list(mongo.db.users.find())
|
||||||
@ -362,7 +363,7 @@ def create_app(config=Config):
|
|||||||
if len(username) >= 2:
|
if len(username) >= 2:
|
||||||
cleaned_username = username[0] + "***" + username[-1]
|
cleaned_username = username[0] + "***" + username[-1]
|
||||||
else:
|
else:
|
||||||
cleaned_username = username
|
cleaned_username = username+"***"+random.choice(string.ascii_letters, k=1)
|
||||||
cleaned_leaders.append({"username": cleaned_username, "count": count})
|
cleaned_leaders.append({"username": cleaned_username, "count": count})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error processing user_id {user_id}: {e}")
|
print(f"Error processing user_id {user_id}: {e}")
|
||||||
@ -385,6 +386,7 @@ def create_app(config=Config):
|
|||||||
|
|
||||||
# Calculate percentage (handle case where total_users might be 0)
|
# Calculate percentage (handle case where total_users might be 0)
|
||||||
active_percentage = round((active_users / total_users) * 100, 1) if total_users > 0 else 0
|
active_percentage = round((active_users / total_users) * 100, 1) if total_users > 0 else 0
|
||||||
|
|
||||||
return render_template('leaderboard.html', leaders=cleaned_leaders, percentage = active_percentage)
|
return render_template('leaderboard.html', leaders=cleaned_leaders, percentage = active_percentage)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -398,7 +398,9 @@ section#pinner-modal::-webkit-scrollbar-thumb {
|
|||||||
/* Animation removed as it was causing visibility issues */
|
/* Animation removed as it was causing visibility issues */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dash-container {
|
||||||
|
max-width: 75vw;
|
||||||
|
}
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
.flashes {
|
.flashes {
|
||||||
@ -422,6 +424,13 @@ ul.flashes li {
|
|||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*/html/body/main/div[1]/div[1]/div[2]/svg/g/path */
|
||||||
|
|
||||||
|
path {
|
||||||
|
cursor: crosshair !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Animations */
|
/* Animations */
|
||||||
@keyframes fadeOut {
|
@keyframes fadeOut {
|
||||||
0% { opacity: 1; transform: translateY(0); }
|
0% { opacity: 1; transform: translateY(0); }
|
||||||
@ -474,7 +483,9 @@ ul.flashes li {
|
|||||||
nav ul {
|
nav ul {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
#dash-container {
|
||||||
|
max-width: 95vw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 812px) {
|
@media (min-width: 812px) {
|
||||||
|
|||||||
@ -28,7 +28,14 @@
|
|||||||
|
|
||||||
</form>
|
</form>
|
||||||
<script>
|
<script>
|
||||||
|
submitButton = document.getElementById('submit');
|
||||||
|
if (submitButton) {
|
||||||
|
submitButton.addEventListener('click', function() {
|
||||||
|
// Disable the button after submission
|
||||||
|
submitButton.disabled = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
document.getElementById('submit').onclick=function(e){
|
document.getElementById('submit').onclick=function(e){
|
||||||
document.getElementById('progress').hidden=''
|
document.getElementById('progress').hidden='false'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -17,14 +17,15 @@
|
|||||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||||
crossorigin=""></script>
|
crossorigin=""></script>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
<link rel="icon" href="{{ url_for('static', filename='images/favico.ico') }}" type="image/x-icon">
|
||||||
<link rel="icon" href="{{ url_for('static', filename='images/favico.ico') }}" type="image/x-icon">
|
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favico.ico') }}" type="image/x-icon">
|
||||||
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favico.ico') }}" type="image/x-icon">
|
<!-- <script src="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/leaflet.markercluster.js" type="text/javascript"></script> -->
|
||||||
<!-- <script src="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/leaflet.markercluster.js" type="text/javascript"></script> -->
|
<script type="application/importmap" src="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/leaflet.markercluster-src.js.map"></script>
|
||||||
<script type="application/importmap" src="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/leaflet.markercluster-src.js.map"></script>
|
<link href="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/MarkerCluster.css">
|
||||||
<link href="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/MarkerCluster.css">
|
<link href="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/MarkerCluster.Default.css">
|
||||||
<link href="https://app.unpkg.com/leaflet.markercluster@1.4.1/files/dist/MarkerCluster.Default.css">
|
|
||||||
<script src="{{ url_for('static', filename='leaflet.markercluster.js')}}"></script>
|
<script src="{{ url_for('static', filename='leaflet.markercluster.js')}}"></script>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
||||||
|
|
||||||
<!-- <script src="{{ url_for('static', filename='src/MarkerClusterGroup.js')}}"></script> -->
|
<!-- <script src="{{ url_for('static', filename='src/MarkerClusterGroup.js')}}"></script> -->
|
||||||
|
|
||||||
<!-- <script type="importmap" src="{{ url_for('static', filename='leaflet.markercluster.js.map')}}"></script>
|
<!-- <script type="importmap" src="{{ url_for('static', filename='leaflet.markercluster.js.map')}}"></script>
|
||||||
@ -106,7 +107,7 @@
|
|||||||
</section>
|
</section>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="flashes">
|
<div class="flashes">
|
||||||
<h3>Seguramente quieres hacer <a href="{{ url_for('thelogin') }}">login</a></h3>
|
<h3>Seguramente quieres <a href="{{ url_for('thelogin') }}">iniciar sesión</a></h3>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -132,7 +133,9 @@
|
|||||||
pinner_button_top.addEventListener('click', toggleSlide);
|
pinner_button_top.addEventListener('click', toggleSlide);
|
||||||
}
|
}
|
||||||
const cancel_add = document.getElementById("cancel-add");
|
const cancel_add = document.getElementById("cancel-add");
|
||||||
|
if (cancel_add) {
|
||||||
cancel_add.addEventListener('click', toggleSlide);
|
cancel_add.addEventListener('click', toggleSlide);
|
||||||
|
}
|
||||||
observer.observe(document.body, { childList: true, subtree: true });
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@ -28,7 +28,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
#file-fallback {
|
#file-fallback {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -41,6 +40,16 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
#location-status {
|
||||||
|
position: fixed;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
color: white;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -50,21 +59,21 @@
|
|||||||
<canvas id="canvas"></canvas>
|
<canvas id="canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="location-status">Esperando ubicación...</div>
|
||||||
|
|
||||||
<div style="position: absolute; bottom: 0; width: 100%; display: flex; flex-direction: column; padding: 10px; box-sizing: border-box;">
|
<div style="position: absolute; bottom: 0; width: 100%; display: flex; flex-direction: column; padding: 10px; box-sizing: border-box;">
|
||||||
<button id="capture-btn" class="control-button" style="margin: 10px; right:20%"><i class="fa fas fa-camera"></i></button>
|
<button id="capture-btn" class="control-button" style="margin: 10px; right:20%"><i class="fa fas fa-camera"></i></button>
|
||||||
<div style="display: flex; justify-content: space-between; width: 100%; box-sizing: border-box;">
|
<div style="display: flex; justify-content: space-between; width: 100%; box-sizing: border-box;">
|
||||||
<button id="retake-btn" class="control-button" style="display: none; margin: 10px 5px 10px 10px; flex: 1; left:20%; background-color: rgba(231, 9, 9, 0.671);color:white; left:20%"><i class="fas fa-redo"></i></button>
|
<button id="retake-btn" class="control-button" style="display: none; margin: 10px 5px 10px 10px; flex: 1; left:20%; background-color: rgba(231, 9, 9, 0.671);color:white; left:20%"><i class="fas fa-redo"></i></button>
|
||||||
<button id="send-btn" class="control-button" style="display: none; margin: 10px 10px 10px 5px; flex: 1; background-color: rgba(49, 182, 28, 0.6);color:white; right: 20%;"><i class="fas fa-paper-plane"></i></button>
|
<button id="send-btn" class="control-button" style="display: none; margin: 10px 10px 10px 5px; flex: 1; background-color: rgba(49, 182, 28, 0.6);color:white; right: 20%;" disabled><i class="fas fa-paper-plane"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<form id="camera-form" action="{{ url_for('camera') }}" method="POST" enctype="multipart/form-data" style="display:none;">
|
<form id="camera-form" action="{{ url_for('camera') }}" method="POST" enctype="multipart/form-data" style="display:none;">
|
||||||
<input type="hidden" name="latitude" id="latitude" value="">
|
<input type="hidden" name="latitude" id="latitude" value="">
|
||||||
<input type="hidden" name="longitude" id="longitude" value="">
|
<input type="hidden" name="longitude" id="longitude" value="">
|
||||||
<input type="hidden" name="has_image" id="has_image" value="false">
|
<input type="hidden" name="has_image" id="has_image" value="false">
|
||||||
|
|
||||||
<!-- Fallback file input for unsupported browsers -->
|
|
||||||
<div id="file-fallback">
|
<div id="file-fallback">
|
||||||
<label for="photo">Toma o selecciona una foto:</label>
|
<label for="photo">Toma o selecciona una foto:</label>
|
||||||
<input type="file" name="photo" id="photo" accept="image/*" capture="environment" required>
|
<input type="file" name="photo" id="photo" accept="image/*" capture="environment" required>
|
||||||
@ -82,6 +91,11 @@
|
|||||||
const form = document.getElementById('camera-form');
|
const form = document.getElementById('camera-form');
|
||||||
const fallbackInput = document.getElementById('file-fallback');
|
const fallbackInput = document.getElementById('file-fallback');
|
||||||
const hasImageInput = document.getElementById('has_image');
|
const hasImageInput = document.getElementById('has_image');
|
||||||
|
const locationStatus = document.getElementById('location-status');
|
||||||
|
|
||||||
|
// Location tracking variables
|
||||||
|
let hasLocation = false;
|
||||||
|
let watchId = null;
|
||||||
|
|
||||||
// Set up camera stream
|
// Set up camera stream
|
||||||
async function setupCamera() {
|
async function setupCamera() {
|
||||||
@ -109,6 +123,17 @@
|
|||||||
fallbackInput.style.display = 'block';
|
fallbackInput.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we can enable the send button
|
||||||
|
function updateSendButtonState() {
|
||||||
|
if (hasImageInput.value === 'true' && hasLocation) {
|
||||||
|
sendBtn.disabled = false;
|
||||||
|
sendBtn.style.opacity = '1';
|
||||||
|
} else {
|
||||||
|
sendBtn.disabled = true;
|
||||||
|
sendBtn.style.opacity = '0.5';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Capture photo from video feed
|
// Capture photo from video feed
|
||||||
captureBtn.addEventListener('click', function() {
|
captureBtn.addEventListener('click', function() {
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
@ -128,6 +153,9 @@
|
|||||||
|
|
||||||
// Mark that we have an image
|
// Mark that we have an image
|
||||||
hasImageInput.value = 'true';
|
hasImageInput.value = 'true';
|
||||||
|
|
||||||
|
// Check if we can enable send button
|
||||||
|
updateSendButtonState();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Retake photo
|
// Retake photo
|
||||||
@ -143,7 +171,7 @@
|
|||||||
|
|
||||||
// Send photo
|
// Send photo
|
||||||
sendBtn.addEventListener('click', function() {
|
sendBtn.addEventListener('click', function() {
|
||||||
if (hasImageInput.value === 'true') {
|
if (hasImageInput.value === 'true' && hasLocation) {
|
||||||
// Convert canvas to blob and append to FormData
|
// Convert canvas to blob and append to FormData
|
||||||
canvas.toBlob(function(blob) {
|
canvas.toBlob(function(blob) {
|
||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
@ -169,26 +197,62 @@
|
|||||||
}
|
}
|
||||||
}).catch(error => console.error('Error:', error));
|
}).catch(error => console.error('Error:', error));
|
||||||
}, 'image/jpeg', 0.9);
|
}, 'image/jpeg', 0.9);
|
||||||
|
} else if (!hasLocation) {
|
||||||
|
alert('Esperando ubicación GPS. Por favor espera.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Request Geolocation Permission and Set Form Fields
|
// Request Geolocation Permission and Set Form Fields
|
||||||
if ('geolocation' in navigator) {
|
if ('geolocation' in navigator) {
|
||||||
|
locationStatus.textContent = 'Obteniendo ubicación...';
|
||||||
|
locationStatus.style.backgroundColor = 'rgba(255, 165, 0, 0.7)'; // Orange
|
||||||
|
|
||||||
|
// Start watching position for more accurate results
|
||||||
|
watchId = navigator.geolocation.watchPosition(
|
||||||
|
(position) => {
|
||||||
|
document.getElementById('latitude').value = position.coords.latitude;
|
||||||
|
document.getElementById('longitude').value = position.coords.longitude;
|
||||||
|
hasLocation = true;
|
||||||
|
locationStatus.textContent = 'Ubicación: ✓';
|
||||||
|
locationStatus.style.backgroundColor = 'rgba(0, 128, 0, 0.7)'; // Green
|
||||||
|
updateSendButtonState();
|
||||||
|
|
||||||
|
// Once we get a good reading, we can stop watching
|
||||||
|
if (position.coords.accuracy < 100) { // If accuracy is under 100 meters
|
||||||
|
navigator.geolocation.clearWatch(watchId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error('Error getting location:', error);
|
||||||
|
locationStatus.textContent = 'Error de ubicación';
|
||||||
|
locationStatus.style.backgroundColor = 'rgba(255, 0, 0, 0.7)'; // Red
|
||||||
|
|
||||||
|
// Try getting location once more with different options
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => {
|
(position) => {
|
||||||
document.getElementById('latitude').value = position.coords.latitude;
|
document.getElementById('latitude').value = position.coords.latitude;
|
||||||
document.getElementById('longitude').value = position.coords.longitude;
|
document.getElementById('longitude').value = position.coords.longitude;
|
||||||
|
hasLocation = true;
|
||||||
|
locationStatus.textContent = 'Ubicación: ✓';
|
||||||
|
locationStatus.style.backgroundColor = 'rgba(0, 128, 0, 0.7)'; // Green
|
||||||
|
updateSendButtonState();
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.error('Error getting location:', error);
|
console.error('Final error getting location:', error);
|
||||||
|
locationStatus.textContent = 'Error de ubicación';
|
||||||
|
},
|
||||||
|
{ maximumAge: 60000, timeout: 10000 }
|
||||||
|
);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
timeout: 5000
|
timeout: 10000
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error('Geolocation not supported in this browser.');
|
console.error('Geolocation not supported in this browser.');
|
||||||
|
locationStatus.textContent = 'GPS no soportado';
|
||||||
|
locationStatus.style.backgroundColor = 'rgba(255, 0, 0, 0.7)'; // Red
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -7,11 +7,11 @@
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="container-fluid" style="max-width: 75vw; background-color: rgba(189, 216, 3, 0.9); padding: 3rem; padding-top:10rem;display:block">
|
<div class="container-fluid" id="dash-container" style="background-color: rgba(189, 216, 3, 0.9); padding: 3rem; padding-top:10rem;display:block">
|
||||||
<h3>Hola <span style="color: darkgreen;">{{current_user.username}}</span></h3>
|
<h3>Hola <span style="color: darkgreen;">{{current_user.username}}</span></h3>
|
||||||
<p>Aquí puedes ver los pines que has agregado y consultar tu enlace/QR de invitación. Cada vez que recargas esta página, tu enlace de invitacón cambia y el anterior se vuelve inválido.</p>
|
<p>Aquí puedes ver los pines que has agregado y consultar tu enlace/QR de invitación. Cada vez que recargas esta página, tu enlace de invitacón cambia y el anterior se vuelve inválido.</p>
|
||||||
<div class="grid" style="padding-bottom: 2rem;">
|
<div class="grid" style="padding-bottom: 2rem;">
|
||||||
<div id="qrgen" style="padding-left: 5rem;">
|
<div id="qrgen" style="display:flex;justify-content: center;">
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var qrcode = new QRCode(document.getElementById("qrgen"), {
|
var qrcode = new QRCode(document.getElementById("qrgen"), {
|
||||||
@ -23,21 +23,56 @@
|
|||||||
correctLevel : QRCode.CorrectLevel.L
|
correctLevel : QRCode.CorrectLevel.L
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<div>
|
<div style="display: grid; justify-content: center;">
|
||||||
<h2>Tu link es:</h2>
|
<input type="text" id="invite_code" value="{{invite_code}}" style="" hidden="true">
|
||||||
<p><a href="https://baches.qro.mx/registrame/{{invite_code}}">https://baches.qro.mx/registrame/{{invite_code}}</a></p>
|
<button id="copy-button" onclick="copyToClipboard()" style="background-color: rgb(255, 213, 0); color: rgb(0, 0, 0); border: none; padding: 12px 20px; border-radius: 25px; cursor: pointer; margin-top: 15px; display: flex; align-items: center; justify-content: center; font-size:1.2rem;font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.2); transition: all 0.3s ease;">
|
||||||
|
<span style="font-size: 2rem; margin-right: 10px;">📋</span> Copia tu link de invitación
|
||||||
|
</button>
|
||||||
|
<script>
|
||||||
|
function copyToClipboard() {
|
||||||
|
var copyText = document.getElementById("invite_code");
|
||||||
|
copyText.select();
|
||||||
|
// Modern clipboard API
|
||||||
|
navigator.clipboard.writeText("https://baches.qro.mx/registrame/" + copyText.value).then(() => {
|
||||||
|
console.log('Link copied successfully');
|
||||||
|
}).catch(err => {
|
||||||
|
// Fallback for browsers that don't support clipboard API
|
||||||
|
document.execCommand("copy");
|
||||||
|
console.log('Using fallback clipboard method');
|
||||||
|
});
|
||||||
|
|
||||||
|
var button = document.getElementById("copy-button");
|
||||||
|
|
||||||
|
// Change to copied state
|
||||||
|
button.style.backgroundColor = "green";
|
||||||
|
button.style.color = "white";
|
||||||
|
button.style.transition = "all 0.5s ease";
|
||||||
|
button.innerHTML = "<span style=\"font-size: 2rem; margin-right: 10px;\">✓</span> ¡Copiado!";
|
||||||
|
|
||||||
|
// Revert back after 2 seconds
|
||||||
|
setTimeout(function() {
|
||||||
|
button.style.backgroundColor = "rgb(255, 213, 0)";
|
||||||
|
button.style.color = "rgb(0, 0, 0)";
|
||||||
|
button.style.transition = "all 0.5s ease";
|
||||||
|
button.innerHTML = "<span style=\"font-size: 2rem; margin-right: 10px;\">📋</span> Copia tu link de invitación";
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<p>¡Cada vez que recargas esta página, tu código de invitación cambia para prevenir malos usos! </p>
|
||||||
|
<p>Asegúrate de que a quien invites use su invitación de inmediato 😈</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if pins %}
|
{% if pins %}
|
||||||
{% for pin in pins %}
|
{% for pin in pins %}
|
||||||
|
<div class="pin-card" style="{% if pin.reviewed and pin.reviewed == false %} background-color: rgb(255, 170, 0) {% endif %};margin-bottom: 2rem; background-color: #f8f9fa; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); overflow: hidden; display: flex; flex-wrap: wrap;">
|
||||||
<div class="pin-card" style="margin-bottom: 2rem; background-color: #f8f9fa; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); overflow: hidden; display: flex; flex-wrap: wrap;">
|
|
||||||
<div class="pin-image" style="flex: 0 0 250px; padding: 15px; display: flex; align-items: center; justify-content: center;">
|
<div class="pin-image" style="flex: 0 0 250px; padding: 15px; display: flex; align-items: center; justify-content: center;">
|
||||||
<img style="max-width: 100%; max-height: 200px; object-fit: cover; border-radius: 4px;" src="{{ pin.photo }}" alt="Foto de mejora urbana">
|
<img style="max-width: 100%; max-height: 200px; object-fit: cover; border-radius: 4px;" src="{{ pin.photo }}" alt="Foto de mejora urbana">
|
||||||
</div>
|
</div>
|
||||||
<div class="pin-data" style="flex: 1; padding: 15px;">
|
<div class="pin-data" style="flex: 1; padding: 15px;">
|
||||||
<h4 style="margin-top: 0; color: #333;">{{ pin.typeofpin }}</h4>
|
<h4 style="margin-top: 0; color: #333;">{{ pin.typeofpin }}</h4>
|
||||||
<p><strong>Agregado el:</strong> {{ pin.time }}</p>
|
<p><strong>Agregado:</strong> {{ pin.time }}</p>
|
||||||
|
{% if pin.reviewed and pin.reviewed == False %}<p><strong>Estado:</strong> Pendiente de revisión</p>{% endif %}
|
||||||
|
<p><strong>Modificado:</strong> {% if pin.last_mod %} {{pin.last_mod}} {% endif %}</p>
|
||||||
<p><strong>Descripción:</strong> {{ pin.description }}</p>
|
<p><strong>Descripción:</strong> {{ pin.description }}</p>
|
||||||
<p><strong>Dirección:</strong> {{ pin.address }}</p>
|
<p><strong>Dirección:</strong> {{ pin.address }}</p>
|
||||||
<p><small>Coordenadas: {{ pin.lat }}, {{ pin.lng }}</small></p>
|
<p><small>Coordenadas: {{ pin.lat }}, {{ pin.lng }}</small></p>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="map" style="height: 100%; position: static;"></div>
|
<div id="map" style="height: 100%; position: static; cursor:crosshair"></div>
|
||||||
<script>
|
<script>
|
||||||
// document.addEventListener('DOMContentLoaded', function() {
|
// document.addEventListener('DOMContentLoaded', function() {
|
||||||
var map = new L.map('map', {center: [20.57, -100.38], zoom:16, zoomControl: false });
|
var map = new L.map('map', {center: [20.57, -100.38], zoom:16, zoomControl: false });
|
||||||
@ -38,7 +38,7 @@
|
|||||||
// Improved geolocation using direct browser API
|
// Improved geolocation using direct browser API
|
||||||
function getLocation() {
|
function getLocation() {
|
||||||
if (navigator.geolocation) {
|
if (navigator.geolocation) {
|
||||||
console.warn("Geolocalización soportada en este navegador.", navigator.geolocation);
|
console.log("Geolocalización soportada en este navegador.", navigator.geolocation);
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
onLocationFound,
|
onLocationFound,
|
||||||
onLocationError,
|
onLocationError,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container" style="background-color: rgba(255,255,255,0.85); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(15px); padding:2rem; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
<div class="container" style="background-color: rgba(255,255,255,0.85); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(15px); padding:2rem; margin-top: 5rem; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="header-cta">
|
<div class="header-cta">
|
||||||
<h2 style="text-align: center; color: #172f01; margin-bottom: 1rem;">¡Hazte mapista y pon tu granito de fotoevidencia!</h2>
|
<h2 style="text-align: center; color: #172f01; margin-bottom: 1rem;">¡Hazte mapista y pon tu granito de fotoevidencia!</h2>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user