Compare commits

...

2 Commits
main ... main

7 changed files with 3741 additions and 3808 deletions

2
.env.example Normal file
View File

@ -0,0 +1,2 @@
VITE_GIV_EMAIL = 'youremail@email.com'
VITE_LAST_USERNAME = 'your_last_username'

7324
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +1,47 @@
{
"name": "givs-website-react",
"private": true,
"version": "1.3.3",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@fontsource-variable/red-hat-display": "^5.1.1",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@tanstack/react-query": "^5.69.0",
"@types/node": "^22.13.0",
"axios": "^1.8.4",
"dotenv": "^16.4.7",
"fs": "^0.0.1-security",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.4",
"keen-slider": "^6.8.6",
"lucide-react": "^0.474.0",
"path": "^0.12.7",
"pnpm": "^9.15.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^15.4.1",
"react-router-dom": "^7.1.5",
"react-typed": "^2.0.12",
"styled-components": "^6.1.14"
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.19.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.18",
"globals": "^15.14.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.22.0",
"vite": "^5.4.14"
}
}
{
"name": "givs-website-react",
"private": true,
"version": "1.3.5",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@fontsource-variable/red-hat-display": "^5.1.1",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@tanstack/react-query": "^5.69.0",
"@types/node": "^22.13.0",
"axios": "^1.8.4",
"fs": "^0.0.1-security",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.4",
"keen-slider": "^6.8.6",
"lucide-react": "^0.474.0",
"path": "^0.12.7",
"pnpm": "^9.15.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^15.4.1",
"react-router-dom": "^7.1.5",
"react-typed": "^2.0.12",
"styled-components": "^6.1.14"
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.19.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.18",
"globals": "^15.14.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.22.0",
"vite": "^5.4.14"
}
}

View File

@ -1,61 +1,10 @@
import { api } from "../lib/axios";
export interface TrackResponse {
track: {
album: {
mbid: string,
"#text": string
},
artist: {
mbid: string,
"#text": string
},
date: {
uts: string,
"#text": string
},
image: [{
"#text": string,
size: string
}],
mbid: string,
name: string,
streamable: string,
url: string
}
}
export interface getRecentTracksResponse {
recenttracks: {
track: [{
artist: {
mbid: string,
"#text": string
},
streamable: string,
image: [{
"#text": string,
size: string
}],
mbid: string,
name: string,
url: string,
date: {
uts: string,
"#text": string
}
}]
}
}
export async function getRecentTracks() {
try {
const response = await api.get<TrackResponse>('');
console.log('Last.fm data:', response.data);
const response = await api.get('/latest-song');
return response.data;
} catch (error) {
console.error('Err while fetching Last.fm data:', error);
throw error;
return error;
}
}

View File

@ -1,7 +1,8 @@
import axios from 'axios'
const defaultApiUrl = 'https://lastfm-last-played.biancarosa.com.br/givfnz/latest-song';
const username = import.meta.env.VITE_LAST_USERNAME;
const defaultApiUrl = `https://lastfm-last-played.biancarosa.com.br/${username}`;
export const api = axios.create({
baseURL: import.meta.env.VITE_LASTFM_API_URL || defaultApiUrl,
baseURL: defaultApiUrl,
})

View File

@ -1,33 +1,33 @@
import { useState } from 'react';
import { Button, TextArea } from './styles';
import { MainContainer } from '../../components/MainContent/styles';
import { Send } from 'lucide-react';
import { Paragraph } from '../../components/Paragraph/styles';
import { useTranslation } from 'react-i18next';
export default function Contact() {
const { t } = useTranslation();
const emailAddress = import.meta.env.VITE_GIV_EMAIL;
const [typedText, setTypedText] = useState('');
function handleSubmit() {
const mailToTrigger = 'mailto:' + emailAddress + '&subject=I visited your website!&body=' + typedText;
window.location.href = mailToTrigger
}
return (
<MainContainer>
<h1>{t("contact")}</h1>
<Paragraph>
<span>{t("contactInfo")}</span>
</Paragraph>
<form onSubmit={handleSubmit}>
<TextArea
onChange={(e) => setTypedText(e.target.value)}
className="bgb"
/>
<Button type='submit'><Send className="ico" />{t("send")}</Button>
</form>
</MainContainer>
);
import { useState } from 'react';
import { Button, TextArea } from './styles';
import { MainContainer } from '../../components/MainContent/styles';
import { Send } from 'lucide-react';
import { Paragraph } from '../../components/Paragraph/styles';
import { useTranslation } from 'react-i18next';
export default function Contact() {
const { t } = useTranslation();
const emailAddress = import.meta.env.VITE_GIV_EMAIL;
const [typedText, setTypedText] = useState('');
function handleSubmit() {
const mailToTrigger = 'mailto:' + emailAddress + '&subject=I visited your website!&body=' + typedText;
window.location.href = mailToTrigger
}
return (
<MainContainer>
<h1>{t("contact")}</h1>
<Paragraph>
<span>{t("contactInfo")}</span>
</Paragraph>
<form onSubmit={handleSubmit}>
<TextArea
onChange={(e) => setTypedText(e.target.value)}
className="bgb"
/>
<Button type='submit'><Send className="ico" />{t("send")}</Button>
</form>
</MainContainer>
);
}

View File

@ -1,4 +1,4 @@
import { getRecentTracks, TrackResponse } from "../../api/lastfm";
import { getRecentTracks } from "../../api/lastfm";
import { MainContainer } from "../../components/MainContent/styles";
import { useQuery } from '@tanstack/react-query'
import { Paragraph } from "../../components/Paragraph/styles";
@ -8,7 +8,7 @@ import { MusicDescription, MusicTitle } from "./styles";
export default function Music() {
const { t } = useTranslation()
const { data: lastResponse, isLoading, isError, error } = useQuery<TrackResponse>({
const { data: lastResponse, isLoading, isError, error } = useQuery({
queryKey: ['song'],
queryFn: getRecentTracks,
retry: 1,