SEO, accessibility and consistency fixes

This commit is contained in:
Barunes Padhy 2024-06-22 11:40:35 +03:00
parent 076efaf577
commit a051197b16
9 changed files with 84 additions and 61 deletions

View File

@ -40,6 +40,7 @@ def github_deploy():
deploy_location = settings.DEPLOY_CONFIG["DEPLOY_LOCATION"]+'/ghpages'
copy_data_and_html('ghpages')
print("All data and HTML successfully copied to target folder")
if not os.path.exists(f'{deploy_location}/.git'):
try:
existing_repo = draw_dialogue_box(
@ -51,6 +52,7 @@ def github_deploy():
git_existing_repo_setup(deploy_location)
else:
github_init(deploy_location)
github_pages_deploy(deploy_location)
return {'message': 'Github deployment successful', 'status': status.HTTP_200_OK}
except Exception as e:

View File

@ -79,9 +79,10 @@ def git_update_viewable_ui(deploy_location, dist_folder_name, copy_index_and_ass
shutil.move(f'{settings.DEPLOY_CONFIG["DEPLOY_LOCATION"]}/{dist_folder_name}', f'{deploy_location}')
if copy_index_and_asset:
print("Copying index.html and assets")
copy_content(
f'{deploy_location}.temp/index.html',
deploy_location,
f'{deploy_location}/index.html',
'file',
'remove_and_copy'
)
@ -91,6 +92,8 @@ def git_update_viewable_ui(deploy_location, dist_folder_name, copy_index_and_ass
'folder',
'remove_and_copy'
)
else:
print("Skipping index.html and assets folder")
copy_content(
f'{deploy_location}.temp/data',
f'{deploy_location}/data',
@ -135,11 +138,12 @@ def github_pages_deploy(deploy_location):
user_email = run_git_command("git_config_email", deploy_location)
user_name = run_git_command("git_config_name", deploy_location)
repo_name = run_git_command("git_get_origin_url", deploy_location).split("/").pop()
repo_name = run_git_command("git_get_origin_url", deploy_location)
repo_name = repo_name['subprocess_output'].split("/").pop()
deploy_confirmation = draw_dialogue_box(
'Github Deploy',
f'Deploying as {user_name.subprocess_output} with email {user_email.subprocess_output} to {repo_name.subprocess_output}',
f'Deploying as {user_name["subprocess_output"]} with email {user_email["subprocess_output"]} to {repo_name}',
'confirmation'
)
@ -147,8 +151,8 @@ def github_pages_deploy(deploy_location):
run_git_command('git_pull', deploy_location)
print("completed git pull")
origin_url = run_git_command('git_get_origin_url', deploy_location)
print("Got origin as "+str(origin_url.subprocess_output))
parsed_url = urllib.parse.urlparse(origin_url.subprocess_output)
print("Got origin as "+str(origin_url["subprocess_output"]))
parsed_url = urllib.parse.urlparse(origin_url["subprocess_output"])
print(parsed_url)
if not '@' in parsed_url.netloc:
username = draw_dialogue_box('Github Deploy', 'Enter your username', 'textbox')

View File

@ -15,7 +15,7 @@ def copy_content(source, destination, content_type, copy_type='merge'):
else:
if copy_type == 'remove_and_copy' and os.path.exists(destination):
os.remove(destination)
shutil.copy(source, destination)
shutil.copy2(source, destination)
print(f'{content_type} copied successfully from {source} to {destination}')
except Exception as e:
print(f'Error occurred: {e}')
@ -69,4 +69,4 @@ def run_command(operation, command_location, command_map_list, parameter=None):
subprocess_result = {'subprocess_output': subprocess_output, 'subprocess_returncode': subprocess_returncode}
return subprocess_result
except subprocess.CalledProcessError as e:
return None
return {'subprocess_output': None, 'subprocess_returncode': 1}

View File

@ -3545,6 +3545,17 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
"node_modules/@types/node": {
"version": "20.14.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.7.tgz",
"integrity": "sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/parse-json": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
@ -4218,9 +4229,9 @@
}
},
"node_modules/axios": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz",
"integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==",
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@ -8698,6 +8709,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true,
"optional": true,
"peer": true
},
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",

View File

@ -40,7 +40,7 @@ function BlogList(props) {
if (GlobalTheme && ThemeConfig) {
return (
<Container fluid className={`mb-2 p-0 ${ThemeConfig[GlobalTheme].background}`}>
<Col className="d-md-block"><Button color={ThemeConfig[GlobalTheme].buttonColor} onClick={() => navigate('/categories/')} className="ms-5 mt-5" outline><FontAwesomeIcon icon={faLeftLong}/></Button></Col>
<Col className="d-md-block"><Button aria-label='Go to Categories page' color={ThemeConfig[GlobalTheme].buttonColor} onClick={() => navigate('/categories/')} className="ms-5 mt-5" outline><FontAwesomeIcon icon={faLeftLong}/></Button></Col>
<CategoryBar currentPage={categoryID} GlobalTheme={GlobalTheme} ThemeConfig={ThemeConfig} />
<Row className="justify-content-center align-items-center">
<Col className="d-flex flex-column align-items-center">

View File

@ -8,7 +8,7 @@ import CategoryBar from './shared/category-bar';
import {
Container,Row, Col,Spinner, UncontrolledCollapse, Button, ButtonGroup, Card, CardBody
} from 'reactstrap';
import { Link, useParams, useNavigate } from 'react-router-dom';
import { useParams, useNavigate } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faLeftLong, faCopy } from '@fortawesome/free-solid-svg-icons';
import { faFacebook, faReddit, faXTwitter } from '@fortawesome/free-brands-svg-icons';
@ -41,6 +41,31 @@ function Blog(props) {
}
};
const shareButton = (event, shareTarget) => {
if (shareTarget === 'copy'){
event.preventDefault();
navigator.clipboard.writeText(window.location.href).then(() => {
props.notificationToggler('Link copied')
})
return false;
}
if (shareTarget === 'facebook'){
event.preventDefault();
window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(window.location.href)}`, 'facebook-share-dialog', 'width=800,height=600');
return false;
}
if (shareTarget === 'reddit'){
event.preventDefault();
window.open(`https://www.reddit.com/submit?url=${window.location.href}&title=${blogData.name}`, 'facebook-share-dialog', 'width=800,height=600');
return false;
}
if (shareTarget === 'x'){
event.preventDefault();
window.open(`https://twitter.com/intent/tweet?text=Check%20out%20this%20article!&url=${window.location.href}`, 'facebook-share-dialog', 'width=800,height=600');
return false;
}
}
useEffect(() => {
DataService.getData(`blog/${blogID}/blog-data`).then(response =>{
setBlogData(response.data)
@ -60,7 +85,7 @@ function Blog(props) {
if (GlobalTheme && ThemeConfig) {
return (
<Container fluid className={`${ThemeConfig[GlobalTheme].background}`}>
<Col xs="3" className="d-md-block"><Button color={ThemeConfig[GlobalTheme].buttonColor} onClick={() => navigate(`/categories/${blogData.parentCategory}`)} className="ms-5 mt-5" outline><FontAwesomeIcon icon={faLeftLong}/></Button></Col>
<Col xs="3" className="d-md-block"><Button aria-label='Go to blogs' color={ThemeConfig[GlobalTheme].buttonColor} onClick={() => navigate(`/categories/${blogData.parentCategory}`)} className="ms-5 mt-5" outline><FontAwesomeIcon icon={faLeftLong}/></Button></Col>
<CategoryBar currentPage={blogData.parentCategory} GlobalTheme={GlobalTheme} ThemeConfig={ThemeConfig}/>
<Row className="mb-4">
<Col className="p-0">
@ -83,6 +108,7 @@ function Blog(props) {
<div>
<Button
color="primary"
aria-label='Share this blog'
id="toggler"
style={{
marginBottom: '1rem'
@ -97,43 +123,17 @@ function Blog(props) {
vertical
className="my-2"
>
<Button outline>
<Link className="p-3" to="#" onClick={(e) => {
e.preventDefault();
navigator.clipboard.writeText(window.location.href).then(() => {
props.notificationToggler('Link copied')
})
return false;
}}>
<FontAwesomeIcon icon={faCopy}/> Copy Link
</Link>
<Button aria-label='copy link' outline onClick={(event) => shareButton(event,'copy')}>
<FontAwesomeIcon icon={faCopy}/> Copy Link
</Button>
<Button outline>
<Link className="p-3" to="#" onClick={(e) => {
e.preventDefault();
window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(window.location.href)}`, 'facebook-share-dialog', 'width=800,height=600');
return false;
}}>
<FontAwesomeIcon icon={faFacebook}/> Facebook
</Link>
<Button onClick={(event) => shareButton(event, 'facebook')} aria-label='share to Facebook' outline>
<FontAwesomeIcon icon={faFacebook}/> Facebook
</Button>
<Button outline>
<Link className="p-3" to="#" onClick={(e) => {
e.preventDefault();
window.open(`https://www.reddit.com/submit?url=${window.location.href}&title=${blogData.name}`, 'facebook-share-dialog', 'width=800,height=600');
return false;
}}>
<FontAwesomeIcon icon={faReddit}/> Reddit
</Link>
<Button onClick={(event) => shareButton(event, 'reddit')} aria-label='share to Reddit' outline>
<FontAwesomeIcon icon={faReddit}/> Reddit
</Button>
<Button outline>
<Link className="p-3" to="#" onClick={(e) => {
e.preventDefault();
window.open(`https://twitter.com/intent/tweet?text=Check%20out%20this%20article!&url=${window.location.href}`, 'facebook-share-dialog', 'width=800,height=600');
return false;
}}>
<FontAwesomeIcon icon={faXTwitter}/>
</Link>
<Button onClick={(event) => shareButton(event, 'x')} aria-label='share to X' outline>
<FontAwesomeIcon icon={faXTwitter}/>
</Button>
</ButtonGroup>
</CardBody>

View File

@ -42,7 +42,7 @@ function Blogs(props) {
<Col className='d-flex flex-column align-items-center'>
{/* Top Section - Categories */}
<div className='w-100'>
<Col xs='3' className='d-md-block'><Button color={ThemeConfig[GlobalTheme].buttonColor} onClick={() => navigate('/')} className='ms-5 mt-5' outline><FontAwesomeIcon icon={faLeftLong}/></Button></Col>
<Col xs='3' className='d-md-block'><Button aria-label='Go to Home page' color={ThemeConfig[GlobalTheme].buttonColor} onClick={() => navigate('/')} className='ms-5 mt-5' outline><FontAwesomeIcon icon={faLeftLong}/></Button></Col>
<Card className={`my-2 ${ThemeConfig[GlobalTheme].background}`} style={{width: '100%', border: 'none'}}>
<CardBody>
<CardTitle style={{ display: 'grid' }} className={`${ThemeConfig[GlobalTheme].textColor} justify-content-center`} tag='h1'>

View File

@ -1,10 +1,11 @@
import { useEffect, useState } from 'react';
import DataService from '../../services/data-service';
import { Link } from 'react-router-dom';
import { Container, Row, Col, Button, Spinner, ButtonGroup } from 'reactstrap';
import { useNavigate } from 'react-router-dom';
function CategoryBar(props) {
let navigate = useNavigate();
const [categoryMetadata, setCategoryMetadata] = useState([]);
useEffect(() => {
@ -34,13 +35,13 @@ function CategoryBar(props) {
<Button
key={item.id}
className="btn-lg"
onClick={() => navigate(`/categories/${item.id}`)}
color={`${ThemeConfig[GlobalTheme].buttonColor}`}
outline
active={props.currentPage === item.id}
>
<Link className="p-3" to={`/categories/${item.id}`}>
{item.name}
</Link></Button>
{item.name}
</Button>
)) : <Spinner />
}
</ButtonGroup>

View File

@ -12,10 +12,11 @@ import { useState, useEffect } from 'react';
import MediaService from '../../services/media-service'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSun, faMoon, faPen } from '@fortawesome/free-solid-svg-icons';
import { Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
function Header(props) {
let navigate = useNavigate();
const GlobalTheme = props.GlobalTheme;
const ThemeConfig = props.ThemeConfig;
const UserData = props.UserData;
@ -45,19 +46,15 @@ function Header(props) {
src={MediaService.getMedia(UserData.profilePhoto)}
/> : ''
}
<Button color={`${ThemeConfig ? ThemeConfig[GlobalTheme].navBar['buttonColor'] : ''}`} size='lg'>
<Link to='/'>
{ UserData ? UserData.name : <Spinner> Loading... </Spinner> }
</Link>
<Button onClick={() => navigate('/')} aria-label='Go to Home page' color={`${ThemeConfig ? ThemeConfig[GlobalTheme].navBar['buttonColor'] : ''}`} size='lg'>
{ UserData ? UserData.name : <Spinner> Loading... </Spinner> }
</Button>
</NavbarBrand>
<Nav className='ml-lg-auto' navbar>
<NavItem>
<ButtonGroup style={{marginTop: '15px', marginBottom: '15px'}}>
<Button color={`${ThemeConfig ? ThemeConfig[GlobalTheme].navBar['buttonColor'] : ''}`}>
<Link to='/categories'>
<FontAwesomeIcon icon={faPen} /> Blogs
</Link>
<Button onClick={() => navigate('/categories')} style={{marginRight: '10px', borderRadius: '6px 0px 0px 6px'}} aria-label='Go to categories' color={`${ThemeConfig ? ThemeConfig[GlobalTheme].navBar['buttonColor'] : ''}`}>
<FontAwesomeIcon icon={faPen} /> Blogs
</Button>
<Button
color={`${ThemeConfig ? ThemeConfig[GlobalTheme].navBar['buttonColor'] : ''}`}