Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="ko">
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="src/asset/icon.png" />
Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"bootstrap-icons": "^1.13.1",
"i18next": "^25.5.2",
"react": "^19.1.1",
"react-dom": "^19.1.1",
Expand Down
28 changes: 18 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import { Outlet, Link, useLocation } from 'react-router-dom';
import { useTranslation } from "react-i18next";
import { useState } from 'react';
import TranslateButton from './language/translate_button.tsx';
import SoundCloudIcon from './components/soundcloud_icon';
import './style.scss';
import 'bootstrap-icons/font/bootstrap-icons.css'

function App() {
const location = useLocation();
const { t } = useTranslation();
const path = location.pathname;
const [isMenuOpen, setIsMenuOpen] = useState(false);

return (
<div>
<header>
<nav className="container">
<div className="logo">ISLAND</div>
<div className="nav-menu">
<Link to="/" className={"nav-link "+(path=="/"?"active":"")}>{t("home")}</Link>
<Link to="/submission" className={"nav-link "+(path=="/submission"?"active":"")}>{t("submit_id")}</Link>
<Link to="/about" className={"nav-link "+(path=="/about"?"active":"")}>{t("about_island")}</Link>
<div className={`hamburger${isMenuOpen ? ' active' : ''}`} onClick={() => {setIsMenuOpen(!isMenuOpen)}}>
<span></span>
<span></span>
<span></span>
</div>
<div className={`nav-menu${isMenuOpen ? ' active' : ''}`}>
<Link to="/" className={"nav-link "+(path=="/"?"active":"")} onClick={() => setIsMenuOpen(false)}>{t("home")}</Link>
<Link to="/submission" className={"nav-link "+(path=="/submission"?"active":"")} onClick={() => setIsMenuOpen(false)}>{t("submit_id")}</Link>
<Link to="/about" className={"nav-link "+(path=="/about"?"active":"")} onClick={() => setIsMenuOpen(false)}>{t("about_island")}</Link>
<TranslateButton></TranslateButton>
</div>
</nav>
Expand All @@ -28,12 +37,11 @@ function App() {
<footer>
<div className="footer-content">
<p className="social">
<a href="https://soundcloud.com/island-promotion" target="_blank">SoundCloud</a>·
<a href="https://discord.gg/B55PyFm7nW" target="_blank">Discord</a>·
<a href="https://instagram.com/island.ids" target="_blank">Instagram</a>
</p>
<p className="contact">
<a href="mailto:contact@islandlabel.com">contact@islandlabel.com</a>
<a href="https://soundcloud.com/island-by-rrayy" target="_blank" aria-label="SoundCloud">
<SoundCloudIcon style={{ width: '14px', height: '14px', verticalAlign: 'middle' }} />
</a>·
<a href="https://discord.gg/B55PyFm7nW" target="_blank"><i className="bi bi-discord"></i></a>·
<a href="https://instagram.com/island.ids" target="_blank"><i className="bi bi-instagram"></i></a>
</p>
<p className="license">
© 2025 ISLAND · MIT License
Expand Down
44 changes: 42 additions & 2 deletions src/components/componets.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.release-card {
cursor: pointer;

width: 400px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%);
width: 300px;
background: #1a1a1a;
border: 1px solid rgba(255, 255, 255, 0.08);
transition: all 0.4s ease;
padding: 5px;
Expand Down Expand Up @@ -30,4 +30,44 @@
text-transform: uppercase;
letter-spacing: 1px;
}

.release-link {
display: inline-block;
margin-top: 15px;
padding: 8px 20px;
background: rgba(255, 255, 255, 0.1);
color: #fff;
text-decoration: none;
border-radius: 20px;
font-size: 0.9em;
transition: all 0.3s ease;
border: 2px solid rgba(255, 255, 255, 0.2);
}
}

.text-card {
background: #2a2a2a;
border-radius: 12px;
padding: 20px;
margin-left: 20%;
margin-right: 20%;
margin-bottom: 15px;
margin-top: 15px;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
border: 1px solid #333;
animation: slideUp 0.8s ease-out;

h2 {
font-size: 2em;
margin-top: 10px;
margin-bottom: 20px;
color: #fff;
border-bottom: 2px solid #444;
padding-bottom: 10px;
}

@media (max-width: 768px) {
margin-left: 10px;
margin-right: 10px;
}
}
11 changes: 10 additions & 1 deletion src/components/song_card.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import "./componets.scss";
import {Link} from 'react-router-dom';
import { useTranslation } from "react-i18next";

type Props = {
Song_Name: string;
Artist_Name: string;
Cover_Art: string;
index: number;
};

// TODO: 사클 API로 곡 데이터 만으로도 커버 아트 가져올 수 있게 바꾸기
function Song_card({ Song_Name, Artist_Name, Cover_Art}: Props) {
// 현재는 releases.json에서 커버 아트 URL을 직접 넣어주고 있음, 추후에 필요하다 생각되면 사클 API로 바꾸기 (아직 ㄴㄴ)

function Song_card({ Song_Name, Artist_Name, Cover_Art, index}: Props) {
const { t } = useTranslation();

return (
<div className="release-card">
<img className="release-image" src={Cover_Art} alt={Song_Name} />
<div className="release-info">
<h3>{Song_Name}</h3>
<div className="release-artist">{Artist_Name}</div>
<Link to={`/song/${index}`} className="release-link">{t("detail")}</Link>
</div>
</div>
);
Expand Down
30 changes: 30 additions & 0 deletions src/components/soundcloud_icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';

const SoundCloudIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg
viewBox="-271 345.8 256 111.2"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
style={{ transform: 'translateY(-2px)' }}
{...props}
>
<g>
<path fill="currentColor" d="M-238.4,398.1c-0.8,0-1.4,0.6-1.5,1.5l-2.3,28l2.3,27.1c0.1,0.8,0.7,1.5,1.5,1.5c0.8,0,1.4-0.6,1.5-1.5l2.6-27.1l-2.6-28 C-237,398.7-237.7,398.1-238.4,398.1z"/>
<path fill="currentColor" d="M-228.2,399.9c-0.9,0-1.7,0.7-1.7,1.7l-2.1,26l2.1,27.3c0.1,1,0.8,1.7,1.7,1.7c0.9,0,1.6-0.7,1.7-1.7l2.4-27.3l-2.4-26 C-226.6,400.6-227.3,399.9-228.2,399.9z"/>
<path fill="currentColor" d="M-258.6,403.5c-0.5,0-1,0.4-1.1,1l-2.5,23l2.5,22.5c0.1,0.6,0.5,1,1.1,1c0.5,0,1-0.4,1.1-1l2.9-22.5l-2.9-23 C-257.7,404-258.1,403.5-258.6,403.5z"/>
<path fill="currentColor" d="M-268.1,412.3c-0.5,0-1,0.4-1,1l-1.9,14.3l1.9,14c0.1,0.6,0.5,1,1,1s0.9-0.4,1-1l2.2-14l-2.2-14.2 C-267.2,412.8-267.6,412.3-268.1,412.3z"/>
<path fill="currentColor" d="M-207.5,373.5c-1.2,0-2.1,0.9-2.2,2.1l-1.9,52l1.9,27.2c0.1,1.2,1,2.1,2.2,2.1s2.1-0.9,2.2-2.1l2.1-27.2l-2.1-52 C-205.4,374.4-206.4,373.5-207.5,373.5z"/>
<path fill="currentColor" d="M-248.6,399c-0.7,0-1.2,0.5-1.3,1.3l-2.4,27.3l2.4,26.3c0.1,0.7,0.6,1.3,1.3,1.3c0.7,0,1.2-0.5,1.3-1.2l2.7-26.3l-2.7-27.3 C-247.4,399.6-247.9,399-248.6,399z"/>
<path fill="currentColor" d="M-217.9,383.4c-1,0-1.9,0.8-1.9,1.9l-2,42.3l2,27.3c0.1,1.1,0.9,1.9,1.9,1.9s1.9-0.8,1.9-1.9l2.3-27.3l-2.3-42.3 C-216,384.2-216.9,383.4-217.9,383.4z"/>
<path fill="currentColor" d="M-154.4,359.3c-1.8,0-3.2,1.4-3.2,3.2l-1.2,65l1.2,26.1c0,1.8,1.5,3.2,3.2,3.2c1.8,0,3.2-1.5,3.2-3.2l1.4-26.1l-1.4-65 C-151.1,360.8-152.6,359.3-154.4,359.3z"/>
<path fill="currentColor" d="M-197.1,368.9c-1.3,0-2.3,1-2.4,2.4l-1.8,56.3l1.8,26.9c0,1.3,1.1,2.3,2.4,2.3s2.3-1,2.4-2.4l2-26.9l-2-56.3 C-194.7,370-195.8,368.9-197.1,368.9z"/>
<path fill="currentColor" d="M-46.5,394c-4.3,0-8.4,0.9-12.2,2.4C-61.2,368-85,345.8-114,345.8c-7.1,0-14,1.4-20.1,3.8c-2.4,0.9-3,1.9-3,3.7v99.9 c0,1.9,1.5,3.5,3.4,3.7c0.1,0,86.7,0,87.3,0c17.4,0,31.5-14.1,31.5-31.5C-15,408.1-29.1,394-46.5,394z"/>
<path fill="currentColor" d="M-143.6,353.2c-1.9,0-3.4,1.6-3.5,3.5l-1.4,70.9l1.4,25.7c0,1.9,1.6,3.4,3.5,3.4c1.9,0,3.4-1.6,3.5-3.5l1.5-25.8l-1.5-70.9 C-140.2,354.8-141.7,353.2-143.6,353.2z"/>
<path fill="currentColor" d="M-186.5,366.8c-1.4,0-2.5,1.1-2.6,2.6l-1.6,58.2l1.6,26.7c0,1.4,1.2,2.6,2.6,2.6s2.5-1.1,2.6-2.6l1.8-26.7l-1.8-58.2 C-184,367.9-185.1,366.8-186.5,366.8z"/>
<path fill="currentColor" d="M-175.9,368.1c-1.5,0-2.8,1.2-2.8,2.8l-1.5,56.7l1.5,26.5c0,1.6,1.3,2.8,2.8,2.8s2.8-1.2,2.8-2.8l1.7-26.5l-1.7-56.7 C-173.1,369.3-174.3,368.1-175.9,368.1z"/>
<path fill="currentColor" d="M-165.2,369.9c-1.7,0-3,1.3-3,3l-1.4,54.7l1.4,26.3c0,1.7,1.4,3,3,3c1.7,0,3-1.3,3-3l1.5-26.3l-1.5-54.7 C-162.2,371.3-163.5,369.9-165.2,369.9z"/>
</g>
</svg>
);

export default SoundCloudIcon;
18 changes: 18 additions & 0 deletions src/components/text_card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { ReactNode } from 'react';
import "./componets.scss";

type Props = {
title: string;
children: ReactNode;
}

function Card({ title, children }: Props) {
return (
<div className="text-card">
<h2>{title}</h2>
{children}
</div>
);
}

export default Card;
3 changes: 2 additions & 1 deletion src/language/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
"support_desc":"Support for in-production tracks, feedback, collaboration opportunities",
"label":"Label Transition",
"label_desc":"We aim to become a label for growing artists",
"operators": "Operators"
"operators": "Operators",
"detail": "View Details"
}
3 changes: 2 additions & 1 deletion src/language/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
"support_desc":"자체제작 음향 소프트웨어 지원, 피드백 제공, 협업 기회",
"label":"음반사로 전환",
"label_desc":"성장하는 아티스트를 위한 음반사화 추진",
"operators": "운영진"
"operators": "운영진",
"detail": "더 알아보기"
}
2 changes: 1 addition & 1 deletion src/language/translate_button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ i18n
translation: ko,
},
},
lng: "ko-KR",
lng: "en-US",
fallbackLng: {
"ko-KR": ["ko-KR"],
default: ["en-US"],
Expand Down
2 changes: 2 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import App from './App'; // 최상위 레이아웃 컴포넌트, 공통 레이
import HomePage from './pages/Home';
import SubmitPage from './pages/id_submit';
import About from './pages/about';
import SongPage from './pages/song';

const router = createBrowserRouter([
{
Expand All @@ -14,6 +15,7 @@ const router = createBrowserRouter([
{ index: true, element: <HomePage/> },
{ path: 'submission', element: <SubmitPage /> },
{ path: 'about', element: <About/> },
{ path: 'song/:id', element: <SongPage /> },
],
},
]);
Expand Down
16 changes: 7 additions & 9 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import 'swiper/swiper.css';
import "./pages.scss";
import { EffectCoverflow, Pagination } from 'swiper/modules';
import releases from '../releases.json';
import Text_Card from "../components/text_card";

function HomePage(){
//API를 써서 리스트 가져오기?
const { t } = useTranslation();
console.log(releases);

return (
<div>
Expand All @@ -19,15 +19,14 @@ function HomePage(){
<p>{t("sub_title")}</p>
</div>
</section>
<section className="releases">
<h2 className="section-title">{t("releases")}</h2>
<Text_Card title={t("releases")}>
<Swiper
effect={"coverflow"}
grabCursor={true}
centeredSlides={true}
slidesPerView={"auto"}
coverflowEffect={{
rotate: 50,
rotate: 30,
stretch: 0,
depth: 100,
modifier: 1,
Expand All @@ -42,22 +41,21 @@ function HomePage(){
console.log("song"),
(
<SwiperSlide key={idx}>
<Song_card {...song} />
<Song_card {...song} index={idx}/>
</SwiperSlide>
)
)
)}
</Swiper>
</section>
<section className="ID">
<h2 className="section-title">ID</h2>
</Text_Card>
<Text_Card title="ID">
<iframe
width="100%"
height="450"
allow="autoplay"
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/playlists/soundcloud%253Aplaylists%253A2089388063&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=false&show_reposts=false&show_teaser=false"
></iframe>
</section>
</Text_Card>
</div>
);
}
Expand Down
Loading