643 lines
31 KiB
HTML
643 lines
31 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Social Account Details - Account Management{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="content">
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="page-header">
|
|
<div class="page-title">
|
|
<h4>
|
|
<a href="{% url 'accounts:social_account_list' %}" class="me-3">
|
|
<i class="fas fa-arrow-left"></i>
|
|
</a>
|
|
Social Account Details
|
|
</h4>
|
|
<h6>View and manage linked social account</h6>
|
|
</div>
|
|
<div class="page-btn">
|
|
<a href="{% url 'accounts:social_account_update' object.pk %}" class="btn btn-secondary me-2">
|
|
<i class="fas fa-edit me-1"></i>Edit Settings
|
|
</a>
|
|
<a href="#" class="btn btn-primary" onclick="testConnection()">
|
|
<i class="fas fa-plug me-1"></i>Test Connection
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Account Information -->
|
|
<div class="col-lg-8 col-md-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-user-circle me-2"></i>
|
|
Account Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-2 text-center">
|
|
<div class="provider-icon-large mb-3">
|
|
{% if object.provider == 'google' %}
|
|
<i class="fab fa-google fa-4x text-danger"></i>
|
|
{% elif object.provider == 'microsoft' %}
|
|
<i class="fab fa-microsoft fa-4x text-primary"></i>
|
|
{% elif object.provider == 'github' %}
|
|
<i class="fab fa-github fa-4x text-dark"></i>
|
|
{% elif object.provider == 'linkedin' %}
|
|
<i class="fab fa-linkedin fa-4x text-info"></i>
|
|
{% elif object.provider == 'facebook' %}
|
|
<i class="fab fa-facebook fa-4x text-primary"></i>
|
|
{% elif object.provider == 'twitter' %}
|
|
<i class="fab fa-twitter fa-4x text-info"></i>
|
|
{% else %}
|
|
<i class="fas fa-link fa-4x text-secondary"></i>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-10">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Provider</label>
|
|
<div class="info-value">
|
|
<strong>{{ object.provider|default:"Google"|title }}</strong>
|
|
<small class="d-block text-muted">OAuth 2.0 Authentication</small>
|
|
</div>
|
|
</div>
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Account Email</label>
|
|
<div class="info-value">
|
|
<strong>{{ object.email|default:"john.smith@gmail.com" }}</strong>
|
|
{% if object.email_verified %}
|
|
<i class="fas fa-check-circle text-success ms-2" title="Verified"></i>
|
|
{% else %}
|
|
<i class="fas fa-exclamation-triangle text-warning ms-2" title="Unverified"></i>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Display Name</label>
|
|
<div class="info-value">
|
|
<strong>{{ object.display_name|default:"John Smith" }}</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Account Status</label>
|
|
<div class="info-value">
|
|
{% if object.is_active %}
|
|
<span class="badges bg-lightgreen">
|
|
<i class="fas fa-check-circle me-1"></i>Active
|
|
</span>
|
|
{% else %}
|
|
<span class="badges bg-lightred">
|
|
<i class="fas fa-times-circle me-1"></i>Inactive
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Login Enabled</label>
|
|
<div class="info-value">
|
|
{% if object.login_enabled %}
|
|
<span class="badge bg-success">
|
|
<i class="fas fa-sign-in-alt me-1"></i>Enabled
|
|
</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary">
|
|
<i class="fas fa-ban me-1"></i>Disabled
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Account ID</label>
|
|
<div class="info-value">
|
|
<code>{{ object.uid|default:"1234567890" }}</code>
|
|
<button class="btn btn-sm btn-outline-secondary ms-2" onclick="copyToClipboard('{{ object.uid|default:"1234567890" }}')">
|
|
<i class="fas fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-4">
|
|
<div class="col-md-6">
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Linked Date</label>
|
|
<div class="info-value">
|
|
<strong>{{ object.date_joined|default:"January 15, 2024"|date:"F d, Y" }}</strong>
|
|
<small class="d-block text-muted">{{ object.date_joined|default:"3 months ago"|timesince }} ago</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="info-group mb-3">
|
|
<label class="info-label">Last Used</label>
|
|
<div class="info-value">
|
|
<strong>{{ object.last_login|default:"Today 09:30 AM"|date:"M d, Y g:i A" }}</strong>
|
|
<small class="d-block text-muted">{{ object.last_login|default:"2 hours ago"|timesince }} ago</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Permissions & Scopes -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-key me-2"></i>
|
|
Permissions & Scopes
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="permissions-grid">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6 class="text-success mb-3">
|
|
<i class="fas fa-check-circle me-2"></i>Granted Permissions
|
|
</h6>
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-user text-primary me-3"></i>
|
|
<div>
|
|
<strong>Profile Information</strong>
|
|
<p class="text-muted small mb-0">Access to basic profile data (name, email, avatar)</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-envelope text-info me-3"></i>
|
|
<div>
|
|
<strong>Email Address</strong>
|
|
<p class="text-muted small mb-0">Access to primary email address</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% if object.provider == 'google' %}
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-calendar text-warning me-3"></i>
|
|
<div>
|
|
<strong>Calendar Access</strong>
|
|
<p class="text-muted small mb-0">Read calendar events and availability</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% if object.provider == 'github' %}
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-code-branch text-success me-3"></i>
|
|
<div>
|
|
<strong>Repository Access</strong>
|
|
<p class="text-muted small mb-0">Read public repositories</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6 class="text-muted mb-3">
|
|
<i class="fas fa-times-circle me-2"></i>Not Granted
|
|
</h6>
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-edit text-muted me-3"></i>
|
|
<div>
|
|
<strong>Write Access</strong>
|
|
<p class="text-muted small mb-0">Post or modify content on your behalf</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-users text-muted me-3"></i>
|
|
<div>
|
|
<strong>Contacts</strong>
|
|
<p class="text-muted small mb-0">Access to your contact list</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="permission-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-file text-muted me-3"></i>
|
|
<div>
|
|
<strong>File Access</strong>
|
|
<p class="text-muted small mb-0">Access to your files and documents</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<button type="button" class="btn btn-outline-primary" onclick="requestAdditionalPermissions()">
|
|
<i class="fas fa-plus me-1"></i>Request Additional Permissions
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary ms-2" onclick="revokePermissions()">
|
|
<i class="fas fa-minus me-1"></i>Revoke Permissions
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Connection History -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-history me-2"></i>
|
|
Connection History
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th>Date & Time</th>
|
|
<th>Action</th>
|
|
<th>IP Address</th>
|
|
<th>Location</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<strong>Today 09:30 AM</strong>
|
|
<small class="d-block text-muted">Apr 15, 2024</small>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-primary">Login</span>
|
|
</td>
|
|
<td>192.168.1.100</td>
|
|
<td>
|
|
<i class="fas fa-map-marker-alt text-muted me-1"></i>
|
|
New York, NY
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-success">Success</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<strong>Yesterday 02:15 PM</strong>
|
|
<small class="d-block text-muted">Apr 14, 2024</small>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-info">Token Refresh</span>
|
|
</td>
|
|
<td>192.168.1.100</td>
|
|
<td>
|
|
<i class="fas fa-map-marker-alt text-muted me-1"></i>
|
|
New York, NY
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-success">Success</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<strong>Apr 13, 08:45 AM</strong>
|
|
<small class="d-block text-muted">Apr 13, 2024</small>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-primary">Login</span>
|
|
</td>
|
|
<td>10.0.0.50</td>
|
|
<td>
|
|
<i class="fas fa-map-marker-alt text-muted me-1"></i>
|
|
Office Network
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-success">Success</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<strong>Apr 12, 11:20 AM</strong>
|
|
<small class="d-block text-muted">Apr 12, 2024</small>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-warning">Failed Login</span>
|
|
</td>
|
|
<td>203.0.113.45</td>
|
|
<td>
|
|
<i class="fas fa-map-marker-alt text-muted me-1"></i>
|
|
Unknown Location
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-danger">Failed</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="text-center mt-3">
|
|
<a href="#" class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-history me-1"></i>View Full History
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Actions Sidebar -->
|
|
<div class="col-lg-4 col-md-12">
|
|
<!-- Quick Actions -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-bolt me-2"></i>
|
|
Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-primary" onclick="testConnection()">
|
|
<i class="fas fa-plug me-2"></i>Test Connection
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="refreshToken()">
|
|
<i class="fas fa-sync me-2"></i>Refresh Token
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="syncProfile()">
|
|
<i class="fas fa-user-sync me-2"></i>Sync Profile
|
|
</button>
|
|
<button type="button" class="btn btn-outline-warning" onclick="toggleLogin()">
|
|
<i class="fas fa-sign-in-alt me-2"></i>
|
|
{% if object.login_enabled %}Disable{% else %}Enable{% endif %} Login
|
|
</button>
|
|
<hr>
|
|
<button type="button" class="btn btn-outline-danger" onclick="confirmDisconnect()">
|
|
<i class="fas fa-unlink me-2"></i>Disconnect Account
|
|
</button>
|
|
<a href="{% url 'accounts:social_account_delete' object.pk %}" class="btn btn-danger">
|
|
<i class="fas fa-trash me-2"></i>Remove Account
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Account Statistics -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-chart-bar me-2"></i>
|
|
Usage Statistics
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="stat-item mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Total Logins</span>
|
|
<strong class="text-primary">127</strong>
|
|
</div>
|
|
</div>
|
|
<div class="stat-item mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>This Month</span>
|
|
<strong class="text-success">23</strong>
|
|
</div>
|
|
</div>
|
|
<div class="stat-item mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Success Rate</span>
|
|
<strong class="text-info">98.4%</strong>
|
|
</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Failed Attempts</span>
|
|
<strong class="text-warning">2</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Security Information -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-shield-alt me-2"></i>
|
|
Security Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="security-info">
|
|
<div class="security-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-lock text-success me-3"></i>
|
|
<div>
|
|
<strong>OAuth 2.0</strong>
|
|
<small class="d-block text-muted">Secure authentication protocol</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="security-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-key text-info me-3"></i>
|
|
<div>
|
|
<strong>Token Encryption</strong>
|
|
<small class="d-block text-muted">Access tokens are encrypted</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="security-item mb-3">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-clock text-warning me-3"></i>
|
|
<div>
|
|
<strong>Token Expiry</strong>
|
|
<small class="d-block text-muted">Tokens expire automatically</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="security-item">
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-eye-slash text-secondary me-3"></i>
|
|
<div>
|
|
<strong>Privacy Protected</strong>
|
|
<small class="d-block text-muted">Limited data access only</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function testConnection() {
|
|
const button = event.target.closest('button');
|
|
const originalText = button.innerHTML;
|
|
|
|
// Show loading state
|
|
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Testing...';
|
|
button.disabled = true;
|
|
|
|
// Simulate connection test
|
|
setTimeout(() => {
|
|
alert('Connection test successful! Account is properly linked and accessible.');
|
|
button.innerHTML = originalText;
|
|
button.disabled = false;
|
|
}, 2000);
|
|
}
|
|
|
|
function refreshToken() {
|
|
const button = event.target.closest('button');
|
|
const originalText = button.innerHTML;
|
|
|
|
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Refreshing...';
|
|
button.disabled = true;
|
|
|
|
setTimeout(() => {
|
|
alert('Access token refreshed successfully.');
|
|
button.innerHTML = originalText;
|
|
button.disabled = false;
|
|
}, 2000);
|
|
}
|
|
|
|
function syncProfile() {
|
|
const button = event.target.closest('button');
|
|
const originalText = button.innerHTML;
|
|
|
|
button.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Syncing...';
|
|
button.disabled = true;
|
|
|
|
setTimeout(() => {
|
|
alert('Profile information synchronized successfully.');
|
|
button.innerHTML = originalText;
|
|
button.disabled = false;
|
|
}, 2000);
|
|
}
|
|
|
|
function toggleLogin() {
|
|
const isEnabled = {{ object.login_enabled|yesno:"true,false" }};
|
|
const action = isEnabled ? 'disable' : 'enable';
|
|
|
|
if (confirm(`Are you sure you want to ${action} login for this account?`)) {
|
|
alert(`Login ${action}d successfully.`);
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
function requestAdditionalPermissions() {
|
|
alert('This would redirect to the provider to request additional permissions.');
|
|
}
|
|
|
|
function revokePermissions() {
|
|
if (confirm('Are you sure you want to revoke some permissions? This may limit functionality.')) {
|
|
alert('Permission revocation interface would be shown here.');
|
|
}
|
|
}
|
|
|
|
function confirmDisconnect() {
|
|
if (confirm('Are you sure you want to disconnect this account? You can reconnect it later.')) {
|
|
alert('Account disconnected successfully.');
|
|
window.location.href = '{% url "accounts:social_account_list" %}';
|
|
}
|
|
}
|
|
|
|
function copyToClipboard(text) {
|
|
navigator.clipboard.writeText(text).then(function() {
|
|
// Show success feedback
|
|
const button = event.target.closest('button');
|
|
const originalIcon = button.innerHTML;
|
|
button.innerHTML = '<i class="fas fa-check"></i>';
|
|
|
|
setTimeout(() => {
|
|
button.innerHTML = originalIcon;
|
|
}, 2000);
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.info-label {
|
|
font-weight: 600;
|
|
color: #6c757d;
|
|
font-size: 0.875rem;
|
|
margin-bottom: 5px;
|
|
display: block;
|
|
}
|
|
|
|
.info-value {
|
|
color: #495057;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.provider-icon-large {
|
|
padding: 20px;
|
|
background: #f8f9fa;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.permission-item {
|
|
padding: 10px 0;
|
|
border-bottom: 1px solid #f1f1f1;
|
|
}
|
|
|
|
.permission-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.security-item {
|
|
padding: 8px 0;
|
|
}
|
|
|
|
.stat-item {
|
|
padding: 8px 0;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.stat-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.provider-icon-large {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.page-btn {
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.page-btn .btn {
|
|
display: block;
|
|
width: 100%;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.permission-item .d-flex {
|
|
flex-direction: column;
|
|
text-align: center;
|
|
}
|
|
|
|
.permission-item i {
|
|
margin-bottom: 10px;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|