Skip to content

Commit 04009cc

Browse files
committed
feature(sveltecourse):buy
1 parent 2fa7af9 commit 04009cc

13 files changed

Lines changed: 579 additions & 60 deletions

File tree

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import { browser } from '$app/environment';
2+
3+
import { initializeApp, getApps } from 'firebase/app';
4+
import {
5+
getAuth,
6+
signInWithEmailAndPassword,
7+
signInWithPopup,
8+
type AuthProvider,
9+
type Auth,
10+
createUserWithEmailAndPassword
11+
} from 'firebase/auth';
12+
import {
13+
getFirestore,
14+
collection,
15+
doc,
16+
addDoc,
17+
onSnapshot,
18+
Firestore,
19+
setDoc,
20+
type DocumentData,
21+
initializeFirestore
22+
} from 'firebase/firestore';
23+
import { httpsCallable, getFunctions, type Functions } from 'firebase/functions';
24+
import {
25+
getAnalytics,
26+
type Analytics,
27+
logEvent,
28+
type AnalyticsCallOptions
29+
} from 'firebase/analytics';
30+
31+
import { env } from '$env/dynamic/public';
32+
import { getStorage, type FirebaseStorage } from 'firebase/storage';
33+
34+
export const firebaseConfig = {
35+
apiKey: env.PUBLIC_FB_API_KEY,
36+
authDomain: env.PUBLIC_FB_AUTH_DOMAIN,
37+
projectId: env.PUBLIC_FB_PROJECT_ID,
38+
storageBucket: env.PUBLIC_FB_STORAGE_BUCKET,
39+
messagingSenderId: env.PUBLIC_FB_MESSAGE_SENDER_ID,
40+
appId: env.PUBLIC_FB_APP_ID,
41+
measurementId: env.PUBLIC_FB_MEASUREMENT_ID
42+
};
43+
44+
export let app = getApps().at(0);
45+
export let auth: Auth;
46+
export let firestore: Firestore;
47+
export let functions: Functions;
48+
export let storage: FirebaseStorage;
49+
export let analytics: Analytics;
50+
51+
if (
52+
!app &&
53+
browser &&
54+
firebaseConfig.apiKey &&
55+
firebaseConfig.authDomain &&
56+
firebaseConfig.projectId &&
57+
firebaseConfig.storageBucket &&
58+
firebaseConfig.messagingSenderId &&
59+
firebaseConfig.appId &&
60+
firebaseConfig.measurementId
61+
) {
62+
app = initializeApp(firebaseConfig);
63+
auth = getAuth(app);
64+
storage = getStorage(app);
65+
66+
// As httpOnly cookies are to be used, do not persist any state client side.
67+
// setPersistence(auth, browserSessionPersistence);
68+
firestore = initializeFirestore(app, { ignoreUndefinedProperties: true });
69+
functions = getFunctions(app);
70+
analytics = getAnalytics(app);
71+
} else {
72+
if (
73+
browser &&
74+
(!firebaseConfig.apiKey ||
75+
!firebaseConfig.authDomain ||
76+
!firebaseConfig.projectId ||
77+
!firebaseConfig.storageBucket ||
78+
!firebaseConfig.messagingSenderId ||
79+
!firebaseConfig.appId ||
80+
!firebaseConfig.measurementId)
81+
)
82+
console.debug('Skipping Firebase Initialization, check firebaseconfig.');
83+
}
84+
85+
/* AUTH */
86+
87+
const setCookie = (idToken: string) => {
88+
document.cookie = '__ccdlogin=' + idToken + ';max-age=3600';
89+
};
90+
91+
export const ccdSignInWithEmailAndPassword = async ({
92+
email,
93+
password
94+
}: {
95+
email: string;
96+
password: string;
97+
}) => {
98+
const userResponse = await signInWithEmailAndPassword(auth, email, password);
99+
const idToken = await userResponse.user.getIdToken();
100+
setCookie(idToken);
101+
};
102+
103+
export const ccdSignUpWithEmailAndPassword = async ({
104+
email,
105+
password
106+
}: {
107+
email: string;
108+
password: string;
109+
}) => {
110+
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
111+
const idToken = await userCredential.user.getIdToken();
112+
setCookie(idToken);
113+
};
114+
115+
export const ccdSignInWithPopUp = async (provider: AuthProvider) => {
116+
const result = await signInWithPopup(auth, provider);
117+
const idToken = await result.user.getIdToken();
118+
119+
if (!idToken) throw 'Missing id Token';
120+
setCookie(idToken);
121+
};
122+
123+
/* DB */
124+
export const updateUser = async (docRef: string, data: DocumentData) => {
125+
return setDoc(doc(firestore, docRef), data, { merge: true });
126+
};
127+
128+
/* STRIPE */
129+
export const addSubscription = async (price: string, uid: string) => {
130+
const userDoc = doc(collection(firestore, 'stripe-customers'), uid);
131+
return await addDoc(collection(userDoc, 'checkout_sessions'), {
132+
mode: 'payment',
133+
price,
134+
success_url: `${window.location.href}/welcome`,
135+
cancel_url: window.location.href
136+
});
137+
};
138+
139+
/* FUNCTIONS */
140+
export const openStripePortal = async () => {
141+
const functionRef = httpsCallable(functions, 'ext-firestore-stripe-payments-createPortalLink');
142+
const { data } = (await functionRef({
143+
returnUrl: window.location.href
144+
})) as { data: { url: string } };
145+
window.location.assign(data.url);
146+
};
147+
148+
/* Analytics */
149+
export const analyticsLogPageView = async (
150+
eventParams?: {
151+
page_title?: string;
152+
page_location?: string;
153+
page_path?: string;
154+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
155+
[key: string]: any;
156+
},
157+
options?: AnalyticsCallOptions
158+
) => {
159+
if (firebaseConfig.apiKey) {
160+
logEvent(analytics, 'page_view', eventParams, options);
161+
} else {
162+
console.debug('Skipping Firebase Analytics, no key specified.');
163+
}
164+
};

‎apps/sveltefirebase-com/src/lib/components/BuyButton.svelte‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎apps/sveltefirebase-com/src/routes/+layout.svelte‎

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,22 @@
11
<script lang="ts">
22
import '../app.postcss';
3-
import { AppShell, AppBar } from '@skeletonlabs/skeleton';
3+
import { AppShell, AppBar, Modal, initializeStores, Toast } from '@skeletonlabs/skeleton';
4+
initializeStores();
45
56
// Floating UI for Popups
67
import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom';
78
import { storePopup } from '@skeletonlabs/skeleton';
89
storePopup.set({ computePosition, autoUpdate, flip, shift, offset, arrow });
9-
10-
import { FirebaseApp } from 'sveltefire';
11-
import { initializeApp } from 'firebase/app';
12-
import { getFirestore } from 'firebase/firestore';
13-
import { getStorage } from 'firebase/storage';
14-
import { getAuth } from 'firebase/auth';
15-
16-
// Initialize Firebase
17-
const app = initializeApp({
18-
apiKey: 'AIzaSyC6HNoa2QaPsqnolKbeMQUd5_RR1KG_kOs',
19-
authDomain: 'codingcat-dev.firebaseapp.com',
20-
databaseURL: 'https://codingcat-dev.firebaseio.com',
21-
projectId: 'codingcat-dev',
22-
storageBucket: 'codingcat-dev.appspot.com',
23-
messagingSenderId: '67840007708',
24-
appId: '1:67840007708:web:cce11b8a7708056a3d89d9',
25-
measurementId: 'G-S7B60EGPMJ'
26-
});
27-
const firestore = getFirestore(app);
28-
const storage = getStorage(app);
29-
const auth = getAuth(app);
3010
</script>
3111

12+
<Modal />
13+
<Toast />
14+
3215
<!-- App Shell -->
3316
<AppShell>
3417
<svelte:fragment slot="header">
3518
<!-- App Bar -->
36-
<AppBar
37-
background="bg-gradient-to-r from-primary-600 via-primary-500 via-90% to-secondary-500 to-97%"
38-
>
19+
<AppBar background="">
3920
<svelte:fragment slot="lead">
4021
<a
4122
href="/"
@@ -78,7 +59,5 @@
7859
</svelte:fragment>
7960
</AppBar>
8061
</svelte:fragment>
81-
<FirebaseApp {auth} {firestore} {storage}>
82-
<slot />
83-
</FirebaseApp>
62+
<slot />
8463
</AppShell>

0 commit comments

Comments
 (0)