1
0
Fork 0
mirror of https://github.com/dilllxd/gitfolio.git synced 2024-08-14 22:28:09 +00:00

Setting line endings to unix-style (#95)

* Add gitattributes settings to LF
* TY @Pliavi 
* Converting all CRLF to LF
This commit is contained in:
Vitor "Pliavi" Silvério 2019-11-16 23:27:32 -03:00 committed by funny
parent 0e90c885d1
commit 1de7fd23ef
24 changed files with 4560 additions and 4555 deletions

5
.gitattributes vendored Normal file
View file

@ -0,0 +1,5 @@
# Set the default behavior, in case people don't have core.autocrlf set
* text=auto
# Require Unix line endings
* text eol=lf

View file

@ -1,76 +1,76 @@
# Contributor Covenant Code of Conduct # Contributor Covenant Code of Conduct
## Our Pledge ## Our Pledge
In the interest of fostering an open and welcoming environment, we as In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression, size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation. appearance, race, religion, or sexual identity and orientation.
## Our Standards ## Our Standards
Examples of behavior that contributes to creating a positive environment Examples of behavior that contributes to creating a positive environment
include: include:
- Using welcoming and inclusive language - Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences - Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism - Gracefully accepting constructive criticism
- Focusing on what is best for the community - Focusing on what is best for the community
- Showing empathy towards other community members - Showing empathy towards other community members
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or - The use of sexualized language or imagery and unwelcome sexual attention or
advances advances
- Trolling, insulting/derogatory comments, and personal or political attacks - Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment - Public or private harassment
- Publishing others' private information, such as a physical or electronic - Publishing others' private information, such as a physical or electronic
address, without explicit permission address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Our Responsibilities ## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior. response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate, permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful. threatening, offensive, or harmful.
## Scope ## Scope
This Code of Conduct applies both within project spaces and in public spaces This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers. further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at imfunny@wybemf.com. All reported by contacting the project team at imfunny@wybemf.com. All
complaints will be reviewed and investigated and will result in a response that complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident. obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other faith may face temporary or permanent repercussions as determined by other
members of the project's leadership. members of the project's leadership.
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org [homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq https://www.contributor-covenant.org/faq

1348
LICENSE

File diff suppressed because it is too large Load diff

322
README.md
View file

@ -1,161 +1,161 @@
<img src="https://i.imgur.com/eA6clZr.png"> <img src="https://i.imgur.com/eA6clZr.png">
# Gitfolio # Gitfolio
[![Tweet](https://img.shields.io/twitter/url/https/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=personal%20website%20and%20a%20blog%20for%20every%20github%20user%20@imfunnieee%20&url=https://github.com/imfunniee/gitfolio) ![GitHub release](https://img.shields.io/github/release/imfunniee/gitfolio.svg?style=popout-square) ![npm](https://img.shields.io/npm/dm/gitfolio.svg?style=popout-square) ![GitHub top language](https://img.shields.io/github/languages/top/imfunniee/gitfolio.svg?style=popout-square) ![GitHub last commit](https://img.shields.io/github/last-commit/imfunniee/gitfolio.svg?style=popout-square) ![GitHub](https://img.shields.io/github/license/imfunniee/gitfolio.svg?style=popout-square) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) [![Tweet](https://img.shields.io/twitter/url/https/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=personal%20website%20and%20a%20blog%20for%20every%20github%20user%20@imfunnieee%20&url=https://github.com/imfunniee/gitfolio) ![GitHub release](https://img.shields.io/github/release/imfunniee/gitfolio.svg?style=popout-square) ![npm](https://img.shields.io/npm/dm/gitfolio.svg?style=popout-square) ![GitHub top language](https://img.shields.io/github/languages/top/imfunniee/gitfolio.svg?style=popout-square) ![GitHub last commit](https://img.shields.io/github/last-commit/imfunniee/gitfolio.svg?style=popout-square) ![GitHub](https://img.shields.io/github/license/imfunniee/gitfolio.svg?style=popout-square) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
### personal website + blog for every github user ### personal website + blog for every github user
Gitfolio will help you get started with a portfolio website where you could showcase your work + a blog that will help you spread your ideas into real world. Gitfolio will help you get started with a portfolio website where you could showcase your work + a blog that will help you spread your ideas into real world.
Check out this [live demo](https://imfunniee.github.io/gitfolio/) to see gitfolio in action. Check out this [live demo](https://imfunniee.github.io/gitfolio/) to see gitfolio in action.
# Getting Started # Getting Started
### Let's Install ### Let's Install
Install gitfolio Install gitfolio
```sh ```sh
npm i gitfolio -g npm i gitfolio -g
``` ```
### Let's Build ### Let's Build
Using the UI Using the UI
```sh ```sh
$ gitfolio ui $ gitfolio ui
``` ```
> Tip: You can use ui to create new blogs and for updating your folio too. > Tip: You can use ui to create new blogs and for updating your folio too.
or or
```sh ```sh
gitfolio build <username> gitfolio build <username>
``` ```
`<username>` is your username on github. This will build your website using your GitHub username and put it in the `/dist` folder. `<username>` is your username on github. This will build your website using your GitHub username and put it in the `/dist` folder.
To run your website use `run` command, Default port is 3000 To run your website use `run` command, Default port is 3000
```sh ```sh
gitfolio run -p [port] gitfolio run -p [port]
``` ```
🎉 Congrats, you just made yourself a personal website! 🎉 Congrats, you just made yourself a personal website!
### Let's Customize ### Let's Customize
#### Forks #### Forks
To include forks on your personal website just provide `-f` or `--fork` argument while building To include forks on your personal website just provide `-f` or `--fork` argument while building
```sh ```sh
$ gitfolio build <username> -f $ gitfolio build <username> -f
``` ```
#### Sorting Repos #### Sorting Repos
To sort repos provide `--sort [sortBy]` argument while building. Where `[sortBy]` can be `star`, `created`, `updated`, `pushed`,`full_name`. Default: `created` To sort repos provide `--sort [sortBy]` argument while building. Where `[sortBy]` can be `star`, `created`, `updated`, `pushed`,`full_name`. Default: `created`
```sh ```sh
$ gitfolio build <username> --sort star $ gitfolio build <username> --sort star
``` ```
#### Ordering Repos #### Ordering Repos
To order the sorted repos provide `--order [orderBy]` argument while building. Where `[orderBy]` can be `asc` or `desc`. Default: `asc` To order the sorted repos provide `--order [orderBy]` argument while building. Where `[orderBy]` can be `asc` or `desc`. Default: `asc`
```sh ```sh
$ gitfolio build <username> --sort star --order desc $ gitfolio build <username> --sort star --order desc
``` ```
#### Customize Themes #### Customize Themes
Themes are specified using the `--theme [theme-name]` flag when running the `build` command. The available themes are Themes are specified using the `--theme [theme-name]` flag when running the `build` command. The available themes are
- `light` - `light`
- `dark` - `dark`
> TODO: Add more themes > TODO: Add more themes
For example, the following command will build the website with the dark theme For example, the following command will build the website with the dark theme
```sh ```sh
$ gitfolio build <username> --theme dark $ gitfolio build <username> --theme dark
``` ```
#### Customize background image #### Customize background image
To customize the background image just provide `--background [url]` argument while building To customize the background image just provide `--background [url]` argument while building
```sh ```sh
$ gitfolio build <username> --background https://images.unsplash.com/photo-1557277770-baf0ca74f908?w=1634 $ gitfolio build <username> --background https://images.unsplash.com/photo-1557277770-baf0ca74f908?w=1634
``` ```
You could also add in your custom CSS inside `index.css` to give it a more personal feel. You could also add in your custom CSS inside `index.css` to give it a more personal feel.
#### Add Social Media links on your profile #### Add Social Media links on your profile
Twitter, LinkedIn, Medium & Dribbble links to your profile while building Twitter, LinkedIn, Medium & Dribbble links to your profile while building
```sh ```sh
gitfolio build <username> --twitter <twitter_username> --linkedin <linkedin_username> --medium <medium_username> --dribbble <dribbble_username> gitfolio build <username> --twitter <twitter_username> --linkedin <linkedin_username> --medium <medium_username> --dribbble <dribbble_username>
``` ```
### Let's Publish ### Let's Publish
Head over to GitHub and create a new repository named `username.github.io`, where username is your username. Push the files inside`/dist` folder to repo you just created. Head over to GitHub and create a new repository named `username.github.io`, where username is your username. Push the files inside`/dist` folder to repo you just created.
Go To `username.github.io` your site should be up!! Go To `username.github.io` your site should be up!!
### Updating ### Updating
To update your info, simply run To update your info, simply run
```sh ```sh
$ gitfolio update $ gitfolio update
``` ```
or use the `Update` options in gitfolio's UI or use the `Update` options in gitfolio's UI
This will update your info and your repository info. This will update your info and your repository info.
To Update background or theme you need to run `build` command again. To Update background or theme you need to run `build` command again.
### Add a Blog ### Add a Blog
To add your first blog use the UI. To add your first blog use the UI.
```sh ```sh
$ gitfolio ui $ gitfolio ui
``` ```
This will open up a UI page and you can click on `New Blog` to create a new blog. Once you are done writing your blog you can hit the `Create Blog`. This will open up a UI page and you can click on `New Blog` to create a new blog. Once you are done writing your blog you can hit the `Create Blog`.
This will create a blog inside `./dist/blog` folder. This will create a blog inside `./dist/blog` folder.
Look for success or error in your terminal. Look for success or error in your terminal.
This also adds content to `blog.json` file. This file helps in showcasing your blogs on your personal website as [cards](https://imfunniee.github.io/gitfolio/#blog_section). You could customize the JSON object that corresponds your current blog. This also adds content to `blog.json` file. This file helps in showcasing your blogs on your personal website as [cards](https://imfunniee.github.io/gitfolio/#blog_section). You could customize the JSON object that corresponds your current blog.
Blog Demo? [here](https://imfunniee.github.io/gitfolio/blog/my-first-post/) Blog Demo? [here](https://imfunniee.github.io/gitfolio/blog/my-first-post/)
Blog's default JSON Format Blog's default JSON Format
``` ```
{ {
"url_title": "my-first-blog", // the title you provide while creating a new blog, this appears in url "url_title": "my-first-blog", // the title you provide while creating a new blog, this appears in url
"title": "Lorem ipsum dolor sit amet", // main title of blog "title": "Lorem ipsum dolor sit amet", // main title of blog
"sub_title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", // sub-title of blog "sub_title": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", // sub-title of blog
"top_image": "https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1450", // main image of blog "top_image": "https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1450", // main image of blog
"visible": true // don't worry about this "visible": true // don't worry about this
} }
``` ```
### Follow me on twitter for more updates [@imfunnieee](https://twitter.com/imfunnieee) ### Follow me on twitter for more updates [@imfunnieee](https://twitter.com/imfunnieee)
### License ### License
![GitHub](https://img.shields.io/github/license/imfunniee/gitfolio.svg?style=popout-square) ![GitHub](https://img.shields.io/github/license/imfunniee/gitfolio.svg?style=popout-square)

132
api.js
View file

@ -1,66 +1,66 @@
const got = require("got"); const got = require("got");
/** /**
* The defaults here are the same as the API * The defaults here are the same as the API
* @see https://developer.github.com/v3/repos/#list-user-repositories * @see https://developer.github.com/v3/repos/#list-user-repositories
* @param {string} username * @param {string} username
* @param {Object} opts * @param {Object} opts
* @param {('all' | 'owner' | 'member')[]} [opts.types] * @param {('all' | 'owner' | 'member')[]} [opts.types]
* @param {'created' | 'updated' | 'pushed' | 'full_name' | 'star'} [opts.sort] * @param {'created' | 'updated' | 'pushed' | 'full_name' | 'star'} [opts.sort]
* @param {'desc' | 'asc'} [opts.order] * @param {'desc' | 'asc'} [opts.order]
*/ */
async function getRepos(username, opts = {}) { async function getRepos(username, opts = {}) {
let tempRepos; let tempRepos;
let page = 1; let page = 1;
let repos = []; let repos = [];
const sort = opts.sort; const sort = opts.sort;
const order = opts.order || (sort === "full_name" ? "asc" : "desc"); const order = opts.order || (sort === "full_name" ? "asc" : "desc");
const types = opts.types || []; const types = opts.types || [];
let type = "all"; let type = "all";
if ( if (
types.includes("all") || types.includes("all") ||
(types.includes("owner") && types.includes("member")) (types.includes("owner") && types.includes("member"))
) { ) {
type = "all"; type = "all";
} else if (types.includes("member")) { } else if (types.includes("member")) {
type = "member"; type = "member";
} }
do { do {
let requestUrl = `https://api.github.com/users/${username}/repos?per_page=100&page=${page++}&type=${type}`; let requestUrl = `https://api.github.com/users/${username}/repos?per_page=100&page=${page++}&type=${type}`;
if (sort && sort !== "star") { if (sort && sort !== "star") {
requestUrl += `&sort=${sort}&direction=${order}`; requestUrl += `&sort=${sort}&direction=${order}`;
} }
tempRepos = await got(requestUrl); tempRepos = await got(requestUrl);
tempRepos = JSON.parse(tempRepos.body); tempRepos = JSON.parse(tempRepos.body);
repos = repos.concat(tempRepos); repos = repos.concat(tempRepos);
} while (tempRepos.length == 100); } while (tempRepos.length == 100);
if (sort == "star") { if (sort == "star") {
repos = repos.sort(function(a, b) { repos = repos.sort(function(a, b) {
if (order == "desc") { if (order == "desc") {
return b.stargazers_count - a.stargazers_count; return b.stargazers_count - a.stargazers_count;
} else { } else {
return a.stargazers_count - b.stargazers_count; return a.stargazers_count - b.stargazers_count;
} }
}); });
} }
return repos; return repos;
} }
/** /**
* @see https://developer.github.com/v3/users/#get-a-single-user * @see https://developer.github.com/v3/users/#get-a-single-user
* @param {string} username * @param {string} username
*/ */
async function getUser(username) { async function getUser(username) {
const res = await got(`https://api.github.com/users/${username}`); const res = await got(`https://api.github.com/users/${username}`);
return JSON.parse(res.body); return JSON.parse(res.body);
} }
module.exports = { module.exports = {
getRepos, getRepos,
getUser getUser
}; };

View file

@ -1,125 +1,125 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Lorem ipsum dolor</title> <title>Lorem ipsum dolor</title>
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css"
/> />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
crossorigin="anonymous" crossorigin="anonymous"
/> />
<script <script
src="https://code.jquery.com/jquery-3.4.1.min.js" src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous" crossorigin="anonymous"
></script> ></script>
</head> </head>
<body> <body>
<div id="loading"> <div id="loading">
<div id="spinner"></div> <div id="spinner"></div>
</div> </div>
<a href="/" class="go_back"><i class="fas fa-arrow-left"></i></a> <a href="/" class="go_back"><i class="fas fa-arrow-left"></i></a>
<div id="background_overlay"></div> <div id="background_overlay"></div>
<div id="background"></div> <div id="background"></div>
<table id="profile_blog"> <table id="profile_blog">
<tbody> <tbody>
<tr> <tr>
<td style="width:8vw;"><div id="profile_img_blog"></div></td> <td style="width:8vw;"><div id="profile_img_blog"></div></td>
<td style="width:52vw;"> <td style="width:52vw;">
<div id="username_blog"></div> <div id="username_blog"></div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div id="blog-display"> <div id="blog-display">
<h1 id="blog_title">Lorem ipsum dolor</h1> <h1 id="blog_title">Lorem ipsum dolor</h1>
<h2 id="blog_sub_title"> <h2 id="blog_sub_title">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</h2> </h2>
<div id="blog"> <div id="blog">
<img <img
src="https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1450" src="https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1450"
/> />
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut placerat Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut placerat
pretium sem, ac maximus dui sodales a. Nunc aliquet hendrerit turpis pretium sem, ac maximus dui sodales a. Nunc aliquet hendrerit turpis
ac egestas. Phasellus volutpat tristique maximus. ac egestas. Phasellus volutpat tristique maximus.
<b>Pellentesque feugiat eget nisi et dignissim.</b> Nam nibh erat, <b>Pellentesque feugiat eget nisi et dignissim.</b> Nam nibh erat,
sollicitudin non facilisis nec, scelerisque nec ipsum. Sed accumsan sollicitudin non facilisis nec, scelerisque nec ipsum. Sed accumsan
velit condimentum, pharetra felis vitae, commodo tellus. velit condimentum, pharetra felis vitae, commodo tellus.
<u><i>Mauris consequat luctus orci.</i></u> <u><i>Mauris consequat luctus orci.</i></u>
</p> </p>
<p> <p>
Vivamus pharetra lobortis dui non tincidunt. Mauris vitae nisi Vivamus pharetra lobortis dui non tincidunt. Mauris vitae nisi
vestibulum, mollis magna a, maximus mi. Suspendisse dictum eget augue vestibulum, mollis magna a, maximus mi. Suspendisse dictum eget augue
quis sodales. Quisque rutrum ligula nec dapibus tincidunt. quis sodales. Quisque rutrum ligula nec dapibus tincidunt.
<span <span
>Proin hendrerit massa a tellus vestibulum, a hendrerit ipsum >Proin hendrerit massa a tellus vestibulum, a hendrerit ipsum
iaculis. Suspendisse potenti.</span iaculis. Suspendisse potenti.</span
> >
Praesent eget erat blandit, finibus sapien vitae, ullamcorper erat. Praesent eget erat blandit, finibus sapien vitae, ullamcorper erat.
Integer blandit, felis at ullamcorper maximus, odio lectus pretium Integer blandit, felis at ullamcorper maximus, odio lectus pretium
mauris, vel consequat lectus quam eu risus. Pellentesque gravida nec mauris, vel consequat lectus quam eu risus. Pellentesque gravida nec
diam eget vehicula. diam eget vehicula.
</p> </p>
<img <img
src="https://images.unsplash.com/photo-1556814278-8906c7d3a05f?w=1050" src="https://images.unsplash.com/photo-1556814278-8906c7d3a05f?w=1050"
/> />
<p> <p>
Donec hendrerit turpis non libero eleifend dignissim. Mauris non Donec hendrerit turpis non libero eleifend dignissim. Mauris non
tempor metus, et tristique massa. Integer consequat justo quam, vitae tempor metus, et tristique massa. Integer consequat justo quam, vitae
aliquam arcu vestibulum at. Donec porttitor quam in tempus convallis. aliquam arcu vestibulum at. Donec porttitor quam in tempus convallis.
Praesent feugiat eget eros vitae accumsan. Duis ultricies odio quis Praesent feugiat eget eros vitae accumsan. Duis ultricies odio quis
nisl volutpat, consectetur imperdiet sem laoreet. Quisque maximus nisl volutpat, consectetur imperdiet sem laoreet. Quisque maximus
semper ligula at tincidunt. Pellentesque accumsan varius vehicula. semper ligula at tincidunt. Pellentesque accumsan varius vehicula.
</p> </p>
</div> </div>
</div> </div>
<div id="footer_blog"> <div id="footer_blog">
<a href="https://github.com/imfunniee" target="_blank" <a href="https://github.com/imfunniee" target="_blank"
>made on earth by a human</a >made on earth by a human</a
> >
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
setTimeout(function() { setTimeout(function() {
document.getElementById("loading").classList.add("animated"); document.getElementById("loading").classList.add("animated");
document.getElementById("loading").classList.add("fadeOut"); document.getElementById("loading").classList.add("fadeOut");
setTimeout(function() { setTimeout(function() {
document.getElementById("loading").classList.remove("animated"); document.getElementById("loading").classList.remove("animated");
document.getElementById("loading").classList.remove("fadeOut"); document.getElementById("loading").classList.remove("fadeOut");
document.getElementById("loading").style.display = "none"; document.getElementById("loading").style.display = "none";
}, 800); }, 800);
}, 1500); }, 1500);
$.getJSON("../../config.json", function(user) { $.getJSON("../../config.json", function(user) {
var icon = document.createElement("link"); var icon = document.createElement("link");
icon.setAttribute("rel", "icon"); icon.setAttribute("rel", "icon");
icon.setAttribute("href", user[0].userimg); icon.setAttribute("href", user[0].userimg);
icon.setAttribute("type", "image/png"); icon.setAttribute("type", "image/png");
document.getElementsByTagName("head")[0].appendChild(icon); document.getElementsByTagName("head")[0].appendChild(icon);
document.getElementById( document.getElementById(
"profile_img_blog" "profile_img_blog"
).style.background = `url('${user[0].userimg}') center center`; ).style.background = `url('${user[0].userimg}') center center`;
document.getElementById( document.getElementById(
"username_blog" "username_blog"
).innerHTML = `<span style="display:${ ).innerHTML = `<span style="display:${
user[0].name == null || !user[0].name ? "none" : "block" user[0].name == null || !user[0].name ? "none" : "block"
};">${user[0].name}</span>@${user[0].username}<b id="blog_time"></b>`; };">${user[0].name}</span>@${user[0].username}<b id="blog_time"></b>`;
if ((user[0].theme = "dark.css")) { if ((user[0].theme = "dark.css")) {
document.querySelector("#background_overlay").style.background = document.querySelector("#background_overlay").style.background =
"linear-gradient(0deg, rgba(10, 10, 10, 1), rgba(10, 10, 10, 0.1))"; "linear-gradient(0deg, rgba(10, 10, 10, 1), rgba(10, 10, 10, 0.1))";
} else { } else {
document.querySelector("#background_overlay").style.background = document.querySelector("#background_overlay").style.background =
"linear-gradient(0deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.1))"; "linear-gradient(0deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.1))";
} }
}); });
</script> </script>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load diff

View file

@ -1,121 +1,121 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title> <title></title>
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css"
/> />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
crossorigin="anonymous" crossorigin="anonymous"
/> />
<script <script
src="https://code.jquery.com/jquery-3.4.1.min.js" src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous" crossorigin="anonymous"
></script> ></script>
<script src="https://unpkg.com/magic-grid/dist/magic-grid.min.js"></script> <script src="https://unpkg.com/magic-grid/dist/magic-grid.min.js"></script>
<link rel="stylesheet" href="index.css" /> <link rel="stylesheet" href="index.css" />
</head> </head>
<body> <body>
<div id="loading"> <div id="loading">
<div id="spinner"></div> <div id="spinner"></div>
</div> </div>
<div id="profile"> <div id="profile">
<div id="profile_img"></div> <div id="profile_img"></div>
<div id="username"> <div id="username">
<div id="fullname"></div> <div id="fullname"></div>
</div> </div>
<div id="userbio"></div> <div id="userbio"></div>
<div id="about"></div> <div id="about"></div>
</div> </div>
<div id="display"> <div id="display">
<div id="work"> <div id="work">
<h1>Work.</h1> <h1>Work.</h1>
<div class="projects" id="work_section"></div> <div class="projects" id="work_section"></div>
</div> </div>
<div id="forks" style="display:none;"> <div id="forks" style="display:none;">
<h1>Forks.</h1> <h1>Forks.</h1>
<div class="projects" id="forks_section"></div> <div class="projects" id="forks_section"></div>
</div> </div>
<div id="blog_section"> <div id="blog_section">
<h1>Blog.</h1> <h1>Blog.</h1>
<div id="blogs"></div> <div id="blogs"></div>
</div> </div>
<div id="footer"> <div id="footer">
<a href="https://github.com/imfunniee" target="_blank" <a href="https://github.com/imfunniee" target="_blank"
>made on earth by a human</a >made on earth by a human</a
> >
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
setTimeout(function() { setTimeout(function() {
document.getElementById("loading").classList.add("animated"); document.getElementById("loading").classList.add("animated");
document.getElementById("loading").classList.add("fadeOut"); document.getElementById("loading").classList.add("fadeOut");
setTimeout(function() { setTimeout(function() {
document.getElementById("loading").classList.remove("animated"); document.getElementById("loading").classList.remove("animated");
document.getElementById("loading").classList.remove("fadeOut"); document.getElementById("loading").classList.remove("fadeOut");
document.getElementById("loading").style.display = "none"; document.getElementById("loading").style.display = "none";
}, 800); }, 800);
}, 1500); }, 1500);
$.getJSON("blog.json", function(blog) { $.getJSON("blog.json", function(blog) {
blog = blog || []; blog = blog || [];
if (blog.length == 0) { if (blog.length == 0) {
return (document.getElementById("blog_section").style.display = return (document.getElementById("blog_section").style.display =
"none"); "none");
} }
for (var i = 0; i < blog.length; i++) { for (var i = 0; i < blog.length; i++) {
$("#blogs").append(` $("#blogs").append(`
<a href="./blog/${blog[i].url_title}/" target="_blank"> <a href="./blog/${blog[i].url_title}/" target="_blank">
<section> <section>
<img src="./blog/${blog[i].url_title}/${blog[i].top_image}"> <img src="./blog/${blog[i].url_title}/${blog[i].top_image}">
<div class="blog_container"> <div class="blog_container">
<div class="section_title">${blog[i].title}</div> <div class="section_title">${blog[i].title}</div>
<div class="about_section"> <div class="about_section">
${blog[i].sub_title} ${blog[i].sub_title}
</div> </div>
</div> </div>
</section> </section>
</a> </a>
`); `);
} }
}).fail(function() { }).fail(function() {
return (document.getElementById("blog_section").style.display = "none"); return (document.getElementById("blog_section").style.display = "none");
}); });
</script> </script>
<script> <script>
const magicProjectsGrid = new MagicGrid({ const magicProjectsGrid = new MagicGrid({
container: "#work_section", container: "#work_section",
animate: false, animate: false,
gutter: 30, // default gutter size gutter: 30, // default gutter size
static: true, static: true,
useMin: false, useMin: false,
maxColumns: 2, maxColumns: 2,
useTransform: true useTransform: true
}); });
const magicForksGrid = new MagicGrid({ const magicForksGrid = new MagicGrid({
container: "#forks_section", container: "#forks_section",
animate: false, animate: false,
gutter: 30, // default gutter size gutter: 30, // default gutter size
static: true, static: true,
useMin: false, useMin: false,
maxColumns: 2, maxColumns: 2,
useTransform: true useTransform: true
}); });
$("document").ready(() => { $("document").ready(() => {
magicProjectsGrid.listen(); magicProjectsGrid.listen();
magicForksGrid.listen(); magicForksGrid.listen();
}); });
</script> </script>
</body> </body>
</html> </html>

View file

@ -1,49 +1,49 @@
:root { :root {
--bg-color: rgb(10, 10, 10); --bg-color: rgb(10, 10, 10);
--text-color: #fff; --text-color: #fff;
--blog-gray-color: rgb(180, 180, 180); --blog-gray-color: rgb(180, 180, 180);
--background-image: linear-gradient( --background-image: linear-gradient(
90deg, 90deg,
rgba(10, 10, 10, 0.3), rgba(10, 10, 10, 0.3),
rgb(10, 10, 10, 1) rgb(10, 10, 10, 1)
), ),
url("{{{background}}}"); url("{{{background}}}");
--background-background: linear-gradient( --background-background: linear-gradient(
0deg, 0deg,
rgba(10, 10, 10, 1), rgba(10, 10, 10, 1),
rgba(10, 10, 10, 0.6) rgba(10, 10, 10, 0.6)
), ),
url("{{{background}}}") center center fixed; url("{{{background}}}") center center fixed;
--height: 50vh; --height: 50vh;
} }
#display h1 { #display h1 {
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
-webkit-text-fill-color: #fff; -webkit-text-fill-color: #fff;
} }
#blog-display h1 { #blog-display h1 {
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
-webkit-text-fill-color: #fff; -webkit-text-fill-color: #fff;
} }
.projects section { .projects section {
background: rgb(20, 20, 20); background: rgb(20, 20, 20);
} }
#blog_section section { #blog_section section {
background: rgb(20, 20, 20); background: rgb(20, 20, 20);
} }
@media (max-width: 800px) { @media (max-width: 800px) {
:root { :root {
--background-image: linear-gradient( --background-image: linear-gradient(
0deg, 0deg,
rgba(10, 10, 10, 1), rgba(10, 10, 10, 1),
rgba(10, 10, 10, 0) rgba(10, 10, 10, 0)
), ),
url("{{{background}}}") !important; url("{{{background}}}") !important;
} }
} }

View file

@ -1,12 +1,12 @@
:root { :root {
--bg-color: #fff; --bg-color: #fff;
--text-color: rgb(10, 10, 10); --text-color: rgb(10, 10, 10);
--blog-gray-color: rgb(80, 80, 80); --blog-gray-color: rgb(80, 80, 80);
--background-image: linear-gradient( --background-image: linear-gradient(
90deg, 90deg,
rgba(10, 10, 10, 0.4), rgba(10, 10, 10, 0.4),
rgb(10, 10, 10, 0.4) rgb(10, 10, 10, 0.4)
), ),
url("{{{background}}}"); url("{{{background}}}");
--background-background: #fff; --background-background: #fff;
} }

120
bin/gitfolio.js Normal file → Executable file
View file

@ -1,60 +1,60 @@
#! /usr/bin/env node #! /usr/bin/env node
/* Argument parser */ /* Argument parser */
const program = require("commander"); const program = require("commander");
process.env.OUT_DIR = process.env.OUT_DIR || process.cwd(); process.env.OUT_DIR = process.env.OUT_DIR || process.cwd();
const { buildCommand } = require("../build"); const { buildCommand } = require("../build");
const { updateCommand } = require("../update"); const { updateCommand } = require("../update");
const { uiCommand } = require("../ui"); const { uiCommand } = require("../ui");
const { runCommand } = require("../run"); const { runCommand } = require("../run");
const { version } = require("../package.json"); const { version } = require("../package.json");
function collect(val, memo) { function collect(val, memo) {
memo.push(val); memo.push(val);
return memo; return memo;
} }
program program
.command("build <username>") .command("build <username>")
.description( .description(
"Build site with your GitHub username. This will be used to customize your site" "Build site with your GitHub username. This will be used to customize your site"
) )
.option("-t, --theme [theme]", "specify a theme to use", "light") .option("-t, --theme [theme]", "specify a theme to use", "light")
.option("-b, --background [background]", "set the background image") .option("-b, --background [background]", "set the background image")
.option("-f, --fork", "includes forks with repos") .option("-f, --fork", "includes forks with repos")
.option("-s, --sort [sort]", "set default sort for repository", "created") .option("-s, --sort [sort]", "set default sort for repository", "created")
.option("-o, --order [order]", "set default order on sort", "asc") .option("-o, --order [order]", "set default order on sort", "asc")
.option("-w, --twitter [username]", "specify twitter username") .option("-w, --twitter [username]", "specify twitter username")
.option("-l, --linkedin [username]", "specify linkedin username") .option("-l, --linkedin [username]", "specify linkedin username")
.option("-m, --medium [username]", "specify medium username") .option("-m, --medium [username]", "specify medium username")
.option("-d, --dribbble [username]", "specify dribbble username") .option("-d, --dribbble [username]", "specify dribbble username")
.action(buildCommand); .action(buildCommand);
program program
.command("update") .command("update")
.description("Update user and repository data") .description("Update user and repository data")
.action(updateCommand); .action(updateCommand);
program program
.command("ui") .command("ui")
.description("Create and Manage blogs with ease") .description("Create and Manage blogs with ease")
.action(uiCommand); .action(uiCommand);
program program
.command("run") .command("run")
.description("Run build files") .description("Run build files")
.option("-p, --port [port]", "provide a port for localhost, default is 3000") .option("-p, --port [port]", "provide a port for localhost, default is 3000")
.action(runCommand); .action(runCommand);
program.on("command:*", () => { program.on("command:*", () => {
console.log("Unknown Command: " + program.args.join(" ")); console.log("Unknown Command: " + program.args.join(" "));
program.help(); program.help();
}); });
program program
.version(version, "-v --version") .version(version, "-v --version")
.usage("<command> [options]") .usage("<command> [options]")
.parse(process.argv); .parse(process.argv);
if (program.args.length === 0) program.help(); if (program.args.length === 0) program.help();

188
build.js
View file

@ -1,94 +1,94 @@
/* Filepath utilities */ /* Filepath utilities */
const path = require("path"); const path = require("path");
/* Promise library */ /* Promise library */
const bluebird = require("bluebird"); const bluebird = require("bluebird");
const hbs = require("handlebars"); const hbs = require("handlebars");
/* Creates promise-returning async functions /* Creates promise-returning async functions
from callback-passed async functions */ from callback-passed async functions */
const fs = bluebird.promisifyAll(require("fs")); const fs = bluebird.promisifyAll(require("fs"));
const { updateHTML } = require("./populate"); const { updateHTML } = require("./populate");
const { getConfig, outDir } = require("./utils"); const { getConfig, outDir } = require("./utils");
const assetDir = path.resolve(`${__dirname}/assets/`); const assetDir = path.resolve(`${__dirname}/assets/`);
const config = path.join(outDir, "config.json"); const config = path.join(outDir, "config.json");
/** /**
* Creates the stylesheet used by the site from a template stylesheet. * Creates the stylesheet used by the site from a template stylesheet.
* *
* Theme styles are added to the new stylesheet depending on command line * Theme styles are added to the new stylesheet depending on command line
* arguments. * arguments.
*/ */
async function populateCSS({ async function populateCSS({
theme = "light", theme = "light",
background = "https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1500&q=80" background = "https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1500&q=80"
} = {}) { } = {}) {
/* Get the theme the user requests. Defaults to 'light' */ /* Get the theme the user requests. Defaults to 'light' */
theme = `${theme}.css`; theme = `${theme}.css`;
let template = path.resolve(assetDir, "index.css"); let template = path.resolve(assetDir, "index.css");
let stylesheet = path.join(outDir, "index.css"); let stylesheet = path.join(outDir, "index.css");
try { try {
await fs.accessAsync(outDir, fs.constants.F_OK); await fs.accessAsync(outDir, fs.constants.F_OK);
} catch (err) { } catch (err) {
await fs.mkdirAsync(outDir); await fs.mkdirAsync(outDir);
} }
/* Copy over the template CSS stylesheet */ /* Copy over the template CSS stylesheet */
await fs.copyFileAsync(template, stylesheet); await fs.copyFileAsync(template, stylesheet);
/* Get an array of every available theme */ /* Get an array of every available theme */
let themes = await fs.readdirAsync(path.join(assetDir, "themes")); let themes = await fs.readdirAsync(path.join(assetDir, "themes"));
if (!themes.includes(theme)) { if (!themes.includes(theme)) {
console.error('Error: Requested theme not found. Defaulting to "light".'); console.error('Error: Requested theme not found. Defaulting to "light".');
theme = "light"; theme = "light";
} }
/* Read in the theme stylesheet */ /* Read in the theme stylesheet */
let themeSource = await fs.readFileSync(path.join(assetDir, "themes", theme)); let themeSource = await fs.readFileSync(path.join(assetDir, "themes", theme));
themeSource = themeSource.toString("utf-8"); themeSource = themeSource.toString("utf-8");
let themeTemplate = hbs.compile(themeSource); let themeTemplate = hbs.compile(themeSource);
let styles = themeTemplate({ let styles = themeTemplate({
background: `${background}` background: `${background}`
}); });
/* Add the user-specified styles to the new stylesheet */ /* Add the user-specified styles to the new stylesheet */
await fs.appendFileAsync(stylesheet, styles); await fs.appendFileAsync(stylesheet, styles);
/* Update the config file with the user's theme choice */ /* Update the config file with the user's theme choice */
const data = await getConfig(); const data = await getConfig();
data[0].theme = theme; data[0].theme = theme;
await fs.writeFileAsync(config, JSON.stringify(data, null, " ")); await fs.writeFileAsync(config, JSON.stringify(data, null, " "));
} }
async function populateConfig(opts) { async function populateConfig(opts) {
const data = await getConfig(); const data = await getConfig();
Object.assign(data[0], opts); Object.assign(data[0], opts);
await fs.writeFileAsync(config, JSON.stringify(data, null, " ")); await fs.writeFileAsync(config, JSON.stringify(data, null, " "));
} }
async function buildCommand(username, program) { async function buildCommand(username, program) {
await populateCSS(program); await populateCSS(program);
let types; let types;
if (!program.include || !program.include.length) { if (!program.include || !program.include.length) {
types = ["all"]; types = ["all"];
} else { } else {
types = program.include; types = program.include;
} }
const opts = { const opts = {
sort: program.sort, sort: program.sort,
order: program.order, order: program.order,
includeFork: program.fork ? true : false, includeFork: program.fork ? true : false,
types, types,
twitter: program.twitter, twitter: program.twitter,
linkedin: program.linkedin, linkedin: program.linkedin,
medium: program.medium, medium: program.medium,
dribbble: program.dribbble dribbble: program.dribbble
}; };
await populateConfig(opts); await populateConfig(opts);
updateHTML(("%s", username), opts); updateHTML(("%s", username), opts);
} }
module.exports = { module.exports = {
buildCommand, buildCommand,
populateCSS, populateCSS,
populateConfig populateConfig
}; };

View file

@ -1,11 +1,11 @@
[ [
{ {
"username": null, "username": null,
"name": null, "name": null,
"userimg": null, "userimg": null,
"sort": null, "sort": null,
"order": null, "order": null,
"includeFork": null, "includeFork": null,
"theme": "light.css" "theme": "light.css"
} }
] ]

2596
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,48 +1,48 @@
{ {
"name": "gitfolio", "name": "gitfolio",
"version": "0.1.5", "version": "0.1.5",
"description": "a portfolio website for everyone to showcase their work", "description": "a portfolio website for everyone to showcase their work",
"main": "build.js", "main": "build.js",
"bin": "bin/gitfolio.js", "bin": "bin/gitfolio.js",
"scripts": { "scripts": {
"cli": "OUT_DIR='./dist' node bin/gitfolio.js", "cli": "OUT_DIR='./dist' node bin/gitfolio.js",
"clean": "rm -rf ./dist/*", "clean": "rm -rf ./dist/*",
"prettier": "prettier --write \"./**/*.{js,jsx,json,html,css,md}\"", "prettier": "prettier --write \"./**/*.{js,jsx,json,html,css,md}\"",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": { "author": {
"name": "@imfunniee and community", "name": "@imfunniee and community",
"email": "imfunny@wybemf.com", "email": "imfunny@wybemf.com",
"url": "https://imfunniee.github.io" "url": "https://imfunniee.github.io"
}, },
"bugs": "https://github.com/imfunniee/gitfolio/issues", "bugs": "https://github.com/imfunniee/gitfolio/issues",
"homepage": "https://github.com/imfunniee/gitfolio", "homepage": "https://github.com/imfunniee/gitfolio",
"keywords": [ "keywords": [
"personal-website", "personal-website",
"github", "github",
"portfolio", "portfolio",
"portfolio website", "portfolio website",
"blog website", "blog website",
"blog", "blog",
"gitfolio", "gitfolio",
"git" "git"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/imfunniee/gitfolio" "url": "https://github.com/imfunniee/gitfolio"
}, },
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"bluebird": "^3.5.4", "bluebird": "^3.5.4",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"commander": "^2.20.0", "commander": "^2.20.0",
"ejs": "^2.6.2", "ejs": "^2.6.2",
"express": "^4.17.0", "express": "^4.17.0",
"github-emoji": "^1.1.1", "github-emoji": "^1.1.1",
"got": "^9.6.0", "got": "^9.6.0",
"handlebars": "^4.1.2", "handlebars": "^4.1.2",
"jsdom": "^15.1.0", "jsdom": "^15.1.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"prettier": "^1.18.2" "prettier": "^1.18.2"
} }
} }

View file

@ -1,172 +1,172 @@
const fs = require("fs"); const fs = require("fs");
const emoji = require("github-emoji"); const emoji = require("github-emoji");
const jsdom = require("jsdom").JSDOM, const jsdom = require("jsdom").JSDOM,
options = { options = {
resources: "usable" resources: "usable"
}; };
const { getConfig, outDir } = require("./utils"); const { getConfig, outDir } = require("./utils");
const { getRepos, getUser } = require("./api"); const { getRepos, getUser } = require("./api");
function convertToEmoji(text) { function convertToEmoji(text) {
if (text == null) return; if (text == null) return;
text = text.toString(); text = text.toString();
var pattern = /(?<=:\s*).*?(?=\s*:)/gs; var pattern = /(?<=:\s*).*?(?=\s*:)/gs;
if (text.match(pattern) != null) { if (text.match(pattern) != null) {
var str = text.match(pattern); var str = text.match(pattern);
str = str.filter(function(arr) { str = str.filter(function(arr) {
return /\S/.test(arr); return /\S/.test(arr);
}); });
for (i = 0; i < str.length; i++) { for (i = 0; i < str.length; i++) {
if (emoji.URLS[str[i]] != undefined) { if (emoji.URLS[str[i]] != undefined) {
text = text.replace( text = text.replace(
`:${str[i]}:`, `:${str[i]}:`,
`<img src="${emoji.URLS[str[i]]}" class="emoji">` `<img src="${emoji.URLS[str[i]]}" class="emoji">`
); );
} }
} }
return text; return text;
} else { } else {
return text; return text;
} }
} }
module.exports.updateHTML = (username, opts) => { module.exports.updateHTML = (username, opts) => {
const { includeFork, twitter, linkedin, medium, dribbble } = opts; const { includeFork, twitter, linkedin, medium, dribbble } = opts;
//add data to assets/index.html //add data to assets/index.html
jsdom jsdom
.fromFile(`${__dirname}/assets/index.html`, options) .fromFile(`${__dirname}/assets/index.html`, options)
.then(function(dom) { .then(function(dom) {
let window = dom.window, let window = dom.window,
document = window.document; document = window.document;
(async () => { (async () => {
try { try {
console.log("Building HTML/CSS..."); console.log("Building HTML/CSS...");
const repos = await getRepos(username, opts); const repos = await getRepos(username, opts);
for (var i = 0; i < repos.length; i++) { for (var i = 0; i < repos.length; i++) {
let element; let element;
if (repos[i].fork == false) { if (repos[i].fork == false) {
element = document.getElementById("work_section"); element = document.getElementById("work_section");
} else if (includeFork == true) { } else if (includeFork == true) {
document.getElementById("forks").style.display = "block"; document.getElementById("forks").style.display = "block";
element = document.getElementById("forks_section"); element = document.getElementById("forks_section");
} else { } else {
continue; continue;
} }
element.innerHTML += ` element.innerHTML += `
<a href="${repos[i].html_url}" target="_blank"> <a href="${repos[i].html_url}" target="_blank">
<section> <section>
<div class="section_title">${repos[i].name}</div> <div class="section_title">${repos[i].name}</div>
<div class="about_section"> <div class="about_section">
<span style="display:${ <span style="display:${
repos[i].description == undefined repos[i].description == undefined
? "none" ? "none"
: "block" : "block"
};">${convertToEmoji(repos[i].description)}</span> };">${convertToEmoji(repos[i].description)}</span>
</div> </div>
<div class="bottom_section"> <div class="bottom_section">
<span style="display:${ <span style="display:${
repos[i].language == null repos[i].language == null
? "none" ? "none"
: "inline-block" : "inline-block"
};"><i class="fas fa-code"></i>&nbsp; ${ };"><i class="fas fa-code"></i>&nbsp; ${
repos[i].language repos[i].language
}</span> }</span>
<span><i class="fas fa-star"></i>&nbsp; ${ <span><i class="fas fa-star"></i>&nbsp; ${
repos[i].stargazers_count repos[i].stargazers_count
}</span> }</span>
<span><i class="fas fa-code-branch"></i>&nbsp; ${ <span><i class="fas fa-code-branch"></i>&nbsp; ${
repos[i].forks_count repos[i].forks_count
}</span> }</span>
</div> </div>
</section> </section>
</a>`; </a>`;
} }
const user = await getUser(username); const user = await getUser(username);
document.title = user.login; document.title = user.login;
var icon = document.createElement("link"); var icon = document.createElement("link");
icon.setAttribute("rel", "icon"); icon.setAttribute("rel", "icon");
icon.setAttribute("href", user.avatar_url); icon.setAttribute("href", user.avatar_url);
icon.setAttribute("type", "image/png"); icon.setAttribute("type", "image/png");
document.getElementsByTagName("head")[0].appendChild(icon); document.getElementsByTagName("head")[0].appendChild(icon);
document.getElementById( document.getElementById(
"profile_img" "profile_img"
).style.background = `url('${user.avatar_url}') center center`; ).style.background = `url('${user.avatar_url}') center center`;
document.getElementById( document.getElementById(
"username" "username"
).innerHTML = `<span style="display:${ ).innerHTML = `<span style="display:${
user.name == null || !user.name ? "none" : "block" user.name == null || !user.name ? "none" : "block"
};">${user.name}</span><a href="${user.html_url}">@${user.login}</a>`; };">${user.name}</span><a href="${user.html_url}">@${user.login}</a>`;
//document.getElementById("github_link").href = `https://github.com/${user.login}`; //document.getElementById("github_link").href = `https://github.com/${user.login}`;
document.getElementById("userbio").innerHTML = convertToEmoji( document.getElementById("userbio").innerHTML = convertToEmoji(
user.bio user.bio
); );
document.getElementById("userbio").style.display = document.getElementById("userbio").style.display =
user.bio == null || !user.bio ? "none" : "block"; user.bio == null || !user.bio ? "none" : "block";
document.getElementById("about").innerHTML = ` document.getElementById("about").innerHTML = `
<span style="display:${ <span style="display:${
user.company == null || !user.company ? "none" : "block" user.company == null || !user.company ? "none" : "block"
};"><i class="fas fa-users"></i> &nbsp; ${user.company}</span> };"><i class="fas fa-users"></i> &nbsp; ${user.company}</span>
<span style="display:${ <span style="display:${
user.email == null || !user.email ? "none" : "block" user.email == null || !user.email ? "none" : "block"
};"><i class="fas fa-envelope"></i> &nbsp; ${user.email}</span> };"><i class="fas fa-envelope"></i> &nbsp; ${user.email}</span>
<span style="display:${ <span style="display:${
user.blog == null || !user.blog ? "none" : "block" user.blog == null || !user.blog ? "none" : "block"
};"><i class="fas fa-link"></i> &nbsp; <a href="${user.blog}">${ };"><i class="fas fa-link"></i> &nbsp; <a href="${user.blog}">${
user.blog user.blog
}</a></span> }</a></span>
<span style="display:${ <span style="display:${
user.location == null || !user.location ? "none" : "block" user.location == null || !user.location ? "none" : "block"
};"><i class="fas fa-map-marker-alt"></i> &nbsp;&nbsp; ${ };"><i class="fas fa-map-marker-alt"></i> &nbsp;&nbsp; ${
user.location user.location
}</span> }</span>
<span style="display:${ <span style="display:${
user.hireable == false || !user.hireable ? "none" : "block" user.hireable == false || !user.hireable ? "none" : "block"
};"><i class="fas fa-user-tie"></i> &nbsp;&nbsp; Available for hire</span> };"><i class="fas fa-user-tie"></i> &nbsp;&nbsp; Available for hire</span>
<div class="socials"> <div class="socials">
<span style="display:${ <span style="display:${
twitter == null ? "none !important" : "block" twitter == null ? "none !important" : "block"
};"><a href="https://www.twitter.com/${twitter}" target="_blank" class="socials"><i class="fab fa-twitter"></i></a></span> };"><a href="https://www.twitter.com/${twitter}" target="_blank" class="socials"><i class="fab fa-twitter"></i></a></span>
<span style="display:${ <span style="display:${
dribbble == null ? "none !important" : "block" dribbble == null ? "none !important" : "block"
};"><a href="https://www.dribbble.com/${dribbble}" target="_blank" class="socials"><i class="fab fa-dribbble"></i></a></span> };"><a href="https://www.dribbble.com/${dribbble}" target="_blank" class="socials"><i class="fab fa-dribbble"></i></a></span>
<span style="display:${ <span style="display:${
linkedin == null ? "none !important" : "block" linkedin == null ? "none !important" : "block"
};"><a href="https://www.linkedin.com/in/${linkedin}/" target="_blank" class="socials"><i class="fab fa-linkedin-in"></i></a></span> };"><a href="https://www.linkedin.com/in/${linkedin}/" target="_blank" class="socials"><i class="fab fa-linkedin-in"></i></a></span>
<span style="display:${ <span style="display:${
medium == null ? "none !important" : "block" medium == null ? "none !important" : "block"
};"><a href="https://www.medium.com/@${medium}/" target="_blank" class="socials"><i class="fab fa-medium-m"></i></a></span> };"><a href="https://www.medium.com/@${medium}/" target="_blank" class="socials"><i class="fab fa-medium-m"></i></a></span>
</div> </div>
`; `;
//add data to config.json //add data to config.json
const data = await getConfig(); const data = await getConfig();
data[0].username = user.login; data[0].username = user.login;
data[0].name = user.name; data[0].name = user.name;
data[0].userimg = user.avatar_url; data[0].userimg = user.avatar_url;
await fs.writeFile( await fs.writeFile(
`${outDir}/config.json`, `${outDir}/config.json`,
JSON.stringify(data, null, " "), JSON.stringify(data, null, " "),
function(err) { function(err) {
if (err) throw err; if (err) throw err;
console.log("Config file updated."); console.log("Config file updated.");
} }
); );
await fs.writeFile( await fs.writeFile(
`${outDir}/index.html`, `${outDir}/index.html`,
"<!DOCTYPE html>" + window.document.documentElement.outerHTML, "<!DOCTYPE html>" + window.document.documentElement.outerHTML,
function(error) { function(error) {
if (error) throw error; if (error) throw error;
console.log(`Build Complete, Files can be Found @ ${outDir}\n`); console.log(`Build Complete, Files can be Found @ ${outDir}\n`);
} }
); );
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
})(); })();
}) })
.catch(function(error) { .catch(function(error) {
console.log(error); console.log(error);
}); });
}; };

44
run.js
View file

@ -1,22 +1,22 @@
const express = require("express"); const express = require("express");
const path = require("path"); const path = require("path");
const outDir = path.resolve("./dist/" || process.env.OUT_DIR); const outDir = path.resolve("./dist/" || process.env.OUT_DIR);
const app = express(); const app = express();
app.use(express.static(`${outDir}`)); app.use(express.static(`${outDir}`));
function runCommand(program) { function runCommand(program) {
let port = program.port ? program.port : 3000; let port = program.port ? program.port : 3000;
app.get("/", function(req, res) { app.get("/", function(req, res) {
res.sendFile("/index.html"); res.sendFile("/index.html");
}); });
app.listen(port); app.listen(port);
console.log( console.log(
`\nGitfolio running on port ${port}, Navigate to http://localhost:${port} in your browser\n` `\nGitfolio running on port ${port}, Navigate to http://localhost:${port} in your browser\n`
); );
} }
module.exports = { module.exports = {
runCommand runCommand
}; };

482
ui.js
View file

@ -1,241 +1,241 @@
const fs = require("fs"); const fs = require("fs");
const express = require("express"); const express = require("express");
const { updateHTML } = require("./populate"); const { updateHTML } = require("./populate");
const { populateCSS, populateConfig } = require("./build"); const { populateCSS, populateConfig } = require("./build");
const { updateCommand } = require("./update"); const { updateCommand } = require("./update");
const app = express(); const app = express();
app.set("view engine", "ejs"); app.set("view engine", "ejs");
app.use(express.static(__dirname + "/views")); app.use(express.static(__dirname + "/views"));
app.set("views", __dirname + "/views"); app.set("views", __dirname + "/views");
app.use( app.use(
express.json({ express.json({
limit: "50mb" limit: "50mb"
}) })
); );
app.use( app.use(
express.urlencoded({ express.urlencoded({
limit: "50mb", limit: "50mb",
extended: true extended: true
}) })
); );
const port = 3000; const port = 3000;
const jsdom = require("jsdom").JSDOM, const jsdom = require("jsdom").JSDOM,
options = { options = {
resources: "usable" resources: "usable"
}; };
global.DOMParser = new jsdom().window.DOMParser; global.DOMParser = new jsdom().window.DOMParser;
const { getBlog, outDir } = require("./utils"); const { getBlog, outDir } = require("./utils");
function createBlog(title, subtitle, folder, topImage, images, content) { function createBlog(title, subtitle, folder, topImage, images, content) {
// Checks to make sure this directory actually exists // Checks to make sure this directory actually exists
// and creates it if it doesn't // and creates it if it doesn't
if (!fs.existsSync(`${outDir}/blog/`)) { if (!fs.existsSync(`${outDir}/blog/`)) {
fs.mkdirSync( fs.mkdirSync(
`${outDir}/blog/`, `${outDir}/blog/`,
{ {
recursive: true recursive: true
}, },
err => {} err => {}
); );
} }
if (!fs.existsSync(`${outDir}/blog/${folder}`)) { if (!fs.existsSync(`${outDir}/blog/${folder}`)) {
fs.mkdirSync(`${outDir}/blog/${folder}`, { fs.mkdirSync(`${outDir}/blog/${folder}`, {
recursive: true recursive: true
}); });
} }
fs.copyFile( fs.copyFile(
`${__dirname}/assets/blog/blogTemplate.html`, `${__dirname}/assets/blog/blogTemplate.html`,
`${outDir}/blog/${folder}/index.html`, `${outDir}/blog/${folder}/index.html`,
err => { err => {
if (err) throw err; if (err) throw err;
jsdom jsdom
.fromFile(`${outDir}/blog/${folder}/index.html`, options) .fromFile(`${outDir}/blog/${folder}/index.html`, options)
.then(function(dom) { .then(function(dom) {
let window = dom.window, let window = dom.window,
document = window.document; document = window.document;
let style = document.createElement("link"); let style = document.createElement("link");
style.setAttribute("rel", "stylesheet"); style.setAttribute("rel", "stylesheet");
style.setAttribute("href", "../../index.css"); style.setAttribute("href", "../../index.css");
document.getElementsByTagName("head")[0].appendChild(style); document.getElementsByTagName("head")[0].appendChild(style);
document.getElementsByTagName("title")[0].textContent = title; document.getElementsByTagName("title")[0].textContent = title;
document.getElementById("blog_title").textContent = title; document.getElementById("blog_title").textContent = title;
document.getElementById("blog_sub_title").textContent = subtitle; document.getElementById("blog_sub_title").textContent = subtitle;
document.getElementById( document.getElementById(
"background" "background"
).style.background = `url('top_image.${ ).style.background = `url('top_image.${
topImage.split("/")[1].split(";")[0] topImage.split("/")[1].split(";")[0]
}') center center`; }') center center`;
if (content != null) { if (content != null) {
var parser = new DOMParser(); var parser = new DOMParser();
content = parser.parseFromString(content, "text/html"); content = parser.parseFromString(content, "text/html");
document.getElementById("blog").innerHTML = document.getElementById("blog").innerHTML =
content.documentElement.innerHTML; content.documentElement.innerHTML;
} }
images = JSON.parse(images); images = JSON.parse(images);
images.forEach((item, index) => { images.forEach((item, index) => {
var base64Image = item.split(";base64,").pop(); var base64Image = item.split(";base64,").pop();
fs.writeFile( fs.writeFile(
`${outDir}/blog/${folder}/img_${index}.${ `${outDir}/blog/${folder}/img_${index}.${
item.split("/")[1].split(";")[0] item.split("/")[1].split(";")[0]
}`, }`,
base64Image, base64Image,
{ {
encoding: "base64" encoding: "base64"
}, },
function(err) { function(err) {
if (err) throw err; if (err) throw err;
} }
); );
}); });
fs.writeFile( fs.writeFile(
`${outDir}/blog/${folder}/index.html`, `${outDir}/blog/${folder}/index.html`,
"<!DOCTYPE html>" + window.document.documentElement.outerHTML, "<!DOCTYPE html>" + window.document.documentElement.outerHTML,
async function(error) { async function(error) {
if (error) throw error; if (error) throw error;
var base64ImageTop = topImage.split(";base64,").pop(); var base64ImageTop = topImage.split(";base64,").pop();
fs.writeFile( fs.writeFile(
`${outDir}/blog/${folder}/top_image.${ `${outDir}/blog/${folder}/top_image.${
topImage.split("/")[1].split(";")[0] topImage.split("/")[1].split(";")[0]
}`, }`,
base64ImageTop, base64ImageTop,
{ {
encoding: "base64" encoding: "base64"
}, },
function(err) { function(err) {
if (err) throw err; if (err) throw err;
} }
); );
let blog_data = { let blog_data = {
url_title: folder, url_title: folder,
title: title, title: title,
sub_title: subtitle, sub_title: subtitle,
top_image: `top_image.${topImage.split("/")[1].split(";")[0]}`, top_image: `top_image.${topImage.split("/")[1].split(";")[0]}`,
visible: true visible: true
}; };
const old_blogs = await getBlog(); const old_blogs = await getBlog();
old_blogs.push(blog_data); old_blogs.push(blog_data);
fs.writeFile( fs.writeFile(
`${outDir}/blog.json`, `${outDir}/blog.json`,
JSON.stringify(old_blogs, null, " "), JSON.stringify(old_blogs, null, " "),
function(err) { function(err) {
if (err) throw err; if (err) throw err;
console.log( console.log(
`Blog created successfully at ${outDir}\\blog\\${folder}\n` `Blog created successfully at ${outDir}\\blog\\${folder}\n`
); );
} }
); );
} }
); );
}) })
.catch(function(error) { .catch(function(error) {
console.log(error); console.log(error);
}); });
} }
); );
} }
function uiCommand() { function uiCommand() {
app.get("/", function(req, res) { app.get("/", function(req, res) {
res.render("index.ejs"); res.render("index.ejs");
}); });
app.get("/update", function(req, res) { app.get("/update", function(req, res) {
if (!fs.existsSync(`${outDir}/config.json`)) { if (!fs.existsSync(`${outDir}/config.json`)) {
return res.send( return res.send(
'You need to run build command before using update<br><a href="/">Go Back</a>' 'You need to run build command before using update<br><a href="/">Go Back</a>'
); );
} }
updateCommand(); updateCommand();
res.redirect("/"); res.redirect("/");
}); });
app.post("/build", function(req, res) { app.post("/build", function(req, res) {
let username = req.body.username; let username = req.body.username;
if (!username) { if (!username) {
return res.send("username can't be empty"); return res.send("username can't be empty");
} }
let sort = req.body.sort ? req.body.sort : "created"; let sort = req.body.sort ? req.body.sort : "created";
let order = req.body.order ? req.body.order : "asc"; let order = req.body.order ? req.body.order : "asc";
let includeFork = req.body.fork == "true" ? true : false; let includeFork = req.body.fork == "true" ? true : false;
let types = ["owner"]; let types = ["owner"];
let twitter = req.body.twitter ? req.body.twitter : null; let twitter = req.body.twitter ? req.body.twitter : null;
let linkedin = req.body.linkedin ? req.body.linkedin : null; let linkedin = req.body.linkedin ? req.body.linkedin : null;
let medium = req.body.medium ? req.body.medium : null; let medium = req.body.medium ? req.body.medium : null;
let dribbble = req.body.dribbble ? req.body.dribbble : null; let dribbble = req.body.dribbble ? req.body.dribbble : null;
let background = req.body.background let background = req.body.background
? req.body.background ? req.body.background
: "https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1500&q=80"; : "https://images.unsplash.com/photo-1553748024-d1b27fb3f960?w=1500&q=80";
let theme = req.body.theme == "on" ? "dark" : "light"; let theme = req.body.theme == "on" ? "dark" : "light";
const opts = { const opts = {
sort: sort, sort: sort,
order: order, order: order,
includeFork: includeFork, includeFork: includeFork,
types, types,
twitter: twitter, twitter: twitter,
linkedin: linkedin, linkedin: linkedin,
medium: medium, medium: medium,
dribbble: dribbble dribbble: dribbble
}; };
updateHTML(username, opts); updateHTML(username, opts);
populateCSS({ populateCSS({
background: background, background: background,
theme: theme theme: theme
}); });
populateConfig(opts); populateConfig(opts);
res.redirect("/"); res.redirect("/");
}); });
app.get("/blog", function(req, res) { app.get("/blog", function(req, res) {
if (!fs.existsSync(`${outDir}/config.json`)) { if (!fs.existsSync(`${outDir}/config.json`)) {
return res.send( return res.send(
'You need to run build command before accessing blogs<br><a href="/">Go Back</a>' 'You need to run build command before accessing blogs<br><a href="/">Go Back</a>'
); );
} }
fs.readFile(`${outDir}/config.json`, function(err, data) { fs.readFile(`${outDir}/config.json`, function(err, data) {
res.render("blog.ejs", { res.render("blog.ejs", {
profile: JSON.parse(data) profile: JSON.parse(data)
}); });
}); });
}); });
app.post("/createBlog", function(req, res) { app.post("/createBlog", function(req, res) {
let title = req.body.title; let title = req.body.title;
let subtitle = req.body.subtitle; let subtitle = req.body.subtitle;
let content = req.body.content ? req.body.content : null; let content = req.body.content ? req.body.content : null;
if (!title) { if (!title) {
return res.send("title can't be empty"); return res.send("title can't be empty");
} }
if (!subtitle) { if (!subtitle) {
return res.send("subtitle can't be empty"); return res.send("subtitle can't be empty");
} }
if (!content) { if (!content) {
return res.send("something isn't working fine, try again :p"); return res.send("something isn't working fine, try again :p");
} }
let folder = title.replace(/[^a-zA-Z ]/g, "").replace(/ /g, "-"); let folder = title.replace(/[^a-zA-Z ]/g, "").replace(/ /g, "-");
let topImage = req.body.top_image; let topImage = req.body.top_image;
let images = req.body.images; let images = req.body.images;
createBlog(title, subtitle, folder, topImage, images, content); createBlog(title, subtitle, folder, topImage, images, content);
res.redirect("/blog"); res.redirect("/blog");
}); });
console.log("\nStarting..."); console.log("\nStarting...");
app.listen(port); app.listen(port);
console.log( console.log(
`The GUI is running on port ${port}, Navigate to http://localhost:${port} in your browser\n` `The GUI is running on port ${port}, Navigate to http://localhost:${port} in your browser\n`
); );
} }
module.exports = { module.exports = {
uiCommand uiCommand
}; };

View file

@ -1,28 +1,28 @@
const { getConfig } = require("./utils"); const { getConfig } = require("./utils");
const { updateHTML } = require("./populate"); const { updateHTML } = require("./populate");
async function updateCommand() { async function updateCommand() {
const data = await getConfig(); const data = await getConfig();
var username = data[0].username; var username = data[0].username;
if (username == null) { if (username == null) {
console.log( console.log(
"username not found in config.json, please run build command before using update" "username not found in config.json, please run build command before using update"
); );
return; return;
} }
const opts = { const opts = {
sort: data[0].sort, sort: data[0].sort,
order: data[0].order, order: data[0].order,
includeFork: data[0].includeFork, includeFork: data[0].includeFork,
types: data[0].types, types: data[0].types,
twitter: data[0].twitter, twitter: data[0].twitter,
linkedin: data[0].linkedin, linkedin: data[0].linkedin,
medium: data[0].medium, medium: data[0].medium,
dribbble: data[0].dribbble dribbble: data[0].dribbble
}; };
updateHTML(username, opts); updateHTML(username, opts);
} }
module.exports = { module.exports = {
updateCommand updateCommand
}; };

View file

@ -1,39 +1,39 @@
const path = require("path"); const path = require("path");
const bluebird = require("bluebird"); const bluebird = require("bluebird");
const fs = bluebird.promisifyAll(require("fs")); const fs = bluebird.promisifyAll(require("fs"));
const outDir = path.resolve("./dist/" || process.env.OUT_DIR); const outDir = path.resolve("./dist/" || process.env.OUT_DIR);
const configPath = path.join(outDir, "config.json"); const configPath = path.join(outDir, "config.json");
const blogPath = path.join(outDir, "blog.json"); const blogPath = path.join(outDir, "blog.json");
const defaultConfigPath = path.resolve(`${__dirname}/default/config.json`); const defaultConfigPath = path.resolve(`${__dirname}/default/config.json`);
const defaultBlogPath = path.resolve(`${__dirname}/default/blog.json`); const defaultBlogPath = path.resolve(`${__dirname}/default/blog.json`);
/** /**
* Tries to read file from out dir, * Tries to read file from out dir,
* if not present returns default file contents * if not present returns default file contents
*/ */
async function getFileWithDefaults(file, defaultFile) { async function getFileWithDefaults(file, defaultFile) {
try { try {
await fs.accessAsync(file, fs.constants.F_OK); await fs.accessAsync(file, fs.constants.F_OK);
} catch (err) { } catch (err) {
const defaultData = await fs.readFileAsync(defaultFile); const defaultData = await fs.readFileAsync(defaultFile);
return JSON.parse(defaultData); return JSON.parse(defaultData);
} }
const data = await fs.readFileAsync(file); const data = await fs.readFileAsync(file);
return JSON.parse(data); return JSON.parse(data);
} }
async function getConfig() { async function getConfig() {
return getFileWithDefaults(configPath, defaultConfigPath); return getFileWithDefaults(configPath, defaultConfigPath);
} }
async function getBlog() { async function getBlog() {
return getFileWithDefaults(blogPath, defaultBlogPath); return getFileWithDefaults(blogPath, defaultBlogPath);
} }
module.exports = { module.exports = {
outDir, outDir,
getConfig, getConfig,
getBlog getBlog
}; };

View file

@ -1,259 +1,259 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Gitfolio UI</title> <title>Gitfolio UI</title>
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css"
/> />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
crossorigin="anonymous" crossorigin="anonymous"
/> />
<link rel="stylesheet" type="text/css" href="./css/index.css" /> <link rel="stylesheet" type="text/css" href="./css/index.css" />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/css/zeva.min.css" href="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/css/zeva.min.css"
/> />
</head> </head>
<body class="body-light"> <body class="body-light">
<header> <header>
<b>gitfolio</b> <b>gitfolio</b>
<a href="/blog" style="float: right">New Blog </a> <a href="/blog" style="float: right">New Blog </a>
<a href="/update" style="float: right">Update</a> <a href="/update" style="float: right">Update</a>
<a href="/" style="float: right">Home</a> <a href="/" style="float: right">Home</a>
</header> </header>
<div id="top_image"> <div id="top_image">
<i class="fas fa-camera" onclick="applyTopImage()"></i> <i class="fas fa-camera" onclick="applyTopImage()"></i>
</div> </div>
<input <input
type="file" type="file"
id="top_image_file" id="top_image_file"
style="display: none" style="display: none"
accept="image/*" accept="image/*"
style="display: none" style="display: none"
/> />
<table id="profile_blog"> <table id="profile_blog">
<tbody> <tbody>
<tr> <tr>
<td style="width:8vw;"> <td style="width:8vw;">
<div <div
id="profile_img_blog" id="profile_img_blog"
style="background:url('<%= profile[0].userimg%>') center center;" style="background:url('<%= profile[0].userimg%>') center center;"
></div> ></div>
</td> </td>
<td style="width:52vw;"> <td style="width:52vw;">
<div id="username_blog"> <div id="username_blog">
<% if(profile[0].name)%> <% if(profile[0].name)%>
<span><%= profile[0].name%></span> <span><%= profile[0].name%></span>
<% %> <% %>
<br />@<%= profile[0].username%><b id="blog_time"></b> <br />@<%= profile[0].username%><b id="blog_time"></b>
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div id="blog-display"> <div id="blog-display">
<form <form
style="padding: 0px; width:100%;" style="padding: 0px; width:100%;"
method="POST" method="POST"
action="/createBlog" action="/createBlog"
id="form" id="form"
> >
<textarea <textarea
id="blog_title" id="blog_title"
placeholder="blog title here" placeholder="blog title here"
spellcheck="false" spellcheck="false"
rows="1" rows="1"
onkeyup="addRow(event)" onkeyup="addRow(event)"
name="title" name="title"
required required
></textarea> ></textarea>
<br /> <br />
<textarea <textarea
id="blog_sub_title" id="blog_sub_title"
placeholder="blog sub title here" placeholder="blog sub title here"
spellcheck="false" spellcheck="false"
rows="1" rows="1"
name="subtitle" name="subtitle"
onkeyup="addRow(event)" onkeyup="addRow(event)"
required required
></textarea> ></textarea>
<div id="originalContent" style="display: none"></div> <div id="originalContent" style="display: none"></div>
<input type="hidden" name="top_image" id="top" /> <input type="hidden" name="top_image" id="top" />
<input type="hidden" name="content" id="content" /> <input type="hidden" name="content" id="content" />
<input type="hidden" name="images" id="images" /> <input type="hidden" name="images" id="images" />
<div id="blog"></div> <div id="blog"></div>
<div class="div_for_buttons"> <div class="div_for_buttons">
<input <input
type="file" type="file"
name="file" name="file"
id="file" id="file"
style="display: none" style="display: none"
accept="image/*" accept="image/*"
/> />
<button <button
class="button h-weight-bold h-border-pill -size-small" class="button h-weight-bold h-border-pill -size-small"
type="button" type="button"
onclick="clickFile()" onclick="clickFile()"
> >
<i class="fas fa-plus"></i>&nbsp; Image <i class="fas fa-plus"></i>&nbsp; Image
</button> </button>
<button <button
class="button h-weight-bold h-border-pill -size-small" class="button h-weight-bold h-border-pill -size-small"
type="button" type="button"
onclick="addPara()" onclick="addPara()"
> >
<i class="fas fa-plus"></i>&nbsp; Paragraph <i class="fas fa-plus"></i>&nbsp; Paragraph
</button> </button>
<h5>Tip : You can use html inside paragraphs</h5> <h5>Tip : You can use html inside paragraphs</h5>
</div> </div>
<button type="button" class="button" onclick="submitthisform()"> <button type="button" class="button" onclick="submitthisform()">
Create Blog Create Blog
</button> </button>
</form> </form>
</div> </div>
<script <script
type="text/javascript" type="text/javascript"
src="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/js/index.min.js" src="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/js/index.min.js"
></script> ></script>
<script type="text/javascript"> <script type="text/javascript">
var imgElement = document.querySelector("#file"); var imgElement = document.querySelector("#file");
var topImageElement = document.querySelector("#top_image_file"); var topImageElement = document.querySelector("#top_image_file");
var img_number = 0; var img_number = 0;
var blog_para_number = 0; var blog_para_number = 0;
var images = []; var images = [];
function applyTopImage() { function applyTopImage() {
topImageElement.value = ""; topImageElement.value = "";
document.querySelector("#top").value = ""; document.querySelector("#top").value = "";
document.querySelector("#top_image").style.background = document.querySelector("#top_image").style.background =
"linear-gradient(0deg, rgb(250, 250, 250), rgb(220, 220, 220))"; "linear-gradient(0deg, rgb(250, 250, 250), rgb(220, 220, 220))";
topImageElement.click(); topImageElement.click();
} }
topImageElement.addEventListener("change", e => { topImageElement.addEventListener("change", e => {
var reader = new FileReader(); var reader = new FileReader();
reader.readAsDataURL(e.target.files[0]); reader.readAsDataURL(e.target.files[0]);
reader.onload = data => { reader.onload = data => {
var image = data.target.result; var image = data.target.result;
document.querySelector( document.querySelector(
"#top_image" "#top_image"
).style.background = `linear-gradient(0deg, rgba(250, 250, 250, 1), rgba(220, 220, 220, 0)), url('${image}') center center`; ).style.background = `linear-gradient(0deg, rgba(250, 250, 250, 1), rgba(220, 220, 220, 0)), url('${image}') center center`;
document.querySelector("#top").value = image; document.querySelector("#top").value = image;
}; };
}); });
function addRow(e) { function addRow(e) {
e.preventDefault(); e.preventDefault();
if (e.target.clientHeight < e.target.scrollHeight) { if (e.target.clientHeight < e.target.scrollHeight) {
e.target.rows += 1; e.target.rows += 1;
} else { } else {
if (e.target.value == "") { if (e.target.value == "") {
e.target.rows = 1; e.target.rows = 1;
} }
} }
} }
function remove(e, element, blobData) { function remove(e, element, blobData) {
var elem = document.getElementById(element); var elem = document.getElementById(element);
var elem2 = document.getElementById(`${element}_original`); var elem2 = document.getElementById(`${element}_original`);
elem.parentNode.removeChild(e.target); elem.parentNode.removeChild(e.target);
elem.parentNode.removeChild(elem); elem.parentNode.removeChild(elem);
elem2.parentNode.removeChild(elem2); elem2.parentNode.removeChild(elem2);
imgElement.value = ""; imgElement.value = "";
if (element.split("_")[0] == "img") { if (element.split("_")[0] == "img") {
images.splice(images.indexOf(blobData), 1); images.splice(images.indexOf(blobData), 1);
img_number--; img_number--;
} }
} }
function addDataToOriginalPara(id) { function addDataToOriginalPara(id) {
document.querySelector( document.querySelector(
`#para_${id}_original` `#para_${id}_original`
).innerHTML = document.querySelector(`#para_${id}`).value; ).innerHTML = document.querySelector(`#para_${id}`).value;
} }
function clickFile() { function clickFile() {
imgElement.click(); imgElement.click();
} }
imgElement.addEventListener("change", e => { imgElement.addEventListener("change", e => {
var img = document.createElement("img"); var img = document.createElement("img");
var imageblob = URL.createObjectURL(e.target.files[0]); var imageblob = URL.createObjectURL(e.target.files[0]);
img.setAttribute( img.setAttribute(
"src", "src",
`img_${img_number}.${e.target.files[0].type.split("/")[1]}` `img_${img_number}.${e.target.files[0].type.split("/")[1]}`
); );
img.setAttribute("alt", `blog image ${img_number}`); img.setAttribute("alt", `blog image ${img_number}`);
img.setAttribute("id", `img_${img_number}_original`); img.setAttribute("id", `img_${img_number}_original`);
var img2 = document.createElement("img"); var img2 = document.createElement("img");
img2.setAttribute("src", imageblob); img2.setAttribute("src", imageblob);
img2.setAttribute("alt", `blog image ${img_number}`); img2.setAttribute("alt", `blog image ${img_number}`);
img2.setAttribute("id", `img_${img_number}`); img2.setAttribute("id", `img_${img_number}`);
var remove = document.createElement("div"); var remove = document.createElement("div");
remove.setAttribute("class", "remove"); remove.setAttribute("class", "remove");
remove.setAttribute( remove.setAttribute(
"onclick", "onclick",
`remove(event,'img_${img_number}', '${imageblob}')` `remove(event,'img_${img_number}', '${imageblob}')`
); );
remove.innerHTML = '<i class="fas fa-times"></i> Remove'; remove.innerHTML = '<i class="fas fa-times"></i> Remove';
document.querySelector("#originalContent").appendChild(img); document.querySelector("#originalContent").appendChild(img);
document.querySelector("#blog").appendChild(img2); document.querySelector("#blog").appendChild(img2);
document.querySelector("#blog").appendChild(remove); document.querySelector("#blog").appendChild(remove);
var reader = new FileReader(); var reader = new FileReader();
reader.readAsDataURL(e.target.files[0]); reader.readAsDataURL(e.target.files[0]);
reader.onload = data => { reader.onload = data => {
images.push(data.target.result); images.push(data.target.result);
}; };
imgElement.value = ""; imgElement.value = "";
img_number++; img_number++;
}); });
function addPara() { function addPara() {
var para = document.createElement("textarea"); var para = document.createElement("textarea");
para.setAttribute("class", "para"); para.setAttribute("class", "para");
para.setAttribute("id", `para_${blog_para_number}`); para.setAttribute("id", `para_${blog_para_number}`);
para.setAttribute("spellcheck", false); para.setAttribute("spellcheck", false);
para.setAttribute("rows", 1); para.setAttribute("rows", 1);
para.setAttribute( para.setAttribute(
"onkeyup", "onkeyup",
`addRow(event), addDataToOriginalPara('${blog_para_number}')` `addRow(event), addDataToOriginalPara('${blog_para_number}')`
); );
para.setAttribute("required", true); para.setAttribute("required", true);
para.setAttribute("placeholder", "What's on your Mind?"); para.setAttribute("placeholder", "What's on your Mind?");
var remove = document.createElement("div"); var remove = document.createElement("div");
remove.setAttribute("class", "remove"); remove.setAttribute("class", "remove");
remove.setAttribute( remove.setAttribute(
"onclick", "onclick",
`remove(event,'para_${blog_para_number}', null)` `remove(event,'para_${blog_para_number}', null)`
); );
remove.innerHTML = '<i class="fas fa-times"></i> Remove'; remove.innerHTML = '<i class="fas fa-times"></i> Remove';
var originalPara = document.createElement("p"); var originalPara = document.createElement("p");
originalPara.setAttribute("id", `para_${blog_para_number}_original`); originalPara.setAttribute("id", `para_${blog_para_number}_original`);
document.querySelector("#blog").appendChild(para); document.querySelector("#blog").appendChild(para);
document.querySelector("#blog").appendChild(remove); document.querySelector("#blog").appendChild(remove);
document.querySelector("#originalContent").appendChild(originalPara); document.querySelector("#originalContent").appendChild(originalPara);
blog_para_number++; blog_para_number++;
} }
function submitthisform() { function submitthisform() {
document.querySelector("#content").value = document.querySelector( document.querySelector("#content").value = document.querySelector(
"#originalContent" "#originalContent"
).innerHTML; ).innerHTML;
document.querySelector("#images").value = JSON.stringify(images); document.querySelector("#images").value = JSON.stringify(images);
document.querySelector("#form").submit(); document.querySelector("#form").submit();
} }
</script> </script>
</body> </body>
</html> </html>

Binary file not shown.

View file

@ -1,299 +1,299 @@
@import url("https://fonts.googleapis.com/css?family=Poppins"); @import url("https://fonts.googleapis.com/css?family=Poppins");
@import url("https://fonts.googleapis.com/css?family=Questrial"); @import url("https://fonts.googleapis.com/css?family=Questrial");
@font-face { @font-face {
font-family: "Circular"; font-family: "Circular";
src: url("./font/Circular.otf"); src: url("./font/Circular.otf");
} }
body { body {
margin: 0%; margin: 0%;
padding: 0%; padding: 0%;
width: 100vw; width: 100vw;
max-width: 100vw; max-width: 100vw;
overflow-x: hidden; overflow-x: hidden;
align-items: center; align-items: center;
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
background: rgb(250, 250, 250) !important; background: rgb(250, 250, 250) !important;
will-change: auto; will-change: auto;
} }
header { header {
width: 90vw; width: 90vw;
padding: 4vh 5vw; padding: 4vh 5vw;
font-weight: bold; font-weight: bold;
background: rgb(255, 255, 255); background: rgb(255, 255, 255);
font-size: 32px; font-size: 32px;
} }
header b { header b {
font-family: "Circular", sans-serif; font-family: "Circular", sans-serif;
} }
header a { header a {
font-size: 16px; font-size: 16px;
margin: 1.8vh 0px; margin: 1.8vh 0px;
margin-left: 4vw; margin-left: 4vw;
color: #000; color: #000;
text-decoration: none; text-decoration: none;
transition: 0.4s ease-in-out; transition: 0.4s ease-in-out;
} }
header a:hover { header a:hover {
color: #bebebe; color: #bebebe;
} }
form { form {
width: 90vw; width: 90vw;
padding: 2vh 5vw; padding: 2vh 5vw;
} }
form .button { form .button {
margin: 2vh 0px; margin: 2vh 0px;
} }
.input { .input {
margin: 1.5vh 0px !important; margin: 1.5vh 0px !important;
} }
.label { .label {
display: inline-block !important; display: inline-block !important;
margin-right: 25px; margin-right: 25px;
font-weight: bold; font-weight: bold;
} }
button { button {
transition: 0.4s ease-in-out !important; transition: 0.4s ease-in-out !important;
} }
button:hover { button:hover {
color: #fff; color: #fff;
background: #000 !important; background: #000 !important;
} }
.-size-small { .-size-small {
margin-right: 1vw !important; margin-right: 1vw !important;
} }
#top_image { #top_image {
width: 100vw; width: 100vw;
height: 50vh; height: 50vh;
position: absolute; position: absolute;
top: 14vh; top: 14vh;
left: 0; left: 0;
background: linear-gradient(0deg, rgb(250, 250, 250), rgb(200, 200, 200)); background: linear-gradient(0deg, rgb(250, 250, 250), rgb(200, 200, 200));
background-size: cover !important; background-size: cover !important;
background-repeat: no-repeat !important; background-repeat: no-repeat !important;
z-index: 1; z-index: 1;
text-align: right; text-align: right;
} }
#top_image i { #top_image i {
font-size: 20px; font-size: 20px;
position: absolute; position: absolute;
z-index: 5; z-index: 5;
top: 4vh; top: 4vh;
right: 5vw; right: 5vw;
padding: 15px 15px; padding: 15px 15px;
background: #ffffff; background: #ffffff;
color: rgb(0, 0, 0); color: rgb(0, 0, 0);
border-radius: 50%; border-radius: 50%;
} }
#top_image i:hover { #top_image i:hover {
cursor: pointer; cursor: pointer;
} }
#profile_blog { #profile_blog {
width: 60vw; width: 60vw;
margin: 0px 20vw; margin: 0px 20vw;
margin-top: 42vh !important; margin-top: 42vh !important;
text-align: left; text-align: left;
z-index: 1; z-index: 1;
transition: 0.4s ease-in-out; transition: 0.4s ease-in-out;
z-index: 2; z-index: 2;
position: relative; position: relative;
} }
#profile_img_blog { #profile_img_blog {
border-radius: 50%; border-radius: 50%;
width: 90px; width: 90px;
height: 90px; height: 90px;
background-size: cover !important; background-size: cover !important;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
#username_blog { #username_blog {
font-size: 18px; font-size: 18px;
color: #000; color: #000;
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
font-weight: bold; font-weight: bold;
padding-left: 0px; padding-left: 0px;
} }
#username_blog span { #username_blog span {
font-size: 24px; font-size: 24px;
font-family: "Questrial", sans-serif !important; font-family: "Questrial", sans-serif !important;
} }
#username_blog b { #username_blog b {
font-size: 12px; font-size: 12px;
font-family: "Poppins", sans-serif; font-family: "Poppins", sans-serif;
font-weight: bold; font-weight: bold;
} }
#blog-display { #blog-display {
width: 60vw; width: 60vw;
margin: 3vh 20vw; margin: 3vh 20vw;
text-align: left; text-align: left;
z-index: 1; z-index: 1;
transition: 0.4s ease-in-out; transition: 0.4s ease-in-out;
z-index: 2; z-index: 2;
position: relative; position: relative;
} }
#blog_title { #blog_title {
font-size: 50px; font-size: 50px;
color: #000; color: #000;
font-weight: bold; font-weight: bold;
font-family: "Questrial", sans-serif; font-family: "Questrial", sans-serif;
background: transparent; background: transparent;
border: 0px; border: 0px;
width: 100%; width: 100%;
resize: none; resize: none;
height: auto; height: auto;
overflow-y: hidden; overflow-y: hidden;
} }
#blog_sub_title { #blog_sub_title {
font-size: 36px; font-size: 36px;
color: rgb(100, 100, 100); color: rgb(100, 100, 100);
font-weight: bold; font-weight: bold;
font-family: "Questrial", sans-serif; font-family: "Questrial", sans-serif;
background: transparent; background: transparent;
border: 0px; border: 0px;
width: 100%; width: 100%;
resize: none; resize: none;
height: auto; height: auto;
overflow-y: hidden; overflow-y: hidden;
} }
#blog_sub_title::placeholder { #blog_sub_title::placeholder {
color: rgb(100, 100, 100); color: rgb(100, 100, 100);
} }
#blog-display h2 { #blog-display h2 {
color: var(--blog-gray-color); color: var(--blog-gray-color);
} }
#blog-display { #blog-display {
padding: 1vh 0px; padding: 1vh 0px;
font-family: "Questrial", sans-serif; font-family: "Questrial", sans-serif;
} }
.div_for_buttons { .div_for_buttons {
margin-top: 5vh; margin-top: 5vh;
} }
.para { .para {
font-size: 17px; font-size: 17px;
line-height: 25px; line-height: 25px;
word-spacing: 1.2px; word-spacing: 1.2px;
margin: 5vh 0px; margin: 5vh 0px;
background: transparent; background: transparent;
border: 0px; border: 0px;
width: 100%; width: 100%;
font-family: "Questrial", sans-serif; font-family: "Questrial", sans-serif;
resize: none; resize: none;
height: auto; height: auto;
overflow-y: hidden; overflow-y: hidden;
} }
.para span { .para span {
padding: 2px 4px; padding: 2px 4px;
background: #000; background: #000;
color: #fff !important; color: #fff !important;
} }
#blog { #blog {
margin-top: 2vh; margin-top: 2vh;
} }
#blog img { #blog img {
width: 100%; width: 100%;
margin: 2vh 0px; margin: 2vh 0px;
border-radius: 5px; border-radius: 5px;
border: 1px solid rgb(0, 0, 0, 0.08); border: 1px solid rgb(0, 0, 0, 0.08);
} }
.remove { .remove {
margin-bottom: 2vh 0px; margin-bottom: 2vh 0px;
font-weight: bold; font-weight: bold;
transition: 0.4s ease-in-out; transition: 0.4s ease-in-out;
font-size: 16px; font-size: 16px;
} }
.remove i { .remove i {
font-size: 14px; font-size: 14px;
margin-right: 3px; margin-right: 3px;
} }
.remove:hover { .remove:hover {
cursor: pointer; cursor: pointer;
color: rgb(255, 70, 70); color: rgb(255, 70, 70);
} }
@media (max-width: 800px) { @media (max-width: 800px) {
#blog-display { #blog-display {
width: 90vw; width: 90vw;
margin: 0px 5vw; margin: 0px 5vw;
text-align: left; text-align: left;
margin-top: 0vh; margin-top: 0vh;
z-index: 1; z-index: 1;
} }
#profile_blog { #profile_blog {
width: 90vw; width: 90vw;
margin: 0px 5vw; margin: 0px 5vw;
} }
#profile_img_blog { #profile_img_blog {
width: 70px; width: 70px;
height: 70px; height: 70px;
} }
#blog img { #blog img {
margin: 1vh 0px !important; margin: 1vh 0px !important;
} }
#blog p { #blog p {
margin: 2vh 0px; margin: 2vh 0px;
} }
} }
::selection { ::selection {
color: #fff; color: #fff;
background: #000; background: #000;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 5px; width: 5px;
height: 5px; height: 5px;
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
background: #fff; background: #fff;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: #000; background: #000;
} }
input, input,
textarea:focus { textarea:focus {
outline: none; outline: none;
} }
::placeholder { ::placeholder {
color: #000; color: #000;
} }

View file

@ -1,153 +1,153 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Gitfolio UI</title> <title>Gitfolio UI</title>
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css"
/> />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
crossorigin="anonymous" crossorigin="anonymous"
/> />
<link rel="stylesheet" type="text/css" href="./css/index.css" /> <link rel="stylesheet" type="text/css" href="./css/index.css" />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/css/zeva.min.css" href="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/css/zeva.min.css"
/> />
</head> </head>
<body class="body-light"> <body class="body-light">
<header> <header>
<b>gitfolio</b> <b>gitfolio</b>
<a href="/blog" style="float: right">New Blog </a> <a href="/blog" style="float: right">New Blog </a>
<a href="/update" style="float: right">Update</a> <a href="/update" style="float: right">Update</a>
<a href="/" style="float: right">Home</a> <a href="/" style="float: right">Home</a>
</header> </header>
<form method="post" action="build"> <form method="post" action="build">
<h3>Build or Edit Portfolio</h3> <h3>Build or Edit Portfolio</h3>
<input <input
type="text" type="text"
class="input h-weight-bold" class="input h-weight-bold"
placeholder="username" placeholder="username"
id="username" id="username"
name="username" name="username"
required required
/><br /> /><br />
<input <input
type="text" type="text"
class="input h-weight-bold" class="input h-weight-bold"
placeholder="background" placeholder="background"
name="background" name="background"
id="background" id="background"
/> />
<h3>Sort By :</h3> <h3>Sort By :</h3>
<label class="label" <label class="label"
>Star >Star
<input type="radio" name="sort" value="star" /> <input type="radio" name="sort" value="star" />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<label class="label" <label class="label"
>Created >Created
<input type="radio" name="sort" value="created" checked /> <input type="radio" name="sort" value="created" checked />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<label class="label" <label class="label"
>Updated >Updated
<input type="radio" name="sort" value="updated" /> <input type="radio" name="sort" value="updated" />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<label class="label" <label class="label"
>Pushed >Pushed
<input type="radio" name="sort" value="pushed" /> <input type="radio" name="sort" value="pushed" />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<label class="label" <label class="label"
>Full Name >Full Name
<input type="radio" name="sort" value="full_name" /> <input type="radio" name="sort" value="full_name" />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<h3>Order By :</h3> <h3>Order By :</h3>
<label class="label" <label class="label"
>Asc >Asc
<input type="radio" name="order" value="asc" checked /> <input type="radio" name="order" value="asc" checked />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<label class="label" <label class="label"
>Desc >Desc
<input type="radio" name="order" value="desc" /> <input type="radio" name="order" value="desc" />
<span class="radio"></span> <span class="radio"></span>
</label> </label>
<br /><br /> <br /><br />
<label class="label" <label class="label"
>Use Dark Theme >Use Dark Theme
<input type="checkbox" id="theme" name="theme" /> <input type="checkbox" id="theme" name="theme" />
<span class="checkbox"></span> <span class="checkbox"></span>
</label> </label>
<label class="label" <label class="label"
>Include Forks >Include Forks
<input type="checkbox" id="fork" name="fork" value="true" /> <input type="checkbox" id="fork" name="fork" value="true" />
<span class="checkbox"></span> <span class="checkbox"></span>
</label> </label>
<label class="label" <label class="label"
>Include Socials >Include Socials
<input type="checkbox" id="socials" name="socials" /> <input type="checkbox" id="socials" name="socials" />
<span class="checkbox"></span> <span class="checkbox"></span>
</label> </label>
<div style="display: none" id="input_for_socials"> <div style="display: none" id="input_for_socials">
<input <input
type="text" type="text"
class="input h-weight-bold" class="input h-weight-bold"
placeholder="twitter username" placeholder="twitter username"
id="twitter" id="twitter"
name="twitter" name="twitter"
/><br /> /><br />
<input <input
type="text" type="text"
class="input h-weight-bold" class="input h-weight-bold"
placeholder="medium username" placeholder="medium username"
id="medium" id="medium"
name="medium" name="medium"
/><br /> /><br />
<input <input
type="text" type="text"
class="input h-weight-bold" class="input h-weight-bold"
placeholder="dribbble username" placeholder="dribbble username"
id="dribbble" id="dribbble"
name="dribbble" name="dribbble"
/><br /> /><br />
<input <input
type="text" type="text"
class="input h-weight-bold" class="input h-weight-bold"
placeholder="linkedin username" placeholder="linkedin username"
id="linkedin" id="linkedin"
name="linkedin" name="linkedin"
/> />
</div> </div>
<br /><br /> <br /><br />
<button type="submit" class="button" id="build">Build</button> <button type="submit" class="button" id="build">Build</button>
</form> </form>
<script <script
type="text/javascript" type="text/javascript"
src="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/js/index.min.js" src="https://cdn.jsdelivr.net/gh/zeva-ui/zeva/dist/js/index.min.js"
></script> ></script>
<script type="text/javascript"> <script type="text/javascript">
document.querySelector("#socials").addEventListener("change", event => { document.querySelector("#socials").addEventListener("change", event => {
if (event.target.checked) { if (event.target.checked) {
document.querySelector("#input_for_socials").style.display = "block"; document.querySelector("#input_for_socials").style.display = "block";
} else { } else {
document.querySelector("#input_for_socials").style.display = "none"; document.querySelector("#input_for_socials").style.display = "none";
} }
}); });
</script> </script>
</body> </body>
</html> </html>