Initial Commit

This commit is contained in:
Moe Poi ~ 2024-03-26 21:52:13 +07:00
commit 14df101340
Signed by: moepoi
GPG key ID: EADBACA726DD4853
43 changed files with 3438 additions and 0 deletions

24
.gitignore vendored Normal file
View file

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Moe Poi ~
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

17
README.md Normal file
View file

@ -0,0 +1,17 @@
# 💩**MOEPOI.DEV**
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/25db2e9192d54ce99f7a151230e6f0a8)](https://www.codacy.com/gh/moepoi/moepoi.dev/dashboard?utm_source=github.com&utm_medium=referral&utm_content=moepoi/moepoi.dev&utm_campaign=Badge_Grade)
[![CodeFactor](https://www.codefactor.io/repository/github/moepoi/moepoi.dev/badge)](https://www.codefactor.io/repository/github/moepoi/moepoi.dev)
## Build Setup
```bash
# install dependencies
$ npm install
# serve with hot reload
$ npm run dev
# build for production
$ npm run build
```

25
index.html Normal file
View file

@ -0,0 +1,25 @@
<!doctype html>
<!--
__ _______ __________ ____ ____
/ |/ / __ \/ ____/ __ \/ __ \/ _/
/ /|_/ / / / / __/ / /_/ / / / // /
/ / / / /_/ / /___/ ____/ /_/ // /
/_/ /_/\____/_____/_/ \____/___/
-->
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/assets/images/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Moe Poi ~</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.2.0/remixicon.min.css">
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

2885
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

27
package.json Normal file
View file

@ -0,0 +1,27 @@
{
"name": "personal_site",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"@tsconfig/svelte": "^5.0.2",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"svelte": "^4.2.12",
"svelte-check": "^3.6.7",
"svelte-routing": "^2.12.0",
"tailwindcss": "^3.4.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2",
"vite": "^5.2.0"
},
"dependencies": {
}
}

7
postcss.config.js Normal file
View file

@ -0,0 +1,7 @@
import tailwind from 'tailwindcss'
import tailwindConfig from './tailwind.config.js'
import autoprefixer from 'autoprefixer'
export default {
plugins: [tailwind(tailwindConfig),autoprefixer]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

20
src/App.svelte Normal file
View file

@ -0,0 +1,20 @@
<script lang="ts">
import { Router, Route } from 'svelte-routing';
import Home from './routes/Home.svelte';
import Contact from './routes/Contact.svelte';
import Projects from './routes/Projects.svelte';
import Resume from './routes/Resume.svelte';
import NotFound from './routes/NotFound.svelte';
</script>
<main>
<Router>
<Route path="/" component={Home} />
<Route path="/projects" component={Projects} />
<Route path="/resume" component={Resume} />
<Route path="/contact" component={Contact} />
<Route component={NotFound} />
</Router>
</main>

18
src/app.css Normal file
View file

@ -0,0 +1,18 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
::-webkit-scrollbar {
display: none;
}
html {
scrollbar-width: none;
-ms-overflow-style: none;
}
body {
background-color: #020617;
min-height: 100vh;
}

BIN
src/lib/assets/hidden.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/lib/assets/profile.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

View file

@ -0,0 +1,12 @@
<script lang="ts">
import { Link } from 'svelte-routing';
export let isFixed: boolean = false;
</script>
<nav class="{isFixed ? 'fixed' : ''} top-0 left-0 w-full z-50 flex justify-center space-x-4 p-4">
<Link to="/" class='text-white hover:underline'>Home</Link>
<Link to="/projects" class='text-white hover:underline'>Projects</Link>
<Link to="/resume" class='text-white hover:underline'>Resume</Link>
<Link to="/contact" class='text-white hover:underline'>Contact</Link>
</nav>

View file

@ -0,0 +1,14 @@
<div class="mt-5 flex">
<a class="mx-2" href="https://t.me/moepoi" target="_blank">
<i class="ri-telegram-fill text-white text-2xl"></i>
</a>
<a class="mx-2" href="https://moe.onl/@moepoi" target="_blank">
<i class="ri-mastodon-fill text-white text-2xl"></i>
</a>
<a class="mx-2" href="https://github.com/moepoi" target="_blank">
<i class="ri-github-fill text-white text-2xl"></i>
</a>
<a class="mx-2" href="https://linkedin.com/in/moepoi" target="_blank">
<i class="ri-linkedin-box-fill text-white text-2xl"></i>
</a>
</div>

29
src/lib/data/contact.ts Normal file
View file

@ -0,0 +1,29 @@
export let emailAddress: string = 'moe@poi.lol';
export let publicKey: string = `-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZa+LhhYJKwYBBAHaRw8BAQdAoBI6qbxs0VSL2hgo6+3CfSfBJYXeQgOhMv9h
4+KRcSS0Jk1pY2hhZWwgV2lsbGlhbSBKb25hdGhhbiA8bW9lQHBvaS5sb2w+iJYE
ExYKAD4CGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AWIQTBSYGzQ7w/QzuN
8ZHq26ynJt1IUwUCZe9a2AIZAQAKCRDq26ynJt1IU6TCAQCnFrCPEkRC/erGUAHg
0JBd7txDfYqUSBydAjaOaG+IpAD+MblKuqDiRdLunX5WMmGscRJXv0nnyBboXO8n
W4K34wu0Kk1pY2hhZWwgV2lsbGlhbSBKb25hdGhhbiA8bW9lQGdudXdlZWIub3Jn
PoiTBBMWCgA7FiEEwUmBs0O8P0M7jfGR6tuspybdSFMFAmXvWoACGwMFCwkIBwIC
IgIGFQoJCAsCBBYCAwECHgcCF4AACgkQ6tuspybdSFNhgQD/axS57Je10LCiu167
BGbvBYaFCzfgQu5xMeTAcO6+fOsA/0PlN7t3GcgxD4WUCqwlieAK+d7xhjIMKTgp
iLyw374AtCpNaWNoYWVsIFdpbGxpYW0gSm9uYXRoYW4gPG1vZUBjaG9jb2xhLmRl
dj6IkwQTFgoAOxYhBMFJgbNDvD9DO43xkerbrKcm3UhTBQJl71q1AhsDBQsJCAcC
AiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEOrbrKcm3UhTSR4A/Rya61/mzqQUHoWw
rUq6S4JArUyaYDga8IhvosFjKp2YAP4izyhSCiMxesayDNGqiUkDF3HTy3MuGl9V
90vXPj8aCrQwTWljaGFlbCBXaWxsaWFtIEpvbmF0aGFuIDxtb2Vwb2lAcHJvdG9u
bWFpbC5jb20+iJMEExYKADsWIQTBSYGzQ7w/QzuN8ZHq26ynJt1IUwUCZe9axwIb
AwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRDq26ynJt1IU5K2AQDK34r+
TvgOtjYhrjpen67wz5R99O5prSHrUqISrcHkWgD+Km5i2fvOsAueOhOYcTasu25j
NdSs8VPo6ElOU/b8SAW4OARlr4uGEgorBgEEAZdVAQUBAQdAdUJn/xYrkbPZ4ED9
MRcPCeh1Of+QICv1c9/wSq1S6DsDAQgHiHgEGBYKACAWIQTBSYGzQ7w/QzuN8ZHq
26ynJt1IUwUCZa+LhgIbDAAKCRDq26ynJt1IU8aBAQD5y30FC/BtCwlvpDGSR2c7
3uJpJVWej4eM1P1nr5RxCQD+NENMiiSqHPA/5INBXaI3ZBWDJXSAOnopwne4rL98
OAo=
=ti9G
-----END PGP PUBLIC KEY BLOCK-----
`;

87
src/lib/data/projects.ts Normal file
View file

@ -0,0 +1,87 @@
export interface Project {
title: string;
image: string;
date: string;
categories: string;
description: string;
url: string;
}
export const projects: Project[] = [
{
title: 'Nepgear Bot',
image: 'assets/images/projects/nepgear.webp',
date: '23 November 2018',
categories: 'Bot',
description:
'Telegram bot that allows you to search for your favorite Anime, Manga, Character with other useful features !!!',
url: 'https://t.me/NepgearBot'
},
{
title: 'Whois Bot',
image: 'assets/images/projects/whois.webp',
date: ' 3 September 2019',
categories: 'Bot',
description:
'Telegram bot that provide Information about domain, ip, and web hosting.',
url: 'https://t.me/WhoisBot'
},
{
title: 'Moe API',
image: 'assets/images/projects/moe-api.webp',
date: '8 November 2019',
categories: 'Web',
description: 'Powerful API with modern features !!!',
url: 'https://moe.team/'
},
{
title: 'Toaru Stickers',
image: 'assets/images/projects/toaru-stickers.webp',
date: '13 May 2020',
categories: 'App',
description:
'Toaru Stickers Application for Whatsapp. Build with Flutter :)',
url: 'https://github.com/moepoi/Toaru-Stickers'
},
{
title: 'Neonime App',
image: 'assets/images/projects/neonime-app.webp',
date: '5 August 2020',
categories: 'App',
description:
'App for streaming & download anime (Indo sub). Build with Flutter :)',
url: 'https://github.com/moepoi/Neonime-App'
},
{
title: 'Easy Learn',
image: 'assets/images/projects/easy-learn.webp',
date: '15 August 2021',
categories: 'App',
description: 'Learning app for kids.',
url: 'https://github.com/Easy-Learn/App'
},
{
title: 'Nekoya Web',
image: 'assets/images/projects/nekoya-web.webp',
date: '22 November 2021',
categories: 'Web',
description: 'Web application for Nekoya ~',
url: 'https://github.com/Nekoya-Site/Web'
},
{
title: 'Nekoya App',
image: 'assets/images/projects/nekoya-app.webp',
date: '30 May 2022',
categories: 'App',
description: 'Native application for Nekoya ~',
url: 'https://github.com/Nekoya-Site/App'
},
{
title: 'Kitchen Counts',
image: 'assets/images/projects/kitchen-counts.webp',
date: '6 October 2022',
categories: 'App',
description: 'Stock management app for kitchen.',
url: 'https://github.com/moepoi/Kitchen_Counts'
},
];

53
src/lib/data/resume.ts Normal file
View file

@ -0,0 +1,53 @@
export interface Resume {
title: string;
description: string;
}
export const experience: Resume[] = [
{
title: 'Bank Central Asia (BCA)',
description: 'International Business & Back Office Application | 2023'
},
{
title: 'Tarumanagara University',
description: 'Student Assistant | 2022 - 2023'
},
{
title: 'Biswap',
description: 'Community Driver | 2021 - 2023'
},
{
title: 'Clee Ltd',
description: 'Developer & System Administrator | 2020 - 2024'
},
{
title: 'Brainly',
description: 'Moderator | 2019'
},
{
title: 'Notify.moe',
description: 'Staff | 2018 - Present'
}
];
export const education: Resume[] = [
{
title: 'Tarumanagara University',
description: 'Bachelor of Computer Science | 2020 - 2024'
},
{
title: 'Methodist School',
description: 'Senior High School | 2017 - 2020'
}
];
export const language: Resume[] = [
{
title: 'Indonesian',
description: 'Native'
},
{
title: 'English',
description: 'Fluent'
}
];

8
src/main.ts Normal file
View file

@ -0,0 +1,8 @@
import './app.css'
import App from './App.svelte'
const app = new App({
target: document.getElementById('app')!,
})
export default app

38
src/routes/Contact.svelte Normal file
View file

@ -0,0 +1,38 @@
<script lang="ts">
import NavBar from '../lib/components/NavBar.svelte';
import { emailAddress, publicKey } from '../lib/data/contact';
import HiddenImage from '../lib/assets/hidden.webp';
let showSnackbar = false;
const copyItem = async (item: string) => {
await navigator.clipboard.writeText(item);
showSnackbar = true;
setTimeout(() => {
showSnackbar = false;
}, 3000);
};
</script>
<NavBar />
<div class="flex flex-col justify-center items-center gap-5 py-5 max-w-4xl mx-4 sm:mx-6 md:mx-auto min-h-screen">
<div class="bg-gradient-to-r from-cyan-500 to-blue-500 p-4 m-4 rounded-xl flex items-center justify-between">
<a href={`mailto:${emailAddress}`}><p class="text-white text-2xl font-bold">{emailAddress}</p></a>
<button class="bg-white text-cyan-500 ml-5 px-4 py-2 rounded-xl" on:click={() => copyItem(emailAddress)}>Copy</button>
</div>
<div class="bg-indigo-950 p-4 rounded-xl m-4">
<div class="flex justify-between items-center mb-4">
<h2 class="text-white text-2xl font-bold">PGP Public Key</h2>
<button class="bg-white text-indigo-950 ml-5 px-4 py-2 rounded-xl" on:click={() => copyItem(publicKey)}>Copy</button>
</div>
<p class="hidden sm:block text-xs sm:text-sm md:text-base lg:text-lg xl:text-lg 2xl:text-lg text-white whitespace-pre-wrap">{publicKey}</p>
</div>
<img class="block sm:hidden w-45 h-40" src={HiddenImage} alt="Hidden" />
</div>
{#if showSnackbar}
<div class="fixed bottom-0 right-0 m-6 bg-green-500 text-white p-5 rounded-xl">
Copied to clipboard!
</div>
{/if}

13
src/routes/Home.svelte Normal file
View file

@ -0,0 +1,13 @@
<script lang="ts">
import NavBar from '../lib/components/NavBar.svelte';
import SocialMedia from '../lib/components/SocialMedia.svelte';
import profile from '../lib/assets/profile.webp';
</script>
<NavBar isFixed={true} />
<div class="flex flex-col items-center justify-center min-h-screen text-white">
<img class="w-40 h-40 rounded-full" src={profile} alt="" />
<h1 class="mt-5 text-4xl font-bold">Moepoi</h1>
<SocialMedia />
</div>

View file

@ -0,0 +1,10 @@
<script lang="ts">
import NotFoundImage from '../lib/assets/not-found.webp';
import { Link } from 'svelte-routing';
</script>
<div class="flex flex-col items-center justify-center min-h-screen">
<h1 class="text-5xl font-bold text-white">Not Found</h1>
<img class="w-45 h-40 mt-5" src={NotFoundImage} alt="" />
<Link to="/" class="mt-5 bg-gradient-to-r from-indigo-500 to-sky-500 text-white px-4 py-2 rounded-xl">Go Home</Link>
</div>

View file

@ -0,0 +1,22 @@
<script lang="ts">
import NavBar from '../lib/components/NavBar.svelte';
import { projects, type Project } from '../lib/data/projects';
let projectsData: Project[] = projects;
</script>
<NavBar />
<div class="flex justify-center items-center min-h-screen">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-5 py-5 max-w-4xl mx-6 sm:mx-6 md:mx-auto md:px-6">
{#each projectsData as project (project.title)}
<div class="flex flex-col rounded-xl bg-indigo-950">
<div class="w-full h-64 bg-cover bg-center m-0 p-0 rounded-t-xl" style="background-image: url('/{project.image}')"></div>
<div class="p-4 pt-0">
<a href={project.url}><h2 class="mt-4 text-white text-xl font-semibold">{project.title}</h2></a>
<p class="mt-2 text-white text-base">{project.description}</p>
</div>
</div>
{/each}
</div>
</div>

43
src/routes/Resume.svelte Normal file
View file

@ -0,0 +1,43 @@
<script lang="ts">
import NavBar from '../lib/components/NavBar.svelte';
import { experience, education, language, type Resume } from '../lib/data/resume';
let experienceData: Resume[] = experience;
let educationData: Resume[] = education;
let languageData: Resume[] = language;
let resumeFile: string = '/assets/resume/Resume-Michael-William-Jonathan.pdf';
</script>
<NavBar />
<div class="max-w-4xl mx-6 sm:mx-6 md:mx-auto md:px-6">
<div class="bg-gradient-to-r from-sky-500 to-emerald-500 mt-6 p-4 flex justify-between items-center rounded-xl">
<h2 class="text-white text-lg font-bold">Download Resume</h2>
<a href={resumeFile}><button class="bg-white text-emerald-500 ml-5 px-4 py-2 rounded-xl">Download</button></a>
</div>
<div class="-m-4 mt-6 p-4 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 gap-4">
<section class="bg-indigo-950 p-4 rounded-xl">
<h2 class="text-white text-2xl font-bold mb-2">Experience</h2>
{#each experienceData as experience (experience.title)}
<p class="text-white text-xl font-semibold">{experience.title}</p>
<p class="text-white text-lg mb-1">{experience.description}</p>
{/each}
</section>
<section class="bg-indigo-950 p-4 rounded-xl">
<h2 class="text-white text-2xl font-bold mb-2">Education</h2>
{#each educationData as education (education.title)}
<p class="text-white text-xl font-semibold">{education.title}</p>
<p class="text-white text-lg mb-1">{education.description}</p>
{/each}
<h2 class="text-white text-2xl font-bold mb-2 mt-3">Language</h2>
{#each languageData as language (language.title)}
<p class="text-white text-xl font-semibold">{language.title}</p>
<p class="text-white text-lg mb-1">{language.description}</p>
{/each}
</section>
</div>
</div>

2
src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />

10
svelte.config.js Normal file
View file

@ -0,0 +1,10 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
target: '#svelte'
}
}

13
tailwind.config.js Normal file
View file

@ -0,0 +1,13 @@
/** @type {import('tailwindcss').Config} */
export default {
plugins: [],
theme: {
extend: {},
},
content: ["./index.html",'./src/**/*.{svelte,js,ts}'], //for unused css
variants: {
extend: {},
},
darkmode: false, // or 'media' or 'class'
}

20
tsconfig.json Normal file
View file

@ -0,0 +1,20 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"resolveJsonModule": true,
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"allowJs": true,
"checkJs": true,
"isolatedModules": true
},
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
"references": [{ "path": "./tsconfig.node.json" }]
}

10
tsconfig.node.json Normal file
View file

@ -0,0 +1,10 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true
},
"include": ["vite.config.ts"]
}

10
vite.config.ts Normal file
View file

@ -0,0 +1,10 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
optimizeDeps: {
include: ['esm-dep > cjs-dep'],
},
})