SEO, accessibility and consistency fixes
This commit is contained in:
parent
076efaf577
commit
a051197b16
@ -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:
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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}
|
||||
|
||||
25
frontend/viewable-ui/package-lock.json
generated
25
frontend/viewable-ui/package-lock.json
generated
@ -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",
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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'>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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'] : ''}`}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user