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
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
interval: "weekly"
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -34,5 +34,4 @@ yarn-error.log*
|
|||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
|
||||
.vercel
|
||||
next-env.d.ts
|
||||
|
|
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'
|
||||
|
||||
const Icon = ({icon, reference, copy = false} : {icon: any, reference: any, copy?: boolean}) => {
|
||||
return(
|
||||
<>
|
||||
{
|
||||
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} />
|
||||
</>
|
||||
)
|
||||
type Icon = {
|
||||
children: any,
|
||||
reference: string,
|
||||
copyValue?: boolean,
|
||||
}
|
||||
|
||||
const doThings = (value: any) => {
|
||||
copy(value)
|
||||
toast.remove()
|
||||
const notify = () => {
|
||||
toast.remove(),
|
||||
toast.success('Copied to clipboard', {
|
||||
style: {
|
||||
background: '#111',
|
||||
background: '#0f1012',
|
||||
color: '#fff',
|
||||
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')
|
||||
|
||||
module.export = {
|
||||
productionBrowserSourceMaps: true,
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
swcMinify: true,
|
||||
sassOptions: {
|
||||
includePaths: [path.join(__dirname, 'styles')]
|
||||
images: {
|
||||
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",
|
||||
"version": "1.0",
|
||||
"version": "2.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"buildexport": "next build && next export"
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"aws-sdk": "^2.1189.0",
|
||||
"copy-to-clipboard": "^3.3.2",
|
||||
"@swc/core": "^1.2.223",
|
||||
"csstype": "^3.1.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",
|
||||
"aws-sdk": "^2.1194.0",
|
||||
"next": "12.2.5",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-fade-in": "^2.0.1",
|
||||
"react-hot-toast": "^2.3.0",
|
||||
"react-icons": "^4.4.0",
|
||||
"sass": "^1.54.3",
|
||||
"use-last-fm": "^0.6.1"
|
||||
"swr": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/node": "18.6.4",
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.4",
|
||||
"eslint": "8.21.0",
|
||||
"eslint-config-next": "12.2.4",
|
||||
"@types/node": "18.7.3",
|
||||
"@types/react": "18.0.17",
|
||||
"@types/react-dom": "18.0.6",
|
||||
"autoprefixer": "^10.4.8",
|
||||
"copy-to-clipboard": "^3.3.2",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
import { AppProps } from 'next/app'
|
||||
import 'styles/globals.scss'
|
||||
import Head from 'next/head'
|
||||
|
||||
const MyApp = ({ Component, pageProps }: AppProps) => {
|
||||
return <Component {...pageProps} />
|
||||
import { AppProps } from 'next/app'
|
||||
|
||||
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 })
|
||||
}
|
|
@ -1,52 +1,62 @@
|
|||
import { GetServerSideProps } from 'next'
|
||||
import Head from 'next/head'
|
||||
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 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 (
|
||||
<>
|
||||
<Head>
|
||||
<title>albert</title>
|
||||
</Head>
|
||||
<Body>
|
||||
<FadeIn>
|
||||
<MainLayout />
|
||||
<IconLayout>
|
||||
<Icon icon={<FaGithub />} reference={'https://github.com/skidoodle'} copy={false} />
|
||||
<Icon icon={<FaSteam />} reference={'https://steamcommunity.com/id/_albert'} copy={false} />
|
||||
<Icon icon={<FaEnvelope />} reference={'contact@albert.lol'} copy={true} />
|
||||
<Icon icon={<RiInstagramFill />} reference={'https://instagram.com/albertadam_'} copy={false} />
|
||||
<Icon icon={<SiDiscord />} reference={'albert#8838'} copy={true} />
|
||||
</IconLayout>
|
||||
<Time />
|
||||
<Weather data={data} />
|
||||
<Spotify />
|
||||
</FadeIn>
|
||||
</Body>
|
||||
<div className='px-8 w-11/12 m-auto rounded-lg max-w-4xl'>
|
||||
<div className='flex flex-col justify-center items-center mt-32 md:mt-56'>
|
||||
<Image src={profilePic} className="rounded-full text-center" height={150} width={150}/>
|
||||
|
||||
<h1 className='text-4xl font-bold -mt-1'>albert</h1>
|
||||
|
||||
<p className='text-[#9ca3af] text-xl flex flex-wrap items-center justify-center whitespace-pre-wrap'>
|
||||
{ Math.floor((new Date().getTime() - new Date('2004.07.22').getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }
|
||||
yrs old <b className='font-semibold'>system administrator</b> and student from Hungary
|
||||
</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'>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';
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@200;400;700&display=swap');
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html,
|
||||
body {
|
||||
background-color: $background-color;
|
||||
color: $primary-color;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: $font;
|
||||
font-weight: 400;
|
||||
@layer base {
|
||||
html {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #8a58e0 transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
list-style: revert;
|
||||
}
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: rgba($selection-color, .7);
|
||||
color: $primary-color;
|
||||
@layer components {
|
||||
::selection {
|
||||
background-color: #8039e2;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 3px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #8a58e0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
@layer utilities {
|
||||
.gradient {
|
||||
color: transparent;
|
||||
background-clip: text;
|
||||
background-image: linear-gradient(to right, #800a18, #a82044, #9e4a60);
|
||||
animation: gradient 5s ease infinite
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@keyframes gradient {
|
||||
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