added
This commit is contained in:
+214
@@ -0,0 +1,214 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[codz]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# UV
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
#uv.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
#poetry.toml
|
||||||
|
|
||||||
|
# pdm
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
|
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
||||||
|
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
||||||
|
#pdm.lock
|
||||||
|
#pdm.toml
|
||||||
|
.pdm-python
|
||||||
|
.pdm-build/
|
||||||
|
|
||||||
|
# pixi
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
||||||
|
#pixi.lock
|
||||||
|
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
||||||
|
# in the .venv directory. It is recommended not to include this directory in version control.
|
||||||
|
.pixi
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.envrc
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# Abstra
|
||||||
|
# Abstra is an AI-powered process automation framework.
|
||||||
|
# Ignore directories containing user credentials, local state, and settings.
|
||||||
|
# Learn more at https://abstra.io/docs
|
||||||
|
.abstra/
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
||||||
|
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||||
|
# you could uncomment the following to ignore the entire vscode folder
|
||||||
|
# .vscode/
|
||||||
|
|
||||||
|
# Ruff stuff:
|
||||||
|
.ruff_cache/
|
||||||
|
|
||||||
|
# PyPI configuration file
|
||||||
|
.pypirc
|
||||||
|
|
||||||
|
# Cursor
|
||||||
|
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
||||||
|
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
||||||
|
# refer to https://docs.cursor.com/context/ignore-files
|
||||||
|
.cursorignore
|
||||||
|
.cursorindexingignore
|
||||||
|
|
||||||
|
# Marimo
|
||||||
|
marimo/_static/
|
||||||
|
marimo/_lsp/
|
||||||
|
__marimo__/
|
||||||
|
|
||||||
|
# Streamlit
|
||||||
|
.streamlit/secrets.toml
|
||||||
|
|
||||||
|
instance/
|
||||||
|
src/
|
||||||
|
instance/app_data.db
|
||||||
+228
@@ -0,0 +1,228 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
from flask import Flask, request, jsonify, session, send_from_directory
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
app = Flask(__name__, static_folder='../frontend/build', static_url_path='/')
|
||||||
|
app.config['SECRET_KEY'] = 'your_secret_key'
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///manga.db'
|
||||||
|
db = SQLAlchemy(app)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# --- Database Models ---
|
||||||
|
|
||||||
|
class User(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||||
|
password = db.Column(db.String(120), nullable=False)
|
||||||
|
|
||||||
|
class Manga(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
title = db.Column(db.String(120), nullable=False)
|
||||||
|
api_id = db.Column(db.String(120), unique=True, nullable=False)
|
||||||
|
image_url = db.Column(db.String(255), nullable=True)
|
||||||
|
|
||||||
|
class UserManga(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||||
|
manga_id = db.Column(db.Integer, db.ForeignKey('manga.id'), nullable=False)
|
||||||
|
volume_number = db.Column(db.Integer, nullable=True) # New field for volume number
|
||||||
|
|
||||||
|
class Friend(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||||
|
friend_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
||||||
|
|
||||||
|
# --- API Routes ---
|
||||||
|
|
||||||
|
@app.route('/api/signup', methods=['POST'])
|
||||||
|
def signup():
|
||||||
|
data = request.get_json()
|
||||||
|
username = data.get('username')
|
||||||
|
password = data.get('password')
|
||||||
|
|
||||||
|
if not username or not password:
|
||||||
|
return jsonify({'message': 'Username and password are required'}), 400
|
||||||
|
|
||||||
|
if User.query.filter_by(username=username).first():
|
||||||
|
return jsonify({'message': 'Username already exists'}), 409
|
||||||
|
|
||||||
|
new_user = User(username=username, password=password) # In a real app, hash passwords!
|
||||||
|
db.session.add(new_user)
|
||||||
|
db.session.commit()
|
||||||
|
return jsonify({'message': 'User created successfully'}), 201
|
||||||
|
|
||||||
|
@app.route('/api/login', methods=['POST'])
|
||||||
|
def login():
|
||||||
|
data = request.get_json()
|
||||||
|
username = data.get('username')
|
||||||
|
password = data.get('password')
|
||||||
|
|
||||||
|
user = User.query.filter_by(username=username, password=password).first() # In a real app, check hashed password
|
||||||
|
if user:
|
||||||
|
session['user_id'] = user.id
|
||||||
|
return jsonify({'message': 'Login successful', 'user_id': user.id}), 200
|
||||||
|
return jsonify({'message': 'Invalid credentials'}), 401
|
||||||
|
|
||||||
|
@app.route('/api/logout')
|
||||||
|
def logout():
|
||||||
|
session.pop('user_id', None)
|
||||||
|
return jsonify({'message': 'Logged out successfully'}), 200
|
||||||
|
|
||||||
|
@app.route('/api/dashboard')
|
||||||
|
def dashboard():
|
||||||
|
if 'user_id' not in session:
|
||||||
|
return jsonify({'message': 'Unauthorized'}), 401
|
||||||
|
|
||||||
|
user = User.query.get(session['user_id'])
|
||||||
|
if not user:
|
||||||
|
return jsonify({'message': 'User not found'}), 404
|
||||||
|
|
||||||
|
user_mangas = UserManga.query.filter_by(user_id=user.id).all()
|
||||||
|
grouped_user_mangas = {}
|
||||||
|
for um in user_mangas:
|
||||||
|
manga = Manga.query.get(um.manga_id)
|
||||||
|
if manga:
|
||||||
|
if manga.title not in grouped_user_mangas:
|
||||||
|
grouped_user_mangas[manga.title] = {
|
||||||
|
'manga_details': {
|
||||||
|
'id': manga.id,
|
||||||
|
'title': manga.title,
|
||||||
|
'api_id': manga.api_id,
|
||||||
|
'image_url': manga.image_url
|
||||||
|
},
|
||||||
|
'volumes': []
|
||||||
|
}
|
||||||
|
grouped_user_mangas[manga.title]['volumes'].append(um.volume_number)
|
||||||
|
grouped_user_mangas[manga.title]['volumes'].sort()
|
||||||
|
|
||||||
|
friends = Friend.query.filter_by(user_id=user.id).all()
|
||||||
|
friend_users = []
|
||||||
|
for f in friends:
|
||||||
|
friend_user = User.query.get(f.friend_id)
|
||||||
|
if friend_user:
|
||||||
|
friend_users.append({'id': friend_user.id, 'username': friend_user.username})
|
||||||
|
|
||||||
|
friend_mangas_data = {}
|
||||||
|
for friend_user_data in friend_users:
|
||||||
|
friend_id = friend_user_data['id']
|
||||||
|
friend_username = friend_user_data['username']
|
||||||
|
friend_user_mangas = UserManga.query.filter_by(user_id=friend_id).all()
|
||||||
|
grouped_friend_mangas = {}
|
||||||
|
for fum in friend_user_mangas:
|
||||||
|
fmanga = Manga.query.get(fum.manga_id)
|
||||||
|
if fmanga:
|
||||||
|
if fmanga.title not in grouped_friend_mangas:
|
||||||
|
grouped_friend_mangas[fmanga.title] = {
|
||||||
|
'manga_details': {
|
||||||
|
'id': fmanga.id,
|
||||||
|
'title': fmanga.title,
|
||||||
|
'api_id': fmanga.api_id,
|
||||||
|
'image_url': fmanga.image_url
|
||||||
|
},
|
||||||
|
'volumes': []
|
||||||
|
}
|
||||||
|
grouped_friend_mangas[fmanga.title]['volumes'].append(fum.volume_number)
|
||||||
|
grouped_friend_mangas[fmanga.title]['volumes'].sort()
|
||||||
|
friend_mangas_data[friend_username] = grouped_friend_mangas
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'user': {'id': user.id, 'username': user.username},
|
||||||
|
'mangas': grouped_user_mangas,
|
||||||
|
'friends': friend_users,
|
||||||
|
'friend_mangas': friend_mangas_data
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
@app.route('/api/search', methods=['POST'])
|
||||||
|
def search():
|
||||||
|
if 'user_id' not in session:
|
||||||
|
return jsonify({'message': 'Unauthorized'}), 401
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
manga_title = data.get('query')
|
||||||
|
if not manga_title:
|
||||||
|
return jsonify({'message': 'Query parameter is required'}), 400
|
||||||
|
|
||||||
|
response = requests.get(f'https://api.jikan.moe/v4/manga?q={manga_title}')
|
||||||
|
manga_data = response.json()
|
||||||
|
return jsonify(manga_data), 200
|
||||||
|
|
||||||
|
@app.route('/api/add_manga', methods=['POST'])
|
||||||
|
def add_manga():
|
||||||
|
if 'user_id' not in session:
|
||||||
|
return jsonify({'message': 'Unauthorized'}), 401
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
manga_title = data.get('manga_title')
|
||||||
|
manga_api_id = data.get('manga_api_id')
|
||||||
|
image_url = data.get('image_url')
|
||||||
|
volume_number = data.get('volume_number')
|
||||||
|
|
||||||
|
if not manga_title or not manga_api_id:
|
||||||
|
return jsonify({'message': 'Manga title and API ID are required'}), 400
|
||||||
|
|
||||||
|
manga = Manga.query.filter_by(api_id=manga_api_id).first()
|
||||||
|
if not manga:
|
||||||
|
manga = Manga(title=manga_title, api_id=manga_api_id, image_url=image_url)
|
||||||
|
db.session.add(manga)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
user_manga = UserManga.query.filter_by(
|
||||||
|
user_id=session['user_id'],
|
||||||
|
manga_id=manga.id,
|
||||||
|
volume_number=volume_number
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not user_manga:
|
||||||
|
user_manga = UserManga(user_id=session['user_id'], manga_id=manga.id, volume_number=volume_number)
|
||||||
|
db.session.add(user_manga)
|
||||||
|
db.session.commit()
|
||||||
|
return jsonify({'message': 'Manga added successfully'}), 201
|
||||||
|
|
||||||
|
@app.route('/api/search_user', methods=['POST'])
|
||||||
|
def search_user():
|
||||||
|
if 'user_id' not in session:
|
||||||
|
return jsonify({'message': 'Unauthorized'}), 401
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
username = data.get('query')
|
||||||
|
if not username:
|
||||||
|
return jsonify({'message': 'Query parameter is required'}), 400
|
||||||
|
|
||||||
|
users = User.query.filter(User.username.like(f'%{username}%')).all()
|
||||||
|
users_data = [{'id': user.id, 'username': user.username} for user in users]
|
||||||
|
return jsonify({'users': users_data}), 200
|
||||||
|
|
||||||
|
@app.route('/api/add_friend', methods=['POST'])
|
||||||
|
def add_friend():
|
||||||
|
if 'user_id' not in session:
|
||||||
|
return jsonify({'message': 'Unauthorized'}), 401
|
||||||
|
|
||||||
|
data = request.get_json()
|
||||||
|
friend_id = data.get('friend_id')
|
||||||
|
|
||||||
|
if not friend_id:
|
||||||
|
return jsonify({'message': 'Friend ID is required'}), 400
|
||||||
|
|
||||||
|
friendship = Friend.query.filter_by(user_id=session['user_id'], friend_id=friend_id).first()
|
||||||
|
if not friendship:
|
||||||
|
new_friend = Friend(user_id=session['user_id'], friend_id=friend_id)
|
||||||
|
db.session.add(new_friend)
|
||||||
|
db.session.commit()
|
||||||
|
return jsonify({'message': 'Friend added successfully'}), 201
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def serve_index():
|
||||||
|
return send_from_directory(app.static_folder, 'index.html')
|
||||||
|
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def not_found(e):
|
||||||
|
return send_from_directory(app.static_folder, 'index.html')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
|
app.run(debug=True)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manga-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manga-card {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manga-card img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
Generated
+17867
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@testing-library/dom": "^10.4.0",
|
||||||
|
"@testing-library/jest-dom": "^6.6.3",
|
||||||
|
"@testing-library/react": "^16.3.0",
|
||||||
|
"@testing-library/user-event": "^13.5.0",
|
||||||
|
"bootstrap": "^5.3.7",
|
||||||
|
"react": "^19.1.0",
|
||||||
|
"react-bootstrap": "^2.10.10",
|
||||||
|
"react-dom": "^19.1.0",
|
||||||
|
"react-router-dom": "^7.6.3",
|
||||||
|
"react-scripts": "5.0.1",
|
||||||
|
"web-vitals": "^2.1.4"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "react-scripts start",
|
||||||
|
"build": "react-scripts build",
|
||||||
|
"test": "react-scripts test",
|
||||||
|
"eject": "react-scripts eject"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": [
|
||||||
|
"react-app",
|
||||||
|
"react-app/jest"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Web site created using create-react-app"
|
||||||
|
/>
|
||||||
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
|
<!--
|
||||||
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
|
-->
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
<!--
|
||||||
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
|
|
||||||
|
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||||
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
|
-->
|
||||||
|
<title>React App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<!--
|
||||||
|
This HTML file is a template.
|
||||||
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|
||||||
|
You can add webfonts, meta tags, or analytics to this file.
|
||||||
|
The build step will place the bundled scripts into the <body> tag.
|
||||||
|
|
||||||
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
|
-->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"short_name": "React App",
|
||||||
|
"name": "Create React App Sample",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "favicon.ico",
|
||||||
|
"sizes": "64x64 32x32 24x24 16x16",
|
||||||
|
"type": "image/x-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#ffffff"
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
altgraph @ file:///AppleInternal/Library/BuildRoots/39d9dc1a-2111-11f0-be06-226177e5bb69/Library/Caches/com.apple.xbs/Sources/python3/altgraph-0.17.2-py2.py3-none-any.whl
|
||||||
|
blinker==1.7.0
|
||||||
|
certifi==2025.7.9
|
||||||
|
charset-normalizer==3.4.2
|
||||||
|
click==8.1.7
|
||||||
|
Flask==3.0.2
|
||||||
|
Flask-SQLAlchemy==3.1.1
|
||||||
|
future @ file:///AppleInternal/Library/BuildRoots/39d9dc1a-2111-11f0-be06-226177e5bb69/Library/Caches/com.apple.xbs/Sources/python3/future-0.18.2-py3-none-any.whl
|
||||||
|
greenlet==3.0.3
|
||||||
|
gunicorn==21.2.0
|
||||||
|
idna==3.10
|
||||||
|
importlib_metadata==8.7.0
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
Jinja2==3.1.3
|
||||||
|
macholib @ file:///AppleInternal/Library/BuildRoots/39d9dc1a-2111-11f0-be06-226177e5bb69/Library/Caches/com.apple.xbs/Sources/python3/macholib-1.15.2-py2.py3-none-any.whl
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
numpy==1.26.4
|
||||||
|
packaging==23.2
|
||||||
|
pandas==2.2.1
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
pytz==2024.1
|
||||||
|
requests==2.32.4
|
||||||
|
schedule==1.2.2
|
||||||
|
six==1.16.0
|
||||||
|
SQLAlchemy==2.0.28
|
||||||
|
typing_extensions==4.10.0
|
||||||
|
tzdata==2024.1
|
||||||
|
urllib3==2.5.0
|
||||||
|
Werkzeug==3.0.1
|
||||||
|
zipp==3.23.0
|
||||||
Reference in New Issue
Block a user