Skip to content

Commit 1ffdd60

Browse files
committed
feat: improve mobile responsiveness
1 parent 1283146 commit 1ffdd60

4 files changed

Lines changed: 82 additions & 75 deletions

File tree

src/components/GitHubButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ const GitHubButton: React.FC<GitHubButtonProps> = ({
3434
onClick={handleClick}
3535
variant="outline"
3636
size="sm"
37-
className={`text-gray-700 hover:text-gray-900 hover:bg-gray-50 border-gray-300 ${className}`}
37+
className={`h-9 px-2.5 text-gray-700 hover:bg-gray-50 hover:text-gray-900 border-gray-300 sm:px-3 ${className}`}
3838
>
39-
<Github className="w-4 h-4 mr-2" />
39+
<Github className="h-4 w-4 sm:mr-2" />
4040
<span className="hidden sm:inline">GitHub</span>
4141
{!loading && stargazers_count > 0 && (
42-
<div className="flex items-center ml-2 text-xs">
42+
<div className="ml-1 hidden items-center text-xs sm:ml-2 sm:flex">
4343
<Star className="w-3 h-3 mr-1 fill-current text-yellow-500" />
4444
{formatStarCount(stargazers_count)}
4545
</div>

src/components/LanguageSelector.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@ const LanguageSelector = () => {
2222
return (
2323
<DropdownMenu>
2424
<DropdownMenuTrigger asChild>
25-
<Button variant="outline" size="sm" className="w-full h-8 px-3 justify-between">
25+
<Button variant="outline" size="sm" className="h-9 w-auto min-w-[44px] justify-center px-2 sm:min-w-[120px] sm:justify-between sm:px-3">
2626
<div className="flex items-center">
27-
<Globe className="w-4 h-4 mr-2" />
28-
<span className="mr-1">{currentLang?.flag}</span>
29-
<span>{currentLang?.name}</span>
27+
<Globe className="mr-0 h-4 w-4 sm:mr-2" />
28+
<span className="hidden sm:inline mr-1">{currentLang?.flag}</span>
29+
<span className="hidden sm:inline">{currentLang?.name}</span>
30+
<span className="sm:hidden">{currentLang?.flag}</span>
3031
</div>
3132
</Button>
3233
</DropdownMenuTrigger>
33-
<DropdownMenuContent align="start" className="w-full">
34+
<DropdownMenuContent align="end" className="min-w-[140px]">
3435
{languages.map((language) => (
3536
<DropdownMenuItem
3637
key={language.code}

src/pages/Index.tsx

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -70,50 +70,50 @@ const Index = () => {
7070
/>
7171
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50">
7272
{/* Header */}
73-
<header className="bg-white/80 backdrop-blur-md border-b border-slate-200 sticky top-0 z-50">
74-
<div className="container mx-auto px-4 py-4">
75-
<div className="flex items-center justify-between">
76-
<div className="flex items-center space-x-3 cursor-pointer" onClick={() => navigate('/')}>
77-
<div className="w-8 h-8 bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg flex items-center justify-center">
78-
<Code className="w-5 h-5 text-white" />
79-
</div>
80-
<div>
81-
<h1 className="text-xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
82-
{t("devToolkit")}
83-
</h1>
84-
<p className="text-xs text-slate-500">{t("supportDescription")}</p>
85-
</div>
86-
</div>
87-
<div className="flex items-center space-x-4">
73+
<header className="sticky top-0 z-50 border-b border-slate-200 bg-white/90 backdrop-blur-md">
74+
<div className="container mx-auto px-4 py-3 sm:py-4">
75+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
76+
<div className="flex min-w-0 items-center space-x-3 cursor-pointer" onClick={() => navigate('/')}>
77+
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gradient-to-r from-blue-600 to-purple-600">
78+
<Code className="w-5 h-5 text-white" />
79+
</div>
80+
<div className="min-w-0">
81+
<h1 className="truncate text-lg font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent sm:text-xl">
82+
{t("devToolkit")}
83+
</h1>
84+
<p className="truncate text-xs text-slate-500">{t("supportDescription")}</p>
85+
</div>
86+
</div>
87+
<div className="flex flex-wrap items-center gap-2 sm:justify-end sm:gap-3">
8888
<LanguageSelector />
8989
<GitHubButton
90-
owner="mingrammer"
91-
repo="devtoolkit"
92-
variant="compact"
93-
/>
90+
owner="mingrammer"
91+
repo="devtoolkit"
92+
variant="compact"
93+
/>
9494
<Button
9595
onClick={handleBuyMeCoffee}
96-
className="bg-[#FFDD00] hover:bg-[#FFCC00] text-black font-medium px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 border border-gray-300 hover:border-gray-400"
96+
className="h-9 bg-[#FFDD00] px-3 text-black transition-colors duration-200 hover:bg-[#FFCC00]"
9797
size="sm"
9898
>
9999
<img
100100
src="https://cdn.buymeacoffee.com/buttons/bmc-new-btn-logo.svg"
101101
alt="Buy me a coffee"
102-
className="w-5 h-5"
102+
className="h-4 w-4 sm:h-5 sm:w-5"
103103
/>
104-
<span>{t("buyMeCoffee")}</span>
104+
<span className="hidden sm:inline">{t("buyMeCoffee")}</span>
105105
</Button>
106106
</div>
107107
</div>
108108
</div>
109109
</header>
110110

111-
<div className="container mx-auto px-4 py-8">
112-
<div className="grid lg:grid-cols-12 gap-8">
111+
<div className="container mx-auto px-4 py-6 sm:py-8">
112+
<div className="grid gap-6 lg:grid-cols-12 lg:gap-8">
113113
{/* Main Contents */}
114-
<div className="lg:col-span-9">
115-
<div className="mb-8">
116-
<h2 className="text-3xl font-bold text-slate-800 mb-2">
114+
<div className="min-w-0 lg:col-span-9">
115+
<div className="mb-6 sm:mb-8">
116+
<h2 className="mb-2 text-2xl font-bold text-slate-800 sm:text-3xl">
117117
{t("developersEssential")}
118118
</h2>
119119
<p className="text-slate-600">
@@ -123,7 +123,7 @@ const Index = () => {
123123

124124
{/* Search Bar */}
125125
<div className="mb-6">
126-
<div className="relative max-w-md">
126+
<div className="relative max-w-full sm:max-w-md">
127127
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" />
128128
<Input
129129
placeholder={t("searchTools")}
@@ -151,7 +151,7 @@ const Index = () => {
151151
</div>
152152

153153
{/* Tools Grid */}
154-
<div className="grid md:grid-cols-3 lg:grid-cols-4 gap-4 mb-8">
154+
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 mb-8">
155155
{filteredTools.map((tool) => {
156156
const Icon = tool.icon;
157157

@@ -162,20 +162,20 @@ const Index = () => {
162162
onClick={() => handleToolClick(tool.id)}
163163
>
164164
<CardHeader className="pb-3">
165-
<div className="flex items-center space-x-3">
165+
<div className="flex items-start space-x-3">
166166
<div className={`w-10 h-10 ${tool.color} rounded-lg flex items-center justify-center`}>
167167
<Icon className="w-5 h-5 text-white" />
168168
</div>
169-
<div>
170-
<CardTitle className="text-sm">{tool.title}</CardTitle>
169+
<div className="min-w-0">
170+
<CardTitle className="line-clamp-2 text-sm leading-5">{tool.title}</CardTitle>
171171
<Badge variant="secondary" className="text-xs mt-1">
172172
{tool.category}
173173
</Badge>
174174
</div>
175175
</div>
176176
</CardHeader>
177177
<CardContent>
178-
<CardDescription className="text-xs">
178+
<CardDescription className="line-clamp-3 text-xs leading-5">
179179
{tool.description}
180180
</CardDescription>
181181
</CardContent>

src/pages/ToolPage.tsx

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useParams, Navigate } from "react-router-dom";
2-
import { SidebarProvider, SidebarInset } from "@/components/ui/sidebar";
2+
import { SidebarProvider, SidebarInset, SidebarTrigger } from "@/components/ui/sidebar";
33
import { ToolSidebar } from "@/components/ToolSidebar";
44
import { Button } from "@/components/ui/button";
55
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
@@ -102,56 +102,62 @@ const ToolPage = () => {
102102
<SidebarProvider>
103103
<div className="min-h-screen flex w-full">
104104
<ToolSidebar />
105-
<SidebarInset className="flex flex-col">
106-
{/* TopBar를 메인 콘텐츠 영역에만 적용 */}
107-
<div className="h-16 bg-white border-b border-slate-200 px-4 flex items-center justify-end sticky top-0 z-50">
108-
<div className="flex items-center space-x-4">
109-
<LanguageSelector />
110-
<GitHubButton
111-
owner="mingrammer"
112-
repo="devtoolkit"
113-
variant="compact"
114-
/>
115-
<Button
116-
onClick={() => window.open('https://buymeacoffee.com/mingrammer', '_blank')}
117-
className="bg-[#FFDD00] hover:bg-[#FFCC00] text-black font-medium px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 border border-gray-300 hover:border-gray-400"
118-
size="sm"
119-
>
120-
<img
121-
src="https://cdn.buymeacoffee.com/buttons/bmc-new-btn-logo.svg"
122-
alt="Buy me a coffee"
123-
className="w-5 h-5"
105+
<SidebarInset className="flex min-w-0 flex-col">
106+
<div className="sticky top-0 z-50 border-b border-slate-200 bg-white/95 backdrop-blur supports-[backdrop-filter]:bg-white/80">
107+
<div className="flex min-h-16 items-center gap-2 px-3 py-3 sm:px-4">
108+
<SidebarTrigger className="md:hidden" />
109+
<div className="min-w-0 flex-1">
110+
<div className="truncate text-sm font-semibold text-slate-900 sm:text-base">{tool.title}</div>
111+
<div className="truncate text-xs text-slate-500 sm:text-sm">{tool.category}</div>
112+
</div>
113+
<div className="flex shrink-0 items-center gap-2">
114+
<LanguageSelector />
115+
<GitHubButton
116+
owner="mingrammer"
117+
repo="devtoolkit"
118+
variant="compact"
124119
/>
125-
<span>{t("buyMeCoffee")}</span>
126-
</Button>
120+
<Button
121+
onClick={() => window.open('https://buymeacoffee.com/mingrammer', '_blank')}
122+
className="h-9 bg-[#FFDD00] px-3 text-black transition-colors duration-200 hover:bg-[#FFCC00]"
123+
size="sm"
124+
>
125+
<img
126+
src="https://cdn.buymeacoffee.com/buttons/bmc-new-btn-logo.svg"
127+
alt="Buy me a coffee"
128+
className="h-4 w-4 sm:h-5 sm:w-5"
129+
/>
130+
<span className="hidden sm:inline">{t("buyMeCoffee")}</span>
131+
</Button>
132+
</div>
127133
</div>
128134
</div>
129135

130-
<div className="flex-1 p-8">
131-
<Card className="shadow-lg">
132-
<CardHeader>
133-
<div className="flex items-center space-x-3">
134-
<div className={`w-12 h-12 ${tool.color} rounded-lg flex items-center justify-center`}>
135-
<tool.icon className="w-6 h-6 text-white" />
136+
<div className="flex-1 px-3 py-4 sm:px-4 sm:py-6 lg:p-8">
137+
<Card className="overflow-hidden shadow-lg">
138+
<CardHeader className="p-4 sm:p-6">
139+
<div className="flex items-start gap-3 sm:items-center sm:space-x-3">
140+
<div className={`flex h-11 w-11 shrink-0 items-center justify-center rounded-lg ${tool.color} sm:h-12 sm:w-12`}>
141+
<tool.icon className="h-5 w-5 text-white sm:h-6 sm:w-6" />
136142
</div>
137-
<div>
138-
<CardTitle className="text-2xl">{tool.title}</CardTitle>
139-
<CardDescription className="text-lg">{tool.description}</CardDescription>
143+
<div className="min-w-0">
144+
<CardTitle className="text-xl sm:text-2xl">{tool.title}</CardTitle>
145+
<CardDescription className="mt-1 text-sm leading-6 sm:text-base lg:text-lg">{tool.description}</CardDescription>
140146
</div>
141147
</div>
142148
</CardHeader>
143-
<CardContent className="pt-6">
149+
<CardContent className="p-4 pt-0 sm:p-6 sm:pt-2">
144150
{renderTool()}
145151
</CardContent>
146152
</Card>
147153

148-
<div className="mt-8">
154+
<div className="mt-6 sm:mt-8">
149155
<AnalyticsErrorBoundary>
150156
<AdBanner
151157
slot="6031323740"
152158
format="fluid"
153159
layoutKey="-fb+5w+4e-db+86"
154-
className="max-w-2xl mx-auto"
160+
className="mx-auto w-full max-w-2xl"
155161
style={{ minHeight: '250px' }}
156162
/>
157163
</AnalyticsErrorBoundary>

0 commit comments

Comments
 (0)