mirror of
https://github.com/skidoodle/albert.lol.git
synced 2025-02-15 06:09:15 +01:00
v3
This commit is contained in:
parent
3a92d65900
commit
7dedfba1f9
31 changed files with 2971 additions and 1859 deletions
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "next/core-web-vitals",
|
|
||||||
"rules": {
|
|
||||||
"@next/next/no-img-element": "off"
|
|
||||||
}
|
|
||||||
}
|
|
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
|
@ -8,4 +8,4 @@ updates:
|
||||||
- package-ecosystem: "npm" # See documentation for possible values
|
- package-ecosystem: "npm" # See documentation for possible values
|
||||||
directory: "/" # Location of package manifests
|
directory: "/" # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "weekly"
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -34,5 +34,4 @@ yarn-error.log*
|
||||||
|
|
||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
.vercel
|
|
||||||
|
|
21
LICENSE.md
21
LICENSE.md
|
@ -1,21 +0,0 @@
|
||||||
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.
|
|
|
@ -1,2 +0,0 @@
|
||||||
# portfolio-v2
|
|
||||||
Built with Next.js ♥
|
|
|
@ -1,11 +0,0 @@
|
||||||
import styles from 'styles/Home.module.scss'
|
|
||||||
|
|
||||||
const Body = ({children}: {children: any}) => {
|
|
||||||
return(
|
|
||||||
<div className={styles.bodySection}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Body
|
|
|
@ -1,35 +1,32 @@
|
||||||
import toast, { Toaster } from 'react-hot-toast';
|
import Link from 'next/link'
|
||||||
|
import toast from 'react-hot-toast'
|
||||||
import copy from 'copy-to-clipboard'
|
import copy from 'copy-to-clipboard'
|
||||||
|
|
||||||
const Icon = ({icon, reference, copy = false} : {icon: any, reference: any, copy?: boolean}) => {
|
type Icon = {
|
||||||
return(
|
children: any,
|
||||||
<>
|
reference: string,
|
||||||
{
|
copyValue?: boolean,
|
||||||
copy ? (
|
|
||||||
<a href='javascript:void(0)' onClick={() => doThings(reference)}>
|
|
||||||
{icon}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<a href={reference} target='_blank' rel='noopener noreferrer' aria-label="Icon">
|
|
||||||
{icon}
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<Toaster position='bottom-center' reverseOrder={false} />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const doThings = (value: any) => {
|
const notify = () => {
|
||||||
copy(value)
|
toast.remove(),
|
||||||
toast.remove()
|
|
||||||
toast.success('Copied to clipboard', {
|
toast.success('Copied to clipboard', {
|
||||||
style: {
|
style: {
|
||||||
background: '#111',
|
background: '#0f1012',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
fontSize: '1em'
|
fontSize: '1em'
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
)}
|
||||||
|
|
||||||
export default Icon
|
export const Icon = ({ children, reference, copyValue }: Icon) => {
|
||||||
|
if(copyValue) {
|
||||||
|
return <a className={`cursor-pointer`} onClick={ () => { notify(), copy(reference) }} >{ children }</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link href={ reference }>
|
||||||
|
<a target='_blank' className={`cursor-pointer`}>{ children }</a>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import styles from 'styles/Home.module.scss'
|
|
||||||
|
|
||||||
const IconLayout = ({children}: {children: any}) => {
|
|
||||||
return(
|
|
||||||
<>
|
|
||||||
<div className={styles.iconLayout}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default IconLayout
|
|
|
@ -1,14 +0,0 @@
|
||||||
import styles from 'styles/Home.module.scss'
|
|
||||||
|
|
||||||
const MainLayout = () => {
|
|
||||||
return(
|
|
||||||
<>
|
|
||||||
<div className={styles.mainLayout}>
|
|
||||||
<h1>albert</h1>
|
|
||||||
<p>18-year-old <b>system administrator</b> and student from Hungary</p>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MainLayout
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { useLastFM } from 'use-last-fm'
|
|
||||||
import { FaSpotify } from 'react-icons/fa'
|
|
||||||
import styles from 'styles/Home.module.scss'
|
|
||||||
|
|
||||||
const Spotify = () => {
|
|
||||||
const lastFM = useLastFM('albrtadam', 'f6d19bc25ca340225c70c3d386cd4eab');
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div className={styles.spotify}>
|
|
||||||
{lastFM.status === 'playing'
|
|
||||||
?
|
|
||||||
<>
|
|
||||||
<a href={lastFM.song.url} target='_blank' rel='noopener noreferrer'>
|
|
||||||
<img src={lastFM.song.art} width={50} height={50} alt=""/>
|
|
||||||
<p>Listening to <b>{lastFM.song.name}</b></p>
|
|
||||||
</a>
|
|
||||||
</>
|
|
||||||
:
|
|
||||||
<>
|
|
||||||
<img src='song_art.png' width={50} height={50} alt=""/>
|
|
||||||
<p>Not listening to anything</p>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
<div className={styles.tinyText}>
|
|
||||||
<FaSpotify /> Spotify
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Spotify
|
|
|
@ -1,26 +0,0 @@
|
||||||
import { FaClock } from 'react-icons/fa';
|
|
||||||
import { dayjs } from 'components/dayjs'
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import styles from 'styles/Home.module.scss'
|
|
||||||
|
|
||||||
const now = () => dayjs().tz()
|
|
||||||
|
|
||||||
const format = 'hhA'
|
|
||||||
|
|
||||||
const Time = () => {
|
|
||||||
const [date, setDate] = useState(now())
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const timer = setInterval(() => setDate(now()), 1000)
|
|
||||||
return () => clearInterval(timer)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<p className={styles.time}>
|
|
||||||
<FaClock />
|
|
||||||
{' '}{date.format('DD/MM/YYYY • h:mm:ss A')}
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Time
|
|
|
@ -1,28 +0,0 @@
|
||||||
import styles from 'styles/Home.module.scss'
|
|
||||||
import { FaSun, FaMoon, FaCloudSun, FaCloudMoon, FaCloud, FaCloudShowersHeavy } from 'react-icons/fa'
|
|
||||||
import { BsCloudDrizzleFill, BsCloudsFill, BsCloudLightningFill, BsCloudSnowFill, BsCloudFogFill } from 'react-icons/bs'
|
|
||||||
|
|
||||||
const Weather = ({data}: {data: any}) => {
|
|
||||||
const { temp: temperature } = data.main
|
|
||||||
const { icon: weatherIcon, description: weatherDescription} = data.weather[0]
|
|
||||||
|
|
||||||
const icons: any = {
|
|
||||||
_01d: <FaSun />, _01n: <FaMoon />,
|
|
||||||
_02d: <FaCloudSun />, _02n: <FaCloudMoon />,
|
|
||||||
_03d: <FaCloud />, _03n: <FaCloud />,
|
|
||||||
_04d: <BsCloudsFill />, _04n: <BsCloudsFill />,
|
|
||||||
_09d: <BsCloudDrizzleFill />, _09n: <BsCloudDrizzleFill />,
|
|
||||||
_10d: <FaCloudShowersHeavy />, _10n: <FaCloudShowersHeavy />,
|
|
||||||
_11d: <BsCloudLightningFill />, _11n: <BsCloudLightningFill />,
|
|
||||||
_13d: <BsCloudSnowFill />, _13n: <BsCloudSnowFill />,
|
|
||||||
_50d: <BsCloudFogFill />, _50n: <BsCloudFogFill />
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.weather}>
|
|
||||||
{icons[`_${weatherIcon}`]} <p>It's currently <b>{parseInt(temperature)} °C</b> <span>({weatherDescription})</span> in <a href='https://weather.com/en-GB/weather/today/l/b979f874d2f515646f37e2bb434a85cc04869c5a35c6bdf1c6fba26f659313f0' target="_blank" rel='noopener noreferrer'><b>Budapest</b></a></p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Weather
|
|
39
components/data/socials.ts
Normal file
39
components/data/socials.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,9 +0,0 @@
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import utc from 'dayjs/plugin/utc'
|
|
||||||
import timezone from 'dayjs/plugin/timezone'
|
|
||||||
|
|
||||||
dayjs.extend(utc)
|
|
||||||
dayjs.extend(timezone)
|
|
||||||
dayjs.tz.setDefault('Europe/Budapest')
|
|
||||||
|
|
||||||
export { dayjs }
|
|
|
@ -1,9 +1,10 @@
|
||||||
const path = require('path')
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
module.export = {
|
reactStrictMode: true,
|
||||||
productionBrowserSourceMaps: true,
|
|
||||||
swcMinify: true,
|
swcMinify: true,
|
||||||
sassOptions: {
|
images: {
|
||||||
includePaths: [path.join(__dirname, 'styles')]
|
domains: ['i.arch.gay', 'cdn.discordapp.com']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = nextConfig
|
||||||
|
|
2308
package-lock.json
generated
Normal file
2308
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
41
package.json
41
package.json
|
@ -1,39 +1,32 @@
|
||||||
{
|
{
|
||||||
"name": "portfolio",
|
"name": "portfolio",
|
||||||
"version": "1.0",
|
"version": "2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint"
|
||||||
"buildexport": "next build && next export"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aws-sdk": "^2.1189.0",
|
"aws-sdk": "^2.1194.0",
|
||||||
"copy-to-clipboard": "^3.3.2",
|
"next": "12.2.5",
|
||||||
"@swc/core": "^1.2.223",
|
"react": "18.2.0",
|
||||||
"csstype": "^3.1.0",
|
"react-dom": "18.2.0",
|
||||||
"dayjs": "^1.11.4",
|
|
||||||
"dotenv": "^16.0.1",
|
|
||||||
"goober": "2.1.10",
|
|
||||||
"next": "12.2.3",
|
|
||||||
"react": "^18.2.0",
|
|
||||||
"react-dom": "^18.2.0",
|
|
||||||
"react-fade-in": "^2.0.1",
|
"react-fade-in": "^2.0.1",
|
||||||
"react-hot-toast": "^2.3.0",
|
"swr": "^1.3.0"
|
||||||
"react-icons": "^4.4.0",
|
|
||||||
"sass": "^1.54.3",
|
|
||||||
"use-last-fm": "^0.6.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/node": "18.7.3",
|
||||||
"@types/node": "18.6.4",
|
"@types/react": "18.0.17",
|
||||||
"@types/react": "^18.0.15",
|
"@types/react-dom": "18.0.6",
|
||||||
"@types/react-dom": "^18.0.4",
|
"autoprefixer": "^10.4.8",
|
||||||
"eslint": "8.21.0",
|
"copy-to-clipboard": "^3.3.2",
|
||||||
"eslint-config-next": "12.2.4",
|
"postcss": "^8.4.16",
|
||||||
|
"react-hot-toast": "^2.3.0",
|
||||||
|
"react-icons": "^4.4.0",
|
||||||
|
"sass": "^1.54.4",
|
||||||
|
"tailwindcss": "^3.1.8",
|
||||||
"typescript": "4.7.4"
|
"typescript": "4.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,21 @@
|
||||||
import { AppProps } from 'next/app'
|
|
||||||
import 'styles/globals.scss'
|
import 'styles/globals.scss'
|
||||||
|
import Head from 'next/head'
|
||||||
|
|
||||||
const MyApp = ({ Component, pageProps }: AppProps) => {
|
import { AppProps } from 'next/app'
|
||||||
return <Component {...pageProps} />
|
|
||||||
|
export default function({ Component, pageProps }: AppProps) {
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<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>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MyApp
|
|
|
@ -1,24 +0,0 @@
|
||||||
import { Html, Head, Main, NextScript } from 'next/document'
|
|
||||||
|
|
||||||
const Document = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Html lang='zxx'>
|
|
||||||
<Head>
|
|
||||||
<link rel='preconnect' href='https://vitals.vercel-insights.com' />
|
|
||||||
<link rel='preconnect' href='https://ws.audioscrobbler.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>
|
|
||||||
<Main />
|
|
||||||
<NextScript />
|
|
||||||
</Html>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Document
|
|
41
pages/_error.tsx
Normal file
41
pages/_error.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { GetServerSideProps } from 'next'
|
||||||
|
import FadeIn from 'react-fade-in'
|
||||||
|
type ErrorPage = {
|
||||||
|
statusCode: number,
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function({ statusCode, message }: ErrorPage) {
|
||||||
|
return (
|
||||||
|
<FadeIn>
|
||||||
|
<div className='flex flex-col justify-center items-center h-[90vh]'>
|
||||||
|
<div>
|
||||||
|
<h1 className='font-semibold text-2xl inline-block mr-[1.7rem] pr-[1.5rem] border-r-[1px] border-white'>{ statusCode }</h1>
|
||||||
|
<div className='inline-block text-left'>
|
||||||
|
<h2 className='text-lg font-extralight'>{ message }</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FadeIn>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getServerSideProps: GetServerSideProps = async(props) => {
|
||||||
|
const { res, err }: any = props
|
||||||
|
|
||||||
|
const statusCode = res ? res.statusCode : err ? err.statusCode : 404
|
||||||
|
|
||||||
|
let entries: any = {
|
||||||
|
404: 'Az oldal nem található',
|
||||||
|
400: 'Érvénytelen kérelem',
|
||||||
|
500: 'Szerveroldali hiba'
|
||||||
|
}
|
||||||
|
const message = entries[statusCode]
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
statusCode,
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
pages/api/spotify.ts
Normal file
26
pages/api/spotify.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
|
||||||
|
export default async function(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
const { LASTFM_USERNAME, LASTFM_API } = process.env
|
||||||
|
|
||||||
|
const { recenttracks: response } = await fetch(`https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${LASTFM_USERNAME}&api_key=${LASTFM_API}&format=json&limit=1`).then((res) => res.json())
|
||||||
|
|
||||||
|
const { track } = response
|
||||||
|
const { artist, name, url, image } = track[0]
|
||||||
|
|
||||||
|
let nowplaying = Boolean(track[0]['@attr']?.nowplaying)
|
||||||
|
|
||||||
|
if(nowplaying) {
|
||||||
|
return res.status(200).json({
|
||||||
|
nowplaying,
|
||||||
|
song: {
|
||||||
|
artist: artist['#text'],
|
||||||
|
title: name,
|
||||||
|
url: url,
|
||||||
|
image: image[2]['#text'],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).json({ nowplaying })
|
||||||
|
}
|
100
pages/index.tsx
100
pages/index.tsx
|
@ -1,52 +1,62 @@
|
||||||
import { GetServerSideProps } from 'next'
|
import Image from 'next/image'
|
||||||
import Head from 'next/head'
|
import Link from 'next/link'
|
||||||
|
import React from 'react'
|
||||||
|
import useSWR from 'swr'
|
||||||
import FadeIn from 'react-fade-in'
|
import FadeIn from 'react-fade-in'
|
||||||
import Body from 'components/Body'
|
|
||||||
import Icon from 'components/Icon'
|
|
||||||
import IconLayout from 'components/IconLayout'
|
|
||||||
import MainLayout from 'components/MainLayout'
|
|
||||||
import Spotify from 'components/Spotify'
|
|
||||||
import Weather from 'components/Weather'
|
|
||||||
import { FaSteam, FaGithub, FaEnvelope } from 'react-icons/fa'
|
|
||||||
import { RiInstagramFill } from 'react-icons/ri'
|
|
||||||
import { SiDiscord } from 'react-icons/si'
|
|
||||||
import dynamic from 'next/dynamic'
|
|
||||||
const Time = dynamic(() => import('components/Time'), {
|
|
||||||
ssr: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
const Home = ({data}: any) => {
|
import { socials } from 'components/data/socials'
|
||||||
|
import { Icon } from 'components/Icon'
|
||||||
|
import profilePic from '../public/profile.webp'
|
||||||
|
import { Toaster } from 'react-hot-toast'
|
||||||
|
import { FaSpotify } from 'react-icons/fa'
|
||||||
|
|
||||||
|
const fetcher = (url: RequestInfo) => fetch(url).then(r => r.json())
|
||||||
|
|
||||||
|
export default function() {
|
||||||
|
const { data: spotify } = useSWR('/api/spotify', fetcher, { refreshInterval: 1000 })
|
||||||
|
if(!spotify) return
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<FadeIn>
|
||||||
<title>albert</title>
|
<div className='px-8 w-11/12 m-auto rounded-lg max-w-4xl'>
|
||||||
</Head>
|
<div className='flex flex-col justify-center items-center mt-32 md:mt-56'>
|
||||||
<Body>
|
<Image src={profilePic} className="rounded-full text-center" height={150} width={150}/>
|
||||||
<FadeIn>
|
|
||||||
<MainLayout />
|
<h1 className='text-4xl font-bold -mt-1'>albert</h1>
|
||||||
<IconLayout>
|
|
||||||
<Icon icon={<FaGithub />} reference={'https://github.com/skidoodle'} copy={false} />
|
<p className='text-[#9ca3af] text-xl flex flex-wrap items-center justify-center whitespace-pre-wrap'>
|
||||||
<Icon icon={<FaSteam />} reference={'https://steamcommunity.com/id/_albert'} copy={false} />
|
{ Math.floor((new Date().getTime() - new Date('2004.07.22').getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }
|
||||||
<Icon icon={<FaEnvelope />} reference={'contact@albert.lol'} copy={true} />
|
yrs old <b className='font-semibold'>system administrator</b> and student from Hungary
|
||||||
<Icon icon={<RiInstagramFill />} reference={'https://instagram.com/albertadam_'} copy={false} />
|
</p>
|
||||||
<Icon icon={<SiDiscord />} reference={'albert#8838'} copy={true} />
|
</div>
|
||||||
</IconLayout>
|
|
||||||
<Time />
|
<hr className='border-t-[#727277] w-4/5 md:w-2/5 m-auto mt-5 md:mt-8'/>
|
||||||
<Weather data={data} />
|
|
||||||
<Spotify />
|
<div className='mt-3 flex justify-center items-center'>
|
||||||
</FadeIn>
|
<FaSpotify className='text-[#32a866]' />
|
||||||
</Body>
|
|
||||||
|
<p className='font-semibold'>Listening to
|
||||||
|
{
|
||||||
|
spotify.song
|
||||||
|
? <Link href={`${spotify.song.url}`}>
|
||||||
|
<a target='_blank' className='text-[#32a866]'> { spotify.song.title || 'nothing' }</a>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
: <a className='text-[#32a866]'> nothing</a>
|
||||||
|
}
|
||||||
|
</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>\
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async () => {
|
|
||||||
const response = await fetch('https://api.openweathermap.org/data/2.5/weather?lat=47.51&lon=19.04&appid=1b3c10c18e894eaf1fd63eedde53fa54&units=metric')
|
|
||||||
const data = await response.json()
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: { data }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Home
|
|
||||||
|
|
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
BIN
public/profile.webp
Normal file
BIN
public/profile.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.9 KiB |
|
@ -1,128 +0,0 @@
|
||||||
@import '_variables';
|
|
||||||
|
|
||||||
.bodySection {
|
|
||||||
margin-top: 8rem;
|
|
||||||
margin-left: 10%;
|
|
||||||
margin-right: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainLayout {
|
|
||||||
h1 {
|
|
||||||
line-height: .2;
|
|
||||||
font-size: 3rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: $secondary-color;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.iconLayout {
|
|
||||||
margin-bottom: 5%;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
font-size: 1.4em;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-right: 6%;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
svg {
|
|
||||||
font-size: .9em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.weather {
|
|
||||||
img {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: .8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #C7D2FE;
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
font-size: .9em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.spotify {
|
|
||||||
font-size: 1em;
|
|
||||||
margin-top: 5%;
|
|
||||||
padding: 1rem 1rem 1.8rem 1rem;
|
|
||||||
border: 1px solid $spotify-box-color;
|
|
||||||
border-radius: .5rem;
|
|
||||||
|
|
||||||
img {
|
|
||||||
border-radius: 10px;
|
|
||||||
float: left;
|
|
||||||
margin-right: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tinyText {
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: .8em;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
margin-top: 5px;
|
|
||||||
color: #1DB954;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.footerLayout {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 1rem;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
|
|
||||||
a {
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #C7D2FE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
.bodySection {
|
|
||||||
margin-left: 30%;
|
|
||||||
margin-right: 45%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconLayout {
|
|
||||||
margin-bottom: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spotify {
|
|
||||||
margin-top: 8%;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-height: 800px) {
|
|
||||||
.bodySection {
|
|
||||||
margin-top: 15rem;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
$background-color: #000000;
|
|
||||||
$primary-color: #ffffff;
|
|
||||||
$secondary-color: #9CA3AF;
|
|
||||||
$selection-color: #8039e2;
|
|
||||||
$spotify-box-color: #521c9e;
|
|
||||||
$font: 'Inter', sans-serif;
|
|
|
@ -1,26 +1,56 @@
|
||||||
@import '_variables';
|
@tailwind base;
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@200;400;700&display=swap');
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
html,
|
@layer base {
|
||||||
body {
|
html {
|
||||||
background-color: $background-color;
|
scrollbar-width: thin;
|
||||||
color: $primary-color;
|
scrollbar-color: #8a58e0 transparent;
|
||||||
padding: 0;
|
}
|
||||||
margin: 0;
|
|
||||||
font-family: $font;
|
body {
|
||||||
font-weight: 400;
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
list-style: revert;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection {
|
@layer components {
|
||||||
background: rgba($selection-color, .7);
|
::selection {
|
||||||
color: $primary-color;
|
background-color: #8039e2;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #8a58e0;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
@layer utilities {
|
||||||
color: inherit;
|
.gradient {
|
||||||
text-decoration: none;
|
color: transparent;
|
||||||
}
|
background-clip: text;
|
||||||
|
background-image: linear-gradient(to right, #800a18, #a82044, #9e4a60);
|
||||||
|
animation: gradient 5s ease infinite
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
@keyframes gradient {
|
||||||
box-sizing: border-box;
|
0%, 100% {
|
||||||
|
background-size: 200%;
|
||||||
|
background-position: left center;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-size: 200%;
|
||||||
|
background-position: right center;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
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: [],
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue