mirror of
				https://github.com/skidoodle/albert.lol.git
				synced 2025-02-15 06:09:15 +01:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										3
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
{
 | 
			
		||||
  "extends": "next/core-web-vitals"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
# To get started with Dependabot version updates, you'll need to specify which
 | 
			
		||||
# package ecosystems to update and where the package manifests are located.
 | 
			
		||||
# Please see the documentation for all configuration options:
 | 
			
		||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
 | 
			
		||||
 | 
			
		||||
version: 2
 | 
			
		||||
updates:
 | 
			
		||||
  - package-ecosystem: 'npm' # See documentation for possible values
 | 
			
		||||
    directory: '/' # Location of package manifests
 | 
			
		||||
    schedule:
 | 
			
		||||
      interval: 'monthly'
 | 
			
		||||
							
								
								
									
										73
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
# For most projects, this workflow file will not need changing; you simply need
 | 
			
		||||
# to commit it to your repository.
 | 
			
		||||
#
 | 
			
		||||
# You may wish to alter this file to override the set of languages analyzed,
 | 
			
		||||
# or to provide custom queries or build logic.
 | 
			
		||||
#
 | 
			
		||||
# ******** NOTE ********
 | 
			
		||||
# We have attempted to detect the languages in your repository. Please check
 | 
			
		||||
# the `language` matrix defined below to confirm you have the correct set of
 | 
			
		||||
# supported CodeQL languages.
 | 
			
		||||
#
 | 
			
		||||
name: 'CodeQL'
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: ['master']
 | 
			
		||||
  pull_request:
 | 
			
		||||
    # The branches below must be a subset of the branches above
 | 
			
		||||
    branches: ['master']
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '43 21 * * 0'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  analyze:
 | 
			
		||||
    name: Analyze
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    permissions:
 | 
			
		||||
      actions: read
 | 
			
		||||
      contents: read
 | 
			
		||||
      security-events: write
 | 
			
		||||
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        language: ['javascript']
 | 
			
		||||
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
 | 
			
		||||
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      # Initializes the CodeQL tools for scanning.
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@v2
 | 
			
		||||
        with:
 | 
			
		||||
          languages: ${{ matrix.language }}
 | 
			
		||||
          # If you wish to specify custom queries, you can do so here or in a config file.
 | 
			
		||||
          # By default, queries listed here will override any specified in a config file.
 | 
			
		||||
          # Prefix the list here with "+" to use these queries and those in the config file.
 | 
			
		||||
 | 
			
		||||
          # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
 | 
			
		||||
          # queries: security-extended,security-and-quality
 | 
			
		||||
 | 
			
		||||
      # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
 | 
			
		||||
      # If this step fails, then you should remove it and run the build manually (see below)
 | 
			
		||||
      - name: Autobuild
 | 
			
		||||
        uses: github/codeql-action/autobuild@v2
 | 
			
		||||
 | 
			
		||||
      # ℹ️ Command-line programs to run using the OS shell.
 | 
			
		||||
      # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
 | 
			
		||||
 | 
			
		||||
      #   If the Autobuild fails above, remove it and uncomment the following three lines.
 | 
			
		||||
      #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
 | 
			
		||||
 | 
			
		||||
      # - run: |
 | 
			
		||||
      #   echo "Run, Build Application using script"
 | 
			
		||||
      #   ./location_of_script_within_repo/buildscript.sh
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@v2
 | 
			
		||||
        with:
 | 
			
		||||
          category: '/language:${{matrix.language}}'
 | 
			
		||||
							
								
								
									
										20
									
								
								.github/workflows/dependency-review.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/dependency-review.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# Dependency Review Action
 | 
			
		||||
#
 | 
			
		||||
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
 | 
			
		||||
#
 | 
			
		||||
# Source repository: https://github.com/actions/dependency-review-action
 | 
			
		||||
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
 | 
			
		||||
name: 'Dependency Review'
 | 
			
		||||
on: [pull_request]
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  dependency-review:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: 'Checkout Repository'
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
      - name: 'Dependency Review'
 | 
			
		||||
        uses: actions/dependency-review-action@v3
 | 
			
		||||
							
								
								
									
										46
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
 | 
			
		||||
 | 
			
		||||
# dependencies
 | 
			
		||||
/node_modules
 | 
			
		||||
/.pnp
 | 
			
		||||
.pnp.js
 | 
			
		||||
 | 
			
		||||
# testing
 | 
			
		||||
/coverage
 | 
			
		||||
 | 
			
		||||
# next.js
 | 
			
		||||
/.next/
 | 
			
		||||
/out/
 | 
			
		||||
 | 
			
		||||
# production
 | 
			
		||||
/build
 | 
			
		||||
 | 
			
		||||
# misc
 | 
			
		||||
.DS_Store
 | 
			
		||||
*.pem
 | 
			
		||||
 | 
			
		||||
# debug
 | 
			
		||||
npm-debug.log*
 | 
			
		||||
yarn-debug.log*
 | 
			
		||||
yarn-error.log*
 | 
			
		||||
.pnpm-debug.log*
 | 
			
		||||
 | 
			
		||||
# local env files
 | 
			
		||||
.env*.local
 | 
			
		||||
.env
 | 
			
		||||
 | 
			
		||||
# vercel
 | 
			
		||||
.vercel
 | 
			
		||||
 | 
			
		||||
# typescript
 | 
			
		||||
*.tsbuildinfo
 | 
			
		||||
next-env.d.ts
 | 
			
		||||
 | 
			
		||||
# yarn
 | 
			
		||||
.yarn/*
 | 
			
		||||
.yarn/cache
 | 
			
		||||
.yarn/patches
 | 
			
		||||
.yarn/plugins
 | 
			
		||||
.yarn/releases
 | 
			
		||||
.yarn/sdks
 | 
			
		||||
.yarn/versions
 | 
			
		||||
							
								
								
									
										21
									
								
								LICENSE.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2022 skidoodle
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
							
								
								
									
										29
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
# Portfolio v3
 | 
			
		||||
 | 
			
		||||
An awesome portfolio built with [Next.js](https://nextjs.org/) and [Tailwind CSS](https://tailwindcss.com/)
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
Clone the repository
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
git clone https://github.com/skidoodle/albert.lol
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Install the dependencies with [yarn](https://yarnpkg.com/)
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
yarn
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
yarn dev
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Go to `localhost:3000` :)
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
[MIT](https://choosealicense.com/licenses/mit/)
 | 
			
		||||
							
								
								
									
										42
									
								
								components/Icon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								components/Icon.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
import Link from 'next/link';
 | 
			
		||||
import toast from 'react-hot-toast';
 | 
			
		||||
import copy from 'copy-to-clipboard';
 | 
			
		||||
 | 
			
		||||
type Icon = {
 | 
			
		||||
  children: any;
 | 
			
		||||
  reference: string;
 | 
			
		||||
  copyValue?: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const notify = () => {
 | 
			
		||||
  toast.remove(),
 | 
			
		||||
    toast.success('Copied to clipboard', {
 | 
			
		||||
      style: {
 | 
			
		||||
        background: '#0f1012',
 | 
			
		||||
        color: '#fff',
 | 
			
		||||
        fontSize: '1em',
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Icon = ({ children, reference, copyValue }: Icon) => {
 | 
			
		||||
  if (copyValue) {
 | 
			
		||||
    return (
 | 
			
		||||
      <Link
 | 
			
		||||
        href={''}
 | 
			
		||||
        className={`cursor-pointer`}
 | 
			
		||||
        onClick={() => {
 | 
			
		||||
          notify(), copy(reference);
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        {children}
 | 
			
		||||
      </Link>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Link href={reference} target='_blank' className={'cursor-pointer'}>
 | 
			
		||||
      {children}
 | 
			
		||||
    </Link>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										45
									
								
								components/data/socials.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								components/data/socials.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
import { IconType } from 'react-icons/lib';
 | 
			
		||||
import {
 | 
			
		||||
  FaDiscord,
 | 
			
		||||
  FaEnvelope,
 | 
			
		||||
  FaGithub,
 | 
			
		||||
  FaInstagram,
 | 
			
		||||
  FaSteam,
 | 
			
		||||
} from 'react-icons/fa';
 | 
			
		||||
 | 
			
		||||
type Socials = {
 | 
			
		||||
  id: number;
 | 
			
		||||
  ref: string;
 | 
			
		||||
  icon: IconType;
 | 
			
		||||
  copyValue?: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const socials: Array<Socials> = [
 | 
			
		||||
  {
 | 
			
		||||
    id: 1,
 | 
			
		||||
    ref: 'https://github.com/skidoodle',
 | 
			
		||||
    icon: FaGithub,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: 2,
 | 
			
		||||
    ref: 'https://steamcommunity.com/id/_albert',
 | 
			
		||||
    icon: FaSteam,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: 3,
 | 
			
		||||
    ref: 'contact@albert.lol',
 | 
			
		||||
    icon: FaEnvelope,
 | 
			
		||||
    copyValue: true,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: 4,
 | 
			
		||||
    ref: 'https://www.instagram.com/albertadam_/',
 | 
			
		||||
    icon: FaInstagram,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: 5,
 | 
			
		||||
    ref: 'albert#8838',
 | 
			
		||||
    icon: FaDiscord,
 | 
			
		||||
    copyValue: true,
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										25
									
								
								middleware.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								middleware.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import { NextRequest, NextResponse } from 'next/server'
 | 
			
		||||
 | 
			
		||||
export const config = {
 | 
			
		||||
  matcher: [
 | 
			
		||||
    '/ip',
 | 
			
		||||
    '/s3',
 | 
			
		||||
    '/r2',
 | 
			
		||||
    '/spotify'
 | 
			
		||||
  ]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default async function middleware(request: NextRequest) {
 | 
			
		||||
  switch (request.nextUrl.pathname) {
 | 
			
		||||
    case '/ip':
 | 
			
		||||
      return NextResponse.rewrite(new URL('/api/ip', request.nextUrl.origin))
 | 
			
		||||
    case '/s3':
 | 
			
		||||
      return NextResponse.rewrite(new URL('/api/s3', request.nextUrl.origin))
 | 
			
		||||
    case '/r2':
 | 
			
		||||
      return NextResponse.rewrite(new URL('/api/s3', request.nextUrl.origin))
 | 
			
		||||
    case '/spotify':
 | 
			
		||||
      return NextResponse.rewrite(new URL('/api/spotify', request.nextUrl.origin))
 | 
			
		||||
    default:
 | 
			
		||||
      return NextResponse.next()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								next-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								next-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
/// <reference types="next" />
 | 
			
		||||
/// <reference types="next/image-types/global" />
 | 
			
		||||
 | 
			
		||||
// NOTE: This file should not be edited
 | 
			
		||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
 | 
			
		||||
							
								
								
									
										46
									
								
								next.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								next.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
const securityHeaders = [
 | 
			
		||||
  {
 | 
			
		||||
    key: 'X-DNS-Prefetch-Control',
 | 
			
		||||
    value: 'on',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'X-XSS-Protection',
 | 
			
		||||
    value: '1; mode=block',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'X-Content-Type-Options',
 | 
			
		||||
    value: 'nosniff',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'Referrer-Policy',
 | 
			
		||||
    value: 'strict-origin',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'Content-Security-Policy',
 | 
			
		||||
    value: `frame-ancestors 'self';`,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'X-Frame-Options',
 | 
			
		||||
    value: 'SAMEORIGIN',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    key: 'Strict-Transport-Security',
 | 
			
		||||
    value: 'max-age=31536000; includeSubDomains; preload',
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const config = {
 | 
			
		||||
  async headers() {
 | 
			
		||||
    return [
 | 
			
		||||
      {
 | 
			
		||||
        source: '/:path*',
 | 
			
		||||
        headers: securityHeaders,
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
  },
 | 
			
		||||
  reactStrictMode: true,
 | 
			
		||||
  swcMinify: true,
 | 
			
		||||
  poweredByHeader: false,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports = config;
 | 
			
		||||
							
								
								
									
										40
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "portfolio",
 | 
			
		||||
  "version": "3.0",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "author": "albert",
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "next dev",
 | 
			
		||||
    "build": "next build",
 | 
			
		||||
    "start": "next start",
 | 
			
		||||
    "lint": "next lint"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@vercel/analytics": "^0.1.8",
 | 
			
		||||
    "@vercel/edge-config": "^0.1.1",
 | 
			
		||||
    "aws-sdk": "^2.1295.0",
 | 
			
		||||
    "next": "^13.1.5",
 | 
			
		||||
    "react": "^18.2.0",
 | 
			
		||||
    "react-dom": "^18.2.0",
 | 
			
		||||
    "react-fade-in": "^2.0.1",
 | 
			
		||||
    "spotify-now-playing": "^1.1.4",
 | 
			
		||||
    "swr": "^2.0.1"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/node": "18.11.18",
 | 
			
		||||
    "@types/react": "18.0.27",
 | 
			
		||||
    "@types/react-dom": "18.0.10",
 | 
			
		||||
    "autoprefixer": "^10.4.13",
 | 
			
		||||
    "copy-to-clipboard": "^3.3.3",
 | 
			
		||||
    "eslint": "8.32.0",
 | 
			
		||||
    "eslint-config-next": "^13.1.5",
 | 
			
		||||
    "postcss": "^8.4.18",
 | 
			
		||||
    "react-hot-toast": "^2.4.0",
 | 
			
		||||
    "react-icons": "^4.7.1",
 | 
			
		||||
    "sass": "^1.57.1",
 | 
			
		||||
    "tailwindcss": "^3.2.1",
 | 
			
		||||
    "typescript": "4.9.4"
 | 
			
		||||
  },
 | 
			
		||||
  "packageManager": "yarn@1.22.19"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								pages/_app.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								pages/_app.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
import { AppProps } from 'next/app';
 | 
			
		||||
import { Analytics } from '@vercel/analytics/react';
 | 
			
		||||
import Head from 'next/head';
 | 
			
		||||
import 'styles/globals.scss';
 | 
			
		||||
 | 
			
		||||
export default function App({ Component, pageProps }: AppProps) {
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Head>
 | 
			
		||||
        <title>albert</title>
 | 
			
		||||
      </Head>
 | 
			
		||||
      <Component {...pageProps} />
 | 
			
		||||
      <Analytics />
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								pages/_document.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								pages/_document.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import Document, { Html, Head, Main, NextScript } from 'next/document';
 | 
			
		||||
 | 
			
		||||
class AppDocument extends Document {
 | 
			
		||||
  render() {
 | 
			
		||||
    return (
 | 
			
		||||
      <Html lang='en'>
 | 
			
		||||
        <Head>
 | 
			
		||||
          <link rel='preconnect' href='https://vitals.vercel-insights.com' />
 | 
			
		||||
          <meta name='title' content='albert' />
 | 
			
		||||
          <meta name='og:title' content='albert' />
 | 
			
		||||
          <meta name='description' content='system administrator' />
 | 
			
		||||
          <meta name='og:description' content='system administrator' />
 | 
			
		||||
          <meta name='theme-color' content='#000000' />
 | 
			
		||||
          <meta property='og:image' content='/favicon.ico' />
 | 
			
		||||
        </Head>
 | 
			
		||||
        <body>
 | 
			
		||||
          <Main />
 | 
			
		||||
          <NextScript />
 | 
			
		||||
        </body>
 | 
			
		||||
      </Html>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AppDocument;
 | 
			
		||||
							
								
								
									
										14
									
								
								pages/api/ip.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								pages/api/ip.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
import { NextApiRequest, NextApiResponse } from 'next';
 | 
			
		||||
 | 
			
		||||
export default async function ip(req: NextApiRequest, res: NextApiResponse){
 | 
			
		||||
    let ip = req.headers['x-vercel-forwarded-for'];
 | 
			
		||||
    let region = req.headers['x-vercel-ip-country-region'];
 | 
			
		||||
    let country = req.headers['x-vercel-ip-country'];
 | 
			
		||||
    let city = req.headers['x-vercel-ip-city'];
 | 
			
		||||
    res.status(200).json({
 | 
			
		||||
        ip: ip,
 | 
			
		||||
        city: city,
 | 
			
		||||
        country: country,
 | 
			
		||||
        region: region
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								pages/api/s3.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								pages/api/s3.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
import { NextApiRequest, NextApiResponse } from 'next';
 | 
			
		||||
import aws from 'aws-sdk';
 | 
			
		||||
 | 
			
		||||
const { BUCKET, ACCESS_KEY, SECRET_KEY, ENDPOINT, REGION } = process.env;
 | 
			
		||||
 | 
			
		||||
export default async function Storage(req: NextApiRequest, res: NextApiResponse) {
 | 
			
		||||
  aws.config.s3 = {
 | 
			
		||||
    accessKeyId: ACCESS_KEY,
 | 
			
		||||
    secretAccessKey: SECRET_KEY,
 | 
			
		||||
    region: REGION,
 | 
			
		||||
    endpoint: ENDPOINT,
 | 
			
		||||
    signatureVersion: 'v4',
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  let isTruncated: boolean | undefined = true;
 | 
			
		||||
  let startAfter;
 | 
			
		||||
 | 
			
		||||
  let objects = 0;
 | 
			
		||||
  let size = 0;
 | 
			
		||||
 | 
			
		||||
  const s3 = new aws.S3();
 | 
			
		||||
 | 
			
		||||
  while (isTruncated) {
 | 
			
		||||
    let params: any = { Bucket: BUCKET };
 | 
			
		||||
 | 
			
		||||
    if (startAfter) {
 | 
			
		||||
      params.StartAfter = startAfter;
 | 
			
		||||
    }
 | 
			
		||||
    const data = await s3.listObjectsV2(params).promise();
 | 
			
		||||
 | 
			
		||||
    data.Contents?.forEach((object: any) => {
 | 
			
		||||
      objects++;
 | 
			
		||||
      size += object.Size! / 1024 / 1024 / 1024;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    isTruncated = data.IsTruncated;
 | 
			
		||||
    if (isTruncated) {
 | 
			
		||||
      startAfter = data.Contents!.slice(-1)[0].Key;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  res.setHeader(
 | 
			
		||||
    'Cache-Control',
 | 
			
		||||
    'public, s-maxage=10, stale-while-revalidate=59'
 | 
			
		||||
  );
 | 
			
		||||
  res.json({
 | 
			
		||||
    object: objects,
 | 
			
		||||
    size: Number(size.toFixed(2))
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								pages/api/spotify.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								pages/api/spotify.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
import { NextApiRequest, NextApiResponse } from 'next';
 | 
			
		||||
import { SpotifyService } from 'spotify-now-playing'
 | 
			
		||||
 | 
			
		||||
export default async function Spotify(req: NextApiRequest, res: NextApiResponse) {
 | 
			
		||||
    const { CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN } = process.env;
 | 
			
		||||
    const spotify = new SpotifyService(CLIENT_ID!, CLIENT_SECRET!, REFRESH_TOKEN!)
 | 
			
		||||
    const song = await spotify.getCurrentSong()
 | 
			
		||||
 | 
			
		||||
    if(!song || !song.isPlaying ) {
 | 
			
		||||
        return res.status(200).json({
 | 
			
		||||
          nowplaying: false,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    res.status(200).json({
 | 
			
		||||
      nowplaying: true,
 | 
			
		||||
      song: {
 | 
			
		||||
        artist: song.artists.name,
 | 
			
		||||
        title: song.title,
 | 
			
		||||
        url: song.url,
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								pages/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								pages/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
import Image from 'next/image';
 | 
			
		||||
import Link from 'next/link';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import useSWR from 'swr';
 | 
			
		||||
import FadeIn from 'react-fade-in';
 | 
			
		||||
 | 
			
		||||
import { socials } from 'components/data/socials';
 | 
			
		||||
import { Icon } from 'components/Icon';
 | 
			
		||||
import { Toaster } from 'react-hot-toast';
 | 
			
		||||
import { FaSpotify } from 'react-icons/fa';
 | 
			
		||||
 | 
			
		||||
import profilePic from 'public/profile.webp';
 | 
			
		||||
 | 
			
		||||
export const fetcher = (url: RequestInfo) => fetch(url).then((r) => r.json());
 | 
			
		||||
 | 
			
		||||
export default function Main() {
 | 
			
		||||
  var { data: spotify } = useSWR('/api/spotify', fetcher, {
 | 
			
		||||
    refreshInterval: 3000,
 | 
			
		||||
    fallbackData: 'loading',
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <FadeIn>
 | 
			
		||||
      <div className='px-8 2xl:translate-y-2/3 translate-y-1/3 m-auto max-w-4xl'>
 | 
			
		||||
        <div className='flex flex-col justify-center items-center'>
 | 
			
		||||
          <Image
 | 
			
		||||
            src={profilePic}
 | 
			
		||||
            alt='Profile Picture'
 | 
			
		||||
            placeholder='blur'
 | 
			
		||||
            className='rounded-full text-center'
 | 
			
		||||
            height={150}
 | 
			
		||||
            width={150}
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <h1 className='text-4xl font-bold mt-1'>
 | 
			
		||||
            albert
 | 
			
		||||
            <span className='align-text-top text-xs'>
 | 
			
		||||
              {Math.floor(
 | 
			
		||||
                (new Date().getTime() - new Date('2004-07-22').getTime()) /
 | 
			
		||||
                  (1000 * 60 * 60 * 24 * 365.25)
 | 
			
		||||
              )}
 | 
			
		||||
            </span>
 | 
			
		||||
          </h1>
 | 
			
		||||
 | 
			
		||||
          <p className='text-[#9ca3af] text-xl flex flex-wrap items-center justify-center whitespace-pre-wrap'>
 | 
			
		||||
            Systems Administrator
 | 
			
		||||
          </p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <hr className='border-t-[#727277] w-4/5 md:w-2/5 m-auto mt-5 md:mt-8' />
 | 
			
		||||
 | 
			
		||||
        <div className='mt-3 flex justify-center items-center'>
 | 
			
		||||
          <FaSpotify className='text-[#32a866]' />
 | 
			
		||||
          <p className='font-semibold pl-1'>
 | 
			
		||||
            Listening to{' '}
 | 
			
		||||
            {spotify.song ? (
 | 
			
		||||
              <Link
 | 
			
		||||
                href={`${spotify.song.url}`}
 | 
			
		||||
                target='_blank'
 | 
			
		||||
                className='text-[#32a866]'
 | 
			
		||||
              >
 | 
			
		||||
                {' '}
 | 
			
		||||
                {spotify.song.title}
 | 
			
		||||
              </Link>
 | 
			
		||||
            ) : (
 | 
			
		||||
              <span className='text-[#32a866]'>nothing</span>
 | 
			
		||||
            )}
 | 
			
		||||
          </p>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div className='flex justify-between items-center text-3xl mt-11 md:mt-16 max-w-sm m-auto'>
 | 
			
		||||
          {socials.map((social) => (
 | 
			
		||||
            <Icon
 | 
			
		||||
              key={social.id}
 | 
			
		||||
              reference={social.ref}
 | 
			
		||||
              copyValue={social.copyValue}
 | 
			
		||||
            >
 | 
			
		||||
              {React.createElement(social.icon)}
 | 
			
		||||
            </Icon>
 | 
			
		||||
          ))}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <Toaster />
 | 
			
		||||
    </FadeIn>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								postcss.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								postcss.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
module.exports = {
 | 
			
		||||
  plugins: {
 | 
			
		||||
    tailwindcss: {},
 | 
			
		||||
    autoprefixer: {},
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 25 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/profile.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/profile.webp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 28 KiB  | 
							
								
								
									
										31
									
								
								styles/globals.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								styles/globals.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
@tailwind base;
 | 
			
		||||
@tailwind components;
 | 
			
		||||
@tailwind utilities;
 | 
			
		||||
 | 
			
		||||
@layer base {
 | 
			
		||||
  html {
 | 
			
		||||
    scrollbar-width: thin;
 | 
			
		||||
    scrollbar-color: #8a58e0 transparent;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  body {
 | 
			
		||||
    background-color: #000;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@layer components {
 | 
			
		||||
  ::selection {
 | 
			
		||||
    background-color: #8039e2;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::-webkit-scrollbar {
 | 
			
		||||
    width: 3px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::-webkit-scrollbar-thumb {
 | 
			
		||||
    background-color: #8a58e0;
 | 
			
		||||
    border-radius: 10px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tailwind.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
/** @type {import('tailwindcss').Config} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
  content: [
 | 
			
		||||
    './pages/**/*.{js,ts,jsx,tsx}',
 | 
			
		||||
    './components/**/*.{js,ts,jsx,tsx}',
 | 
			
		||||
  ],
 | 
			
		||||
  theme: {
 | 
			
		||||
    extend: {},
 | 
			
		||||
  },
 | 
			
		||||
  plugins: [],
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										21
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "es5",
 | 
			
		||||
    "lib": ["dom", "dom.iterable", "esnext"],
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "forceConsistentCasingInFileNames": true,
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
    "esModuleInterop": true,
 | 
			
		||||
    "module": "esnext",
 | 
			
		||||
    "moduleResolution": "node",
 | 
			
		||||
    "resolveJsonModule": true,
 | 
			
		||||
    "isolatedModules": true,
 | 
			
		||||
    "jsx": "preserve",
 | 
			
		||||
    "incremental": true,
 | 
			
		||||
    "baseUrl": "."
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
 | 
			
		||||
  "exclude": ["node_modules"]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user