@stevederico/skateboard-ui 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/Layout.jsx +7 -9
- package/SettingsView.jsx +70 -75
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/Layout.jsx
CHANGED
|
@@ -41,15 +41,13 @@ export default function Layout({ children }) {
|
|
|
41
41
|
}, []);
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<div className="min-h-screen">
|
|
45
|
-
<
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
</SidebarProvider>
|
|
52
|
-
</div>
|
|
44
|
+
<div className="min-h-screen flex flex-col pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)] pl-[env(safe-area-inset-left)] pr-[env(safe-area-inset-right)]">
|
|
45
|
+
<SidebarProvider>
|
|
46
|
+
{!constants.hideSidebar && <AppSidebar />}
|
|
47
|
+
<main className="flex-1">
|
|
48
|
+
<Outlet />
|
|
49
|
+
</main>
|
|
50
|
+
</SidebarProvider>
|
|
53
51
|
<TabBar className="md:hidden" />
|
|
54
52
|
</div>
|
|
55
53
|
);
|
package/SettingsView.jsx
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useNavigate } from 'react-router-dom';
|
|
3
3
|
import { getState } from './Context.jsx';
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
|
-
import * as LucideIcons from "lucide-react";
|
|
6
4
|
import ThemeToggle from './ThemeToggle.jsx';
|
|
7
|
-
|
|
8
|
-
// Dynamic Icon Component
|
|
9
|
-
const DynamicIcon = ({ name, size = 24, color = 'currentColor', strokeWidth = 2, ...props }) => {
|
|
10
|
-
const toPascalCase = (str) => str.split(/[-_\s]/).map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join('');
|
|
11
|
-
const possibleNames = [name, toPascalCase(name), name.charAt(0).toUpperCase() + name.slice(1)];
|
|
12
|
-
const LucideIcon = possibleNames.find(n => LucideIcons[n]) ? LucideIcons[possibleNames.find(n => LucideIcons[n])] : null;
|
|
13
|
-
return LucideIcon ? React.createElement(LucideIcon, { size, color, strokeWidth, ...props }) : null;
|
|
14
|
-
};
|
|
15
5
|
import constants from "@/constants.json";
|
|
16
6
|
import pkg from '@package';
|
|
17
|
-
import { showCheckout } from './Utilities';
|
|
7
|
+
import { showCheckout, showManage } from './Utilities';
|
|
18
8
|
|
|
19
9
|
export default function SettingsView() {
|
|
20
10
|
const navigate = useNavigate();
|
|
@@ -26,89 +16,94 @@ export default function SettingsView() {
|
|
|
26
16
|
}
|
|
27
17
|
|
|
28
18
|
return (
|
|
29
|
-
<div className="
|
|
30
|
-
{/*
|
|
31
|
-
<div className="
|
|
32
|
-
|
|
33
|
-
<div className="
|
|
19
|
+
<div className="min-h-screen bg-background relative overflow-hidden">
|
|
20
|
+
{/* Content */}
|
|
21
|
+
<div className="relative z-10">
|
|
22
|
+
{/* Header */}
|
|
23
|
+
<div className="flex items-center justify-between px-6 py-4 border-b border-border">
|
|
24
|
+
<h1 className="text-lg font-medium">Settings</h1>
|
|
34
25
|
<ThemeToggle />
|
|
35
26
|
</div>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
{/* Main content */}
|
|
39
|
-
<div className="flex flex-col flex-1 items-center p-4 gap-6">
|
|
40
|
-
{(constants.noLogin == false || typeof constants.noLogin === 'undefined') && (
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
28
|
+
{/* Main content */}
|
|
29
|
+
<div className="flex flex-col items-center p-4 gap-4">
|
|
30
|
+
{/* User Card */}
|
|
31
|
+
{(constants.noLogin === false || typeof constants.noLogin === 'undefined') && (
|
|
32
|
+
<div className="w-full max-w-lg bg-accent rounded-2xl p-5">
|
|
33
|
+
<div className="flex items-center gap-4">
|
|
34
|
+
<div className="w-12 h-12 bg-app dark:text-black text-white flex justify-center items-center rounded-full font-medium">
|
|
35
|
+
<span className="uppercase">{state.user?.name?.split(' ').map(word => word[0]).join('') || "NA"}</span>
|
|
36
|
+
</div>
|
|
37
|
+
<div className="flex-1 min-w-0">
|
|
38
|
+
<div className="font-medium truncate capitalize">{state.user?.name || "No User"}</div>
|
|
39
|
+
<div className="text-sm text-muted-foreground">{state.user?.email || "no@user.com"}</div>
|
|
40
|
+
</div>
|
|
41
|
+
<button
|
|
42
|
+
onClick={signOutClicked}
|
|
43
|
+
className="px-4 py-2 rounded-full text-sm bg-sidebar-background border border-foreground/30 hover:border-foreground transition-all cursor-pointer"
|
|
44
|
+
>
|
|
45
|
+
Sign Out
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
57
50
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<div className="flex items-center">
|
|
51
|
+
{/* Support */}
|
|
52
|
+
<div className="w-full max-w-lg bg-accent rounded-2xl p-5">
|
|
53
|
+
<div className="flex items-center justify-between">
|
|
62
54
|
<div>
|
|
63
|
-
<div className="mb-
|
|
64
|
-
<div className="text-sm text-
|
|
65
|
-
</div>
|
|
66
|
-
<div className="ml-auto">
|
|
67
|
-
<div onClick={() => { window.location.href = `mailto:${constants.companyEmail}`; }} className="bg-sidebar-background text-center border-foreground border ml-2 px-3 py-2 rounded text-sm whitespace-nowrap cursor-pointer">Support</div>
|
|
55
|
+
<div className="mb-1 font-medium">Support</div>
|
|
56
|
+
<div className="text-sm text-muted-foreground">How can we help?</div>
|
|
68
57
|
</div>
|
|
58
|
+
<button
|
|
59
|
+
onClick={() => { window.location.href = `mailto:${constants.companyEmail}`; }}
|
|
60
|
+
className="px-4 py-2 rounded-full text-sm bg-sidebar-background border border-foreground/30 hover:border-foreground transition-all cursor-pointer"
|
|
61
|
+
>
|
|
62
|
+
Contact
|
|
63
|
+
</button>
|
|
69
64
|
</div>
|
|
70
65
|
</div>
|
|
71
|
-
</div>
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<div className="flex items-center">
|
|
67
|
+
{/* Billing */}
|
|
68
|
+
{(constants.noLogin === false || typeof constants.noLogin === 'undefined') && (
|
|
69
|
+
<div className="w-full max-w-lg bg-accent rounded-2xl p-5">
|
|
70
|
+
<div className="flex items-center justify-between">
|
|
78
71
|
<div>
|
|
79
|
-
<div className="mb-
|
|
80
|
-
<div className="text-sm text-
|
|
72
|
+
<div className="mb-1 font-medium">Billing</div>
|
|
73
|
+
<div className="text-sm text-muted-foreground">
|
|
81
74
|
{state.user?.subStatus === null || typeof state.user?.subStatus === 'undefined'
|
|
82
|
-
? "
|
|
75
|
+
? "Free plan"
|
|
83
76
|
: ["active", "canceled"].includes(state.user?.subStatus)
|
|
84
|
-
?
|
|
85
|
-
: `
|
|
77
|
+
? `${state.user?.subStatus === "active" ? "Renews" : "Ends"} ${new Date(state.user.expires * 1000).toLocaleDateString('en-US')}`
|
|
78
|
+
: `Plan ${state.user?.subStatus}`
|
|
86
79
|
}
|
|
87
80
|
</div>
|
|
88
81
|
</div>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
82
|
+
{state.user?.stripeID ? (
|
|
83
|
+
<button
|
|
84
|
+
onClick={() => { showManage(state.user?.stripeID) }}
|
|
85
|
+
className="px-4 py-2 rounded-full text-sm bg-sidebar-background border border-foreground/30 hover:border-foreground transition-all cursor-pointer"
|
|
86
|
+
>
|
|
87
|
+
Manage
|
|
88
|
+
</button>
|
|
89
|
+
) : (
|
|
90
|
+
<button
|
|
91
|
+
onClick={() => { showCheckout(state.user?.email) }}
|
|
92
|
+
className="px-5 py-2 bg-app text-white dark:text-black rounded-full text-sm font-medium hover:opacity-90 transition-all cursor-pointer"
|
|
93
|
+
>
|
|
94
|
+
Subscribe
|
|
95
|
+
</button>
|
|
96
|
+
)}
|
|
98
97
|
</div>
|
|
99
98
|
</div>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
</div>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
{/* Footer */}
|
|
103
|
+
<div className="mt-8 text-center pb-24 md:pb-8">
|
|
104
|
+
<div className="text-xs text-muted-foreground">v{pkg.version}</div>
|
|
105
|
+
</div>
|
|
107
106
|
</div>
|
|
108
107
|
</div>
|
|
109
|
-
|
|
110
|
-
|
|
111
108
|
);
|
|
112
109
|
}
|
|
113
|
-
|
|
114
|
-
|