Skip to content

Commit

Permalink
Start working on admin in config
Browse files Browse the repository at this point in the history
  • Loading branch information
BaseMax committed Nov 30, 2024
1 parent b86a561 commit 5225d71
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 0 deletions.
84 changes: 84 additions & 0 deletions config/admin/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from flask import Flask, render_template, request, redirect, url_for, jsonify, session
import yaml
import os

app = Flask(__name__)
app.secret_key = 'your_secret_key'

YAML_DIR = '../'
YAML_FILES = []
for root, dirs, files in os.walk(YAML_DIR):
for file in files:
if file.endswith('.yaml'):
YAML_FILES.append(os.path.relpath(os.path.join(root, file), start=YAML_DIR))

def read_yaml(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
return yaml.safe_load(file)

def write_yaml(file_path, data):
with open(file_path, 'w', encoding='utf-8') as file:
yaml.dump(data, file, allow_unicode=True, sort_keys=True)

@app.route('/')
def index():
return render_template('index.html', files=YAML_FILES)

@app.route('/edit/<path:filepath>', methods=['GET', 'POST'])
def edit_file(filepath):
file_path = os.path.join(YAML_DIR, filepath)

if not os.path.exists(file_path):
return f"File {filepath} not found.", 404

if request.method == 'POST':
items = request.json.get('items', [])
data = {'items': items}
write_yaml(file_path, data)

return jsonify({'success': True})

data = read_yaml(file_path)
return render_template('edit.html', filename=filepath, items=data['items'])


@app.route('/add-file', methods=['POST'])
def add_file():
new_file = request.form.get('filename')

if not new_file:
session['error'] = 'Filename is required.'
return redirect(url_for('index'))

new_file = new_file.lstrip('/')

if not new_file.endswith('.yaml'):
new_file += '.yaml'

path = os.path.join(YAML_DIR, new_file)

if not path.startswith(os.path.abspath(YAML_DIR)):
session['error'] = 'Invalid filename or directory traversal attempt.'
return redirect(url_for('index'))

if os.path.exists(path):
session['error'] = 'File already exists.'
return redirect(url_for('index'))

try:
write_yaml(path, {'items': []})
except Exception as e:
session['error'] = f'Failed to create file: {e}'
return redirect(url_for('index'))

return redirect(url_for('index'))

def redirect_with_error(error_message):
"""
Helper function to redirect with an error message.
"""
return redirect(url_for('index', error=error_message))

if __name__ == '__main__':
os.makedirs(YAML_DIR, exist_ok=True)
app.run(debug=True, port=5000)
Empty file added config/admin/requirements.txt
Empty file.
74 changes: 74 additions & 0 deletions config/admin/templates/edit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit {{ filename }}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div class="container mt-4">
<h1>Edit File: {{ filename }}</h1>
<table class="table table-bordered" id="data-table">
<thead>
<tr>
<th>ID</th>
<th>Text (EN)</th>
<th>Text (FA)</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td><input class="form-control" value="{{ item.id }}" /></td>
<td><input class="form-control" value="{{ item.text.en if item.text else '' }}" /></td>
<td><input class="form-control" value="{{ item.text.fa if item.text else '' }}" /></td>
<td>
<button class="btn btn-danger btn-sm" onclick="deleteRow(this)">Delete</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<button class="btn btn-success" onclick="addRow()">Add Row</button>
<button class="btn btn-primary" onclick="save()">Save Changes</button>
</div>

<script>
function addRow() {
const table = document.getElementById('data-table').querySelector('tbody');
const row = document.createElement('tr');
row.innerHTML = `
<td><input class="form-control" value="" /></td>
<td><input class="form-control" value="" /></td>
<td><input class="form-control" value="" /></td>
<td><button class="btn btn-danger btn-sm" onclick="deleteRow(this)">Delete</button></td>
`;
table.appendChild(row);
}

function deleteRow(button) {
button.closest('tr').remove();
}

function save() {
const rows = document.getElementById('data-table').querySelectorAll('tbody tr');
const items = Array.from(rows).map(row => {
const cells = row.querySelectorAll('input');
return {
id: cells[0].value,
text: {
en: cells[1].value,
fa: cells[2].value
}
};
});
axios.post(window.location.pathname, { items })
.then(response => alert('Saved successfully!'))
.catch(error => alert('Failed to save.'));
}
</script>
</body>
</html>
33 changes: 33 additions & 0 deletions config/admin/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Salam Admin Panel</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
</head>
<body class="container mt-5">
<h1>Salam Admin Panel</h1>

{% if request.args.get('error') %}
<div class="alert alert-danger" role="alert">
{{ request.args.get('error') }}
</div>
{% endif %}

<form action="{{ url_for('add_file') }}" method="post" class="mb-4">
<div class="input-group">
<input type="text" name="filename" class="form-control" placeholder="Enter new filename">
<button type="submit" class="btn btn-primary">Add File</button>
</div>
</form>

<ul class="list-group">
{% for file in files %}
<li class="list-group-item">
<a href="{{ url_for('edit_file', filepath=file) }}">{{ file }}</a>
</li>
{% endfor %}
</ul>
</body>
</html>

0 comments on commit 5225d71

Please sign in to comment.