├── .gitignore
├── .prettierrc
├── README.md
├── babel.config.js
├── package.json
├── public
├── _redirects
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ ├── images
│ │ ├── 404.svg
│ │ ├── av.png
│ │ ├── github.svg
│ │ ├── sspai.svg
│ │ └── zeit.svg
│ ├── logos
│ │ ├── github.png
│ │ ├── jike.png
│ │ ├── medium.png
│ │ ├── rss.png
│ │ ├── sspai.png
│ │ ├── steam.png
│ │ ├── telegram.png
│ │ ├── twitter.png
│ │ ├── weibo.png
│ │ └── zhihu.png
│ └── styles
│ │ ├── base.css
│ │ └── nprogress.css
├── components
│ ├── GitHubCard.vue
│ └── StatCard.vue
├── main.js
└── views
│ ├── Home.vue
│ ├── NotFound.vue
│ ├── Projects.vue
│ └── Social.vue
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": false,
4 | "trailingComma": "all",
5 | "tabWidth": 2,
6 | "printWidth": 120
7 | }
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://vercel.com/spencerwoo/home)
2 | [](https://spencerwoo.com)
3 |
4 | # Portfolio
5 |
6 | > 🍌 My personal home page, built and designed from scratch.
7 |
8 | Current master branch holds `v2.0` of my portfolio. For `v1.0`, please refer to branch [tree/v1.0](https://github.com/spencerwooo/portfolio/tree/v1.0). **Please note that this is my personal portfolio, so I won't be accepting any feature requests.** Feel free to implement features on your own. 💜
9 |
10 |
11 |
12 | ## One-click deployment
13 |
14 | Deploy your own instance of my portfolio to Vercel:
15 |
16 | [](https://vercel.com/import/project?template=spencerwooo%2Fportfolio)
17 |
18 | ## Copyrights
19 |
20 | Please add proper acknowledgements if you were to deploy this for your own portfolio.
21 |
22 | 如果你希望用我的模板部署自己的 Portfolio,还请加上设计来源。比如:
23 |
24 | [](https://github.com/spencerwooo/portfolio)
25 |
26 | ```html
27 |
28 | ```
29 |
30 | ## Project setup
31 |
32 | ```
33 | yarn install
34 | ```
35 |
36 | ### Compiles and hot-reloads for development
37 |
38 | ```
39 | yarn run serve
40 | ```
41 |
42 | ### Compiles and minifies for production
43 |
44 | ```
45 | yarn run build
46 | ```
47 |
48 | ### Run your tests
49 |
50 | ```
51 | yarn run test
52 | ```
53 |
54 | ### Lints and fixes files
55 |
56 | ```
57 | yarn run lint
58 | ```
59 |
60 | ---
61 |
62 | **🍌 Portfolio** ©Spencer Woo. Released under the [MIT License](./LICENSE).
63 |
64 | Authored and maintained by Spencer Woo.
65 |
66 | [@Portfolio](https://spencerwoo.com) · [@GitHub](https://github.com/spencerwooo) · [@BIT](http://www.bit.edu.cn/)
67 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "portfolio",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "lint-fix": "npx eslint --fix --ext .js --ext .jsx --ext .vue src/"
10 | },
11 | "dependencies": {
12 | "axios": "^0.21.1",
13 | "core-js": "^2.6.5",
14 | "nprogress": "^0.2.0",
15 | "vue": "^2.6.10",
16 | "vue-content-loader": "^0.2.3",
17 | "vue-navigation-bar": "^2.0.0",
18 | "vue-router": "^3.1.3"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^3.9.0",
22 | "@vue/cli-plugin-eslint": "^3.9.0",
23 | "@vue/cli-service": "^3.9.0",
24 | "babel-eslint": "^10.0.1",
25 | "eslint": "^5.16.0",
26 | "eslint-plugin-vue": "^5.0.0",
27 | "vue-template-compiler": "^2.6.10"
28 | },
29 | "eslintConfig": {
30 | "root": true,
31 | "env": {
32 | "node": true
33 | },
34 | "extends": [
35 | "plugin:vue/essential",
36 | "eslint:recommended"
37 | ],
38 | "rules": {},
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | }
42 | },
43 | "postcss": {
44 | "plugins": {
45 | "autoprefixer": {}
46 | }
47 | },
48 | "browserslist": [
49 | "> 1%",
50 | "last 2 versions"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | # Make vue router compatible with Netlify
2 | /* /index.html 200
3 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Spencer Woo
9 |
10 |
11 |
12 | We're sorry but portfolio doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
28 |
29 |
30 |
31 |
71 |
72 |
149 |
--------------------------------------------------------------------------------
/src/assets/images/404.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/assets/images/av.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/images/av.png
--------------------------------------------------------------------------------
/src/assets/images/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/sspai.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/images/zeit.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/logos/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/github.png
--------------------------------------------------------------------------------
/src/assets/logos/jike.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/jike.png
--------------------------------------------------------------------------------
/src/assets/logos/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/medium.png
--------------------------------------------------------------------------------
/src/assets/logos/rss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/rss.png
--------------------------------------------------------------------------------
/src/assets/logos/sspai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/sspai.png
--------------------------------------------------------------------------------
/src/assets/logos/steam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/steam.png
--------------------------------------------------------------------------------
/src/assets/logos/telegram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/telegram.png
--------------------------------------------------------------------------------
/src/assets/logos/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/twitter.png
--------------------------------------------------------------------------------
/src/assets/logos/weibo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/weibo.png
--------------------------------------------------------------------------------
/src/assets/logos/zhihu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/zhihu.png
--------------------------------------------------------------------------------
/src/assets/styles/base.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;1,700&family=Open+Sans:wght@700&display=swap');
2 |
3 | :root {
4 | --title-font-family: open sans, -apple-system, BlinkMacSystemFont, segoe ui, helvetica, arial, pingfang sc,
5 | source han sans sc, noto sans cjk sc, sarasa gothic sc, microsoft yahei, sans-serif, apple color emoji,
6 | segoe ui emoji;
7 | --main-font-family: lato, -apple-system, BlinkMacSystemFont, segoe ui, helvetica, arial, pingfang sc,
8 | source han sans sc, noto sans cjk sc, sarasa gothic sc, microsoft yahei, sans-serif, apple color emoji,
9 | segoe ui emoji;
10 | --monospace-font-family: sfmono-regular, consolas, liberation mono, menlo, monospace;
11 |
12 | --background-color: #fafafa;
13 | --text-color: #000000;
14 | --footer-color: #666666;
15 | --link-color: #0070f3;
16 | --code-color: #bd10e0;
17 | }
18 |
19 | html,
20 | body {
21 | margin: 0;
22 | padding: 0;
23 | background-color: var(--background-color);
24 | font-family: var(--main-font-family);
25 | -webkit-font-smoothing: antialiased;
26 | -moz-osx-font-smoothing: grayscale;
27 | color: var(--text-color);
28 | }
29 |
30 | h1 {
31 | font-size: 28px;
32 | }
33 |
34 | h1,
35 | h2,
36 | h3 {
37 | font-family: var(--title-font-family);
38 | font-weight: 700;
39 | }
40 |
41 | h2 {
42 | font-size: 20px;
43 | padding: 16px 0 4px 0;
44 | }
45 |
46 | h1,
47 | h2,
48 | h3,
49 | h4,
50 | p,
51 | span,
52 | li,
53 | ul {
54 | color: var(--text-color);
55 | }
56 |
57 | a {
58 | text-decoration: none;
59 | color: var(--link-color);
60 | }
61 |
62 | a:hover {
63 | border-bottom: none;
64 | }
65 |
66 | ul {
67 | padding-left: 15px;
68 | line-height: 30px;
69 | margin: 0;
70 | }
71 |
72 | p {
73 | line-height: 30px;
74 | }
75 |
76 | code {
77 | padding: 0.2em 0.4em;
78 | margin: 0;
79 | font-size: 85%;
80 | border-radius: 6px;
81 | color: var(--code-color);
82 | }
83 |
84 | code::before,
85 | code::after {
86 | content: '`';
87 | }
88 |
89 | pre {
90 | padding: 16px;
91 | overflow: auto;
92 | font-size: 85%;
93 | line-height: 1.45;
94 | border-radius: 6px;
95 | word-break: normal;
96 | word-wrap: normal;
97 | border: 1px solid #eaeaea;
98 | margin: 24px 0;
99 | white-space: pre;
100 | -webkit-overflow-scrolling: touch;
101 | }
102 |
103 | code,
104 | pre {
105 | font-family: var(--monospace-font-family);
106 | }
107 |
108 | b {
109 | font-weight: 700;
110 | }
111 |
--------------------------------------------------------------------------------
/src/assets/styles/nprogress.css:
--------------------------------------------------------------------------------
1 | /* Make clicks pass-through */
2 | #nprogress {
3 | pointer-events: none;
4 | }
5 |
6 | #nprogress .bar {
7 | background: #000000;
8 |
9 | position: fixed;
10 | z-index: 1031;
11 | top: 0;
12 | left: 0;
13 |
14 | width: 100%;
15 | height: 2px;
16 | }
17 |
18 | /* Fancy blur effect */
19 | #nprogress .peg {
20 | display: block;
21 | position: absolute;
22 | right: 0px;
23 | width: 100px;
24 | height: 100%;
25 | box-shadow: 0 0 10px #000000, 0 0 5px #000000;
26 | opacity: 1;
27 |
28 | -webkit-transform: rotate(3deg) translate(0px, -4px);
29 | -ms-transform: rotate(3deg) translate(0px, -4px);
30 | transform: rotate(3deg) translate(0px, -4px);
31 | }
32 |
33 | .nprogress-custom-parent {
34 | overflow: hidden;
35 | position: relative;
36 | }
37 |
38 | .nprogress-custom-parent #nprogress .bar {
39 | position: absolute;
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/GitHubCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
49 |
50 |
51 |
52 |
53 |
54 |
73 |
74 |
146 |
--------------------------------------------------------------------------------
/src/components/StatCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{ followers }} {{ suffix }}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
37 |
38 |
110 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import VueRouter from 'vue-router'
4 |
5 | import Home from './views/Home.vue'
6 | import Projects from './views/Projects.vue'
7 | import Social from './views/Social.vue'
8 | import NotFound from './views/NotFound.vue'
9 |
10 | import './assets/styles/base.css'
11 |
12 | Vue.config.productionTip = false
13 | Vue.use(VueRouter)
14 |
15 | import VueNavigationBar from 'vue-navigation-bar'
16 | Vue.component('vue-navigation-bar', VueNavigationBar)
17 |
18 | import axios from 'axios'
19 | Vue.prototype.axios = axios
20 |
21 | // NProgress
22 | import NProgress from 'nprogress'
23 | import './assets/styles/nprogress.css'
24 | NProgress.configure({ easing: 'ease', speed: 500, showSpinner: false })
25 |
26 | const router = new VueRouter({
27 | mode: 'history',
28 | base: process.env.BASE_URL,
29 | routes: [
30 | { path: '/', component: Home },
31 | { path: '/projects', component: Projects },
32 | { path: '/social', component: Social },
33 |
34 | // Not found
35 | { path: '/*', component: NotFound }
36 | ]
37 | })
38 |
39 | router.beforeEach((to, from, next) => {
40 | if (from.name !== null) {
41 | NProgress.start()
42 | }
43 | next()
44 | })
45 | // eslint-disable-next-line no-unused-vars
46 | router.afterEach((to, from) => {
47 | NProgress.done()
48 | })
49 |
50 | new Vue({
51 | router,
52 | render: h => h(App)
53 | }).$mount('#app')
54 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Spencer Woo
6 |
7 |
20 |
21 |
WHO AM I
22 |
23 | I'm Spencer Woo with the ID spencerwoo . Some other variations:
24 | @realSpencerWoo /
25 | @SpencerWoo /
26 | @spencerwooo . You may
27 | know me from GitHub / Jike / SSPAI or other places. Yes, those are also me.
28 |
29 |
30 |
Academics
31 |
52 |
53 |
Devices
54 |
55 | ⚫ ThinkPad X1 Carbon 7th Gen
56 | 🔵 iPhone 12 / iPad Air 3 / AirPods Pro
57 |
58 |
59 |
How can we trust you!
60 |
61 | I have verified my identity with a GPG signature which proves my ownership of this domain. (See the cryptography
62 | proof here:
63 | Keybase - claimed ownership of spencerwoo.com via dns .) In other words, I AM LEGIT HERE.
69 |
70 |
71 | I have my GPG public key hosted on
72 | Keybase - spencerwoo . You
73 | can pull and import my GPG public key with:
74 |
75 |
curl https://keybase.io/spencerwoo/pgp_keys.asc | gpg --import
76 |
77 |
Contacts
78 |
84 |
85 |
86 |
87 |
88 |
141 |
--------------------------------------------------------------------------------
/src/views/NotFound.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
404
4 |
Oh, no. Not here.
5 |
6 |
7 | ← Back home.
8 |
9 |
10 |
11 |
12 |
27 |
--------------------------------------------------------------------------------
/src/views/Projects.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Projects
4 |
Projects I participated in and/or developed.
5 |
6 |
12 |
13 | WSL development best practices. Available at:
14 | Dev on Windows with WSL .
15 |
16 |
17 |
18 |
24 |
25 | Serverless function to count how many people are subscribed to you in your favorite services. Supporting Feedly,
26 | Inoreader, GitHub, Twitter, Jike, Zhihu, and much more.
27 |
28 |
29 |
30 |
31 |
32 | LaTeX templates for your bachelor graduation thesis (and more) here at BIT.
33 |
34 |
35 |
36 |
42 |
43 | The Fully Anonymous Teaching Evaluation System: a project that won National 2nd Prize on the
44 | National College Student Information Security Contest , based on OPAAK and CL
45 | signatures. More on:
46 | Medium - Recap on project FATES.
47 |
48 |
49 |
50 |
56 | I freaking can't believe it that this is my most starred project...
57 |
58 |
59 |
60 |
61 |
122 |
123 |
128 |
--------------------------------------------------------------------------------
/src/views/Social.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Social
4 |
Some of my followers.
5 |
6 |
7 |
8 |
16 |
24 |
25 |
26 |
34 |
42 |
43 |
44 |
52 |
60 |
61 |
62 |
70 |
78 |
79 |
80 |
88 |
96 |
97 |
98 |
99 |
103 |
104 |
105 |
106 |
175 |
176 |
225 |
--------------------------------------------------------------------------------