mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-10-24 12:35:03 +00:00
refactor(mobile): Remove i18n, expand core screens, update plan
BREAKING: Removed multi-language support (i18n) - will be re-added later Changes: - Removed i18n system (6 language files, LanguageContext) - Expanded WalletScreen, SettingsScreen, SwapScreen with more features - Added KurdistanSun component, HEZ/PEZ token icons - Added EditProfileScreen, WalletSetupScreen - Added button e2e tests (Profile, Settings, Wallet) - Updated plan: honest assessment - 42 nav buttons with mock data - Fixed terminology: Polkadot→Pezkuwi, Substrate→Bizinikiwi Reality check: UI complete with mock data, converting to production one-by-one
This commit is contained in:
1 parent
92e5831f7c
commit
24d6a942f8
110 files changed
+11157
-3260
No files matched your search
@@ -16,6 +16,16 @@ import { KurdistanColors } from '../theme/colors';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { supabase } from '../lib/supabase';
|
||||
|
||||
// Cross-platform alert helper
|
||||
const showAlert = (title: string, message: string, buttons?: Array<{text: string; onPress?: () => void}>) => {
|
||||
if (Platform.OS === 'web') {
|
||||
window.alert(`${title}\n\n${message}`);
|
||||
if (buttons?.[0]?.onPress) buttons[0].onPress();
|
||||
} else {
|
||||
showAlert(title, message, buttons);
|
||||
}
|
||||
};
|
||||
|
||||
// Avatar pool - Kurdish/Middle Eastern themed avatars
|
||||
const AVATAR_POOL = [
|
||||
{ id: 'avatar1', emoji: '👨🏻', label: 'Man 1' },
|
||||
@@ -74,7 +84,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
if (Platform.OS !== 'web') {
|
||||
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||
if (status !== 'granted') {
|
||||
Alert.alert(
|
||||
showAlert(
|
||||
'Permission Required',
|
||||
'Sorry, we need camera roll permissions to upload your photo!'
|
||||
);
|
||||
@@ -111,63 +121,88 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
if (__DEV__) console.log('[AvatarPicker] Upload successful:', uploadedUrl);
|
||||
setUploadedImageUri(uploadedUrl);
|
||||
setSelectedAvatar(null); // Clear emoji selection
|
||||
Alert.alert('Success', 'Photo uploaded successfully!');
|
||||
showAlert('Success', 'Photo uploaded successfully!');
|
||||
} else {
|
||||
if (__DEV__) console.error('[AvatarPicker] Upload failed: no URL returned');
|
||||
Alert.alert('Upload Failed', 'Could not upload your photo. Please check your internet connection and try again.');
|
||||
showAlert('Upload Failed', 'Could not upload your photo. Please check your internet connection and try again.');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
setIsUploading(false);
|
||||
if (__DEV__) console.error('[AvatarPicker] Error picking image:', error);
|
||||
Alert.alert('Error', 'Failed to pick image. Please try again.');
|
||||
showAlert('Error', 'Failed to pick image. Please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const uploadImageToSupabase = async (imageUri: string): Promise<string | null> => {
|
||||
if (!user) {
|
||||
if (__DEV__) console.error('[AvatarPicker] No user found');
|
||||
console.error('[AvatarPicker] No user found');
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (__DEV__) console.log('[AvatarPicker] Fetching image blob...');
|
||||
// Convert image URI to blob for web, or use file for native
|
||||
console.log('[AvatarPicker] Starting upload for URI:', imageUri.substring(0, 50) + '...');
|
||||
|
||||
// Convert image URI to blob
|
||||
const response = await fetch(imageUri);
|
||||
const blob = await response.blob();
|
||||
if (__DEV__) console.log('[AvatarPicker] Blob size:', blob.size, 'bytes');
|
||||
console.log('[AvatarPicker] Blob created - size:', blob.size, 'bytes, type:', blob.type);
|
||||
|
||||
// Generate unique filename
|
||||
const fileExt = imageUri.split('.').pop()?.toLowerCase() || 'jpg';
|
||||
const fileName = `${user.id}-${Date.now()}.${fileExt}`;
|
||||
const filePath = `avatars/${fileName}`;
|
||||
if (__DEV__) console.log('[AvatarPicker] Uploading to:', filePath);
|
||||
|
||||
// Upload to Supabase Storage
|
||||
const { data: uploadData, error: uploadError } = await supabase.storage
|
||||
.from('profiles')
|
||||
.upload(filePath, blob, {
|
||||
contentType: `image/${fileExt}`,
|
||||
upsert: false,
|
||||
});
|
||||
|
||||
if (uploadError) {
|
||||
if (__DEV__) console.error('[AvatarPicker] Upload error:', uploadError);
|
||||
if (blob.size === 0) {
|
||||
console.error('[AvatarPicker] Blob is empty!');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (__DEV__) console.log('[AvatarPicker] Upload successful:', uploadData);
|
||||
// Get file extension from blob type or URI
|
||||
let fileExt = 'jpg';
|
||||
if (blob.type) {
|
||||
// Extract extension from MIME type (e.g., 'image/jpeg' -> 'jpeg')
|
||||
const mimeExt = blob.type.split('/')[1];
|
||||
if (mimeExt && mimeExt !== 'octet-stream') {
|
||||
fileExt = mimeExt === 'jpeg' ? 'jpg' : mimeExt;
|
||||
}
|
||||
} else if (!imageUri.startsWith('blob:') && !imageUri.startsWith('data:')) {
|
||||
// Try to get extension from URI for non-blob URIs
|
||||
const uriExt = imageUri.split('.').pop()?.toLowerCase();
|
||||
if (uriExt && ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(uriExt)) {
|
||||
fileExt = uriExt;
|
||||
}
|
||||
}
|
||||
|
||||
const fileName = `${user.id}-${Date.now()}.${fileExt}`;
|
||||
const filePath = `avatars/${fileName}`;
|
||||
const contentType = blob.type || `image/${fileExt}`;
|
||||
|
||||
console.log('[AvatarPicker] Uploading to path:', filePath, 'contentType:', contentType);
|
||||
|
||||
// Upload to Supabase Storage
|
||||
const { data: uploadData, error: uploadError } = await supabase.storage
|
||||
.from('avatars')
|
||||
.upload(filePath, blob, {
|
||||
contentType: contentType,
|
||||
upsert: true, // Allow overwriting if file exists
|
||||
});
|
||||
|
||||
if (uploadError) {
|
||||
console.error('[AvatarPicker] Supabase upload error:', uploadError.message, uploadError);
|
||||
// Show more specific error to user
|
||||
showAlert('Upload Error', `Storage error: ${uploadError.message}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log('[AvatarPicker] Upload successful:', uploadData);
|
||||
|
||||
// Get public URL
|
||||
const { data } = supabase.storage
|
||||
.from('profiles')
|
||||
.from('avatars')
|
||||
.getPublicUrl(filePath);
|
||||
|
||||
if (__DEV__) console.log('[AvatarPicker] Public URL:', data.publicUrl);
|
||||
console.log('[AvatarPicker] Public URL:', data.publicUrl);
|
||||
|
||||
return data.publicUrl;
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('[AvatarPicker] Error uploading to Supabase:', error);
|
||||
} catch (error: any) {
|
||||
console.error('[AvatarPicker] Error uploading to Supabase:', error?.message || error);
|
||||
showAlert('Upload Error', `Failed to upload: ${error?.message || 'Unknown error'}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -176,7 +211,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
const avatarToSave = uploadedImageUri || selectedAvatar;
|
||||
|
||||
if (!avatarToSave || !user) {
|
||||
Alert.alert('Error', 'Please select an avatar or upload a photo');
|
||||
showAlert('Error', 'Please select an avatar or upload a photo');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -199,7 +234,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
|
||||
if (__DEV__) console.log('[AvatarPicker] Avatar saved successfully:', data);
|
||||
|
||||
Alert.alert('Success', 'Avatar updated successfully!');
|
||||
showAlert('Success', 'Avatar updated successfully!');
|
||||
|
||||
if (onAvatarSelected) {
|
||||
onAvatarSelected(avatarToSave);
|
||||
@@ -208,7 +243,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
onClose();
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('[AvatarPicker] Error updating avatar:', error);
|
||||
Alert.alert('Error', 'Failed to update avatar. Please try again.');
|
||||
showAlert('Error', 'Failed to update avatar. Please try again.');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { View, Animated, Easing, StyleSheet } from 'react-native';
|
||||
import Svg, { Circle, Line, Defs, RadialGradient, Stop } from 'react-native-svg';
|
||||
|
||||
interface KurdistanSunProps {
|
||||
size?: number;
|
||||
}
|
||||
|
||||
const AnimatedView = Animated.View;
|
||||
|
||||
export const KurdistanSun: React.FC<KurdistanSunProps> = ({ size = 200 }) => {
|
||||
// Animation values
|
||||
const greenHaloRotation = useRef(new Animated.Value(0)).current;
|
||||
const redHaloRotation = useRef(new Animated.Value(0)).current;
|
||||
const yellowHaloRotation = useRef(new Animated.Value(0)).current;
|
||||
const raysPulse = useRef(new Animated.Value(1)).current;
|
||||
const glowPulse = useRef(new Animated.Value(0.6)).current;
|
||||
|
||||
useEffect(() => {
|
||||
// Green halo rotation (3s, clockwise)
|
||||
Animated.loop(
|
||||
Animated.timing(greenHaloRotation, {
|
||||
toValue: 1,
|
||||
duration: 3000,
|
||||
easing: Easing.linear,
|
||||
useNativeDriver: true,
|
||||
})
|
||||
).start();
|
||||
|
||||
// Red halo rotation (2.5s, counter-clockwise)
|
||||
Animated.loop(
|
||||
Animated.timing(redHaloRotation, {
|
||||
toValue: -1,
|
||||
duration: 2500,
|
||||
easing: Easing.linear,
|
||||
useNativeDriver: true,
|
||||
})
|
||||
).start();
|
||||
|
||||
// Yellow halo rotation (2s, clockwise)
|
||||
Animated.loop(
|
||||
Animated.timing(yellowHaloRotation, {
|
||||
toValue: 1,
|
||||
duration: 2000,
|
||||
easing: Easing.linear,
|
||||
useNativeDriver: true,
|
||||
})
|
||||
).start();
|
||||
|
||||
// Rays pulse animation
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(raysPulse, {
|
||||
toValue: 0.7,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(raysPulse, {
|
||||
toValue: 1,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
])
|
||||
).start();
|
||||
|
||||
// Glow pulse animation
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(glowPulse, {
|
||||
toValue: 0.3,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(glowPulse, {
|
||||
toValue: 0.6,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
])
|
||||
).start();
|
||||
}, []);
|
||||
|
||||
const greenSpin = greenHaloRotation.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['0deg', '360deg'],
|
||||
});
|
||||
|
||||
const redSpin = redHaloRotation.interpolate({
|
||||
inputRange: [-1, 0],
|
||||
outputRange: ['-360deg', '0deg'],
|
||||
});
|
||||
|
||||
const yellowSpin = yellowHaloRotation.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['0deg', '360deg'],
|
||||
});
|
||||
|
||||
const haloSize = size * 0.9;
|
||||
const borderWidth = size * 0.02;
|
||||
|
||||
// Generate 21 rays for Kurdistan flag
|
||||
const rays = Array.from({ length: 21 }).map((_, i) => {
|
||||
const angle = (i * 360) / 21;
|
||||
return (
|
||||
<Line
|
||||
key={i}
|
||||
x1="100"
|
||||
y1="100"
|
||||
x2="100"
|
||||
y2="20"
|
||||
stroke="rgba(255, 255, 255, 0.9)"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="round"
|
||||
transform={`rotate(${angle} 100 100)`}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { width: size, height: size }]}>
|
||||
{/* Rotating colored halos */}
|
||||
<View style={styles.halosContainer}>
|
||||
{/* Green halo (outermost) */}
|
||||
<AnimatedView
|
||||
style={[
|
||||
styles.halo,
|
||||
{
|
||||
width: haloSize,
|
||||
height: haloSize,
|
||||
borderWidth: borderWidth,
|
||||
borderTopColor: '#00FF00',
|
||||
borderBottomColor: '#00FF00',
|
||||
borderLeftColor: 'transparent',
|
||||
borderRightColor: 'transparent',
|
||||
transform: [{ rotate: greenSpin }],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{/* Red halo (middle) */}
|
||||
<AnimatedView
|
||||
style={[
|
||||
styles.halo,
|
||||
{
|
||||
width: haloSize * 0.8,
|
||||
height: haloSize * 0.8,
|
||||
borderWidth: borderWidth,
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent',
|
||||
borderLeftColor: '#FF0000',
|
||||
borderRightColor: '#FF0000',
|
||||
transform: [{ rotate: redSpin }],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{/* Yellow halo (inner) */}
|
||||
<AnimatedView
|
||||
style={[
|
||||
styles.halo,
|
||||
{
|
||||
width: haloSize * 0.6,
|
||||
height: haloSize * 0.6,
|
||||
borderWidth: borderWidth,
|
||||
borderTopColor: '#FFD700',
|
||||
borderBottomColor: '#FFD700',
|
||||
borderLeftColor: 'transparent',
|
||||
borderRightColor: 'transparent',
|
||||
transform: [{ rotate: yellowSpin }],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Kurdistan Sun SVG with 21 rays */}
|
||||
<AnimatedView style={[styles.svgContainer, { opacity: raysPulse }]}>
|
||||
<Svg width={size} height={size} viewBox="0 0 200 200">
|
||||
<Defs>
|
||||
<RadialGradient id="sunGradient" cx="50%" cy="50%" r="50%">
|
||||
<Stop offset="0%" stopColor="rgba(255, 255, 255, 0.8)" />
|
||||
<Stop offset="100%" stopColor="rgba(255, 255, 255, 0.2)" />
|
||||
</RadialGradient>
|
||||
</Defs>
|
||||
|
||||
{/* Sun rays (21 rays for Kurdistan flag) */}
|
||||
{rays}
|
||||
|
||||
{/* Central white circle */}
|
||||
<Circle cx="100" cy="100" r="35" fill="white" />
|
||||
|
||||
{/* Inner glow */}
|
||||
<Circle cx="100" cy="100" r="35" fill="url(#sunGradient)" />
|
||||
</Svg>
|
||||
</AnimatedView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
halosContainer: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
halo: {
|
||||
position: 'absolute',
|
||||
borderRadius: 1000,
|
||||
},
|
||||
svgContainer: {
|
||||
position: 'relative',
|
||||
zIndex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default KurdistanSun;
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import Svg, { Path } from 'react-native-svg';
|
||||
|
||||
interface HezTokenLogoProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const HezTokenLogo: React.FC<HezTokenLogoProps> = ({ size = 56, color = '#008F43' }) => {
|
||||
return (
|
||||
<Svg width={size} height={size} viewBox="0 0 512 512">
|
||||
<Path
|
||||
d="M 240.402 48.006 C 188.287 52.314, 141.167 74.788, 105.116 112.532 C 85.299 133.279, 70.297 157.132, 60.517 183.445 C 45.191 224.681, 43.424 271.913, 55.632 314 C 66.010 349.774, 84.148 379.521, 111.800 406.115 C 142.943 436.066, 183.126 456.011, 225.500 462.550 C 265.416 468.710, 307.444 462.361, 344.500 444.573 C 367.134 433.708, 383.681 422.257, 400.866 405.567 C 435.893 371.548, 457.593 327.727, 462.986 280.125 C 464.375 267.864, 464.362 243.699, 462.961 231.899 C 453.905 155.652, 403.240 90.112, 331.500 61.843 C 303.262 50.716, 269.556 45.596, 240.402 48.006 M 233.179 59.074 C 147.987 70.131, 79.855 132.246, 62.152 215 C 57.094 238.645, 56.786 269.179, 61.367 293 C 71.695 346.708, 104.970 395.534, 150.479 423.756 C 186.629 446.176, 225.285 456.029, 268.500 453.842 C 306.424 451.922, 346.772 436.429, 378.500 411.603 C 386.798 405.110, 402.993 389.002, 410.273 380 C 430.556 354.919, 444.289 325.072, 450.661 292.222 C 453.042 279.945, 453.324 276.184, 453.336 256.500 C 453.348 238.118, 452.990 232.536, 451.159 222.555 C 443.603 181.369, 426.398 147.679, 398.108 118.674 C 366.039 85.794, 327.430 66.100, 282.318 59.609 C 270.415 57.896, 244.433 57.613, 233.179 59.074 M 236.500 63.024 C 208.140 66.234, 180.222 75.547, 156.645 89.661 C 144.403 96.990, 128.260 110, 116.962 121.643 C 88.834 150.629, 72.161 183.296, 64.837 223.766 C 61.687 241.177, 61.697 270.627, 64.860 288.381 C 85.862 406.257, 204.708 477.538, 317.420 439.859 C 364.230 424.212, 404.533 389.796, 427.395 345.949 C 443.039 315.948, 449.504 289.201, 449.378 255 C 449.262 223.348, 443.184 197.400, 429.467 170 C 401.751 114.634, 350.151 76.067, 289 65.011 C 275.773 62.619, 249.021 61.607, 236.500 63.024 M 238 74.167 C 227.196 75.186, 209.419 78.965, 198.143 82.639 C 186.880 86.309, 163.821 97.911, 153.331 105.185 C 119.901 128.367, 95.400 160.672, 82.905 198.041 C 64.936 251.786, 72.865 311.348, 104.165 357.743 C 162.894 444.794, 281.853 465.036, 365.300 402.177 C 378.530 392.210, 386.126 385.002, 396.196 372.856 C 426.577 336.213, 441.370 290.436, 437.945 243.669 C 435.469 209.863, 426.068 182.357, 407.468 154.500 C 377.015 108.891, 326.565 78.931, 271.929 74.007 C 259.651 72.901, 251.004 72.942, 238 74.167 M 236 82.637 C 168.575 90.905, 111.876 137.179, 90.478 201.402 C 83.833 221.346, 82.497 230.695, 82.528 257 C 82.555 279.195, 82.712 281.160, 85.358 292.383 C 88.955 307.636, 93.954 321.949, 99.689 333.409 C 124.128 382.249, 168.812 416.192, 223.166 427.204 C 232.949 429.186, 237.511 429.500, 256.500 429.500 C 275.813 429.500, 279.844 429.213, 289.500 427.148 C 325.709 419.406, 354.192 404.048, 379.550 378.592 C 403.979 354.069, 419.602 324.816, 427.130 289.500 C 429.195 279.816, 429.475 275.809, 429.475 256 C 429.475 230.918, 428.125 221.714, 421.449 201.296 C 404.744 150.198, 362.515 107.926, 310.937 90.669 C 292.846 84.617, 281.120 82.765, 259 82.469 C 248.275 82.325, 237.925 82.401, 236 82.637 M 236 94.682 C 214.128 98.265, 200.483 102.506, 183.500 110.997 C 167.444 119.025, 154.771 128.229, 141.500 141.500 C 118.516 164.484, 103.683 191.789, 96.815 223.755 C 94.792 233.172, 94.510 237.218, 94.536 256.500 C 94.563 276.526, 94.799 279.532, 97.170 290 C 109.918 346.305, 150.312 391.653, 203.706 409.605 C 225.033 416.775, 253.872 419.773, 275.422 417.061 C 312.179 412.434, 345.539 395.954, 371.500 369.596 C 393.551 347.207, 408.236 319.700, 415.195 287.749 C 417.117 278.922, 417.427 274.517, 417.427 256 C 417.427 237.384, 417.122 233.091, 415.153 224 C 411.852 208.750, 407.767 197.097, 400.957 183.500 C 392.881 167.373, 383.724 154.759, 370.483 141.517 C 357.146 128.180, 344.492 118.987, 328.500 111.016 C 303.816 98.712, 282.945 93.909, 255.151 94.136 C 245.993 94.211, 237.375 94.457, 236 94.682 M 170.903 221.262 C 168.925 224.143, 156.882 241.497, 144.142 259.827 C 131.401 278.157, 121.234 293.570, 121.548 294.077 C 121.870 294.598, 132.268 295, 145.433 295 L 168.748 295 180.103 278.750 C 186.348 269.813, 193.375 259.870, 195.717 256.656 L 199.976 250.813 195.905 245.156 C 193.666 242.045, 188.159 234.217, 183.667 227.760 C 179.175 221.302, 175.275 216.020, 175 216.021 C 174.725 216.023, 172.881 218.381, 170.903 221.262 M 331.483 220.750 C 330.027 222.813, 325.001 229.900, 320.315 236.500 C 315.629 243.100, 311.574 249.045, 311.305 249.712 C 310.858 250.819, 316.593 259.634, 334.077 284.714 L 340.500 293.928 364.809 293.964 C 383.360 293.991, 388.944 293.718, 388.382 292.810 C 387.978 292.155, 383.373 285.517, 378.150 278.060 C 365.190 259.554, 347.489 234.127, 341.039 224.750 C 338.107 220.488, 335.353 217, 334.919 217 C 334.485 217, 332.938 218.688, 331.483 220.750 M 190 342 L 190 364 194.961 364 L 199.922 364 200.211 355.250 L 200.500 346.500 210.250 346.214 L 220 345.928 220 354.964 L 220 364 225.500 364 L 231 364 231 342 L 231 320 225.500 320 L 220 320 220 328.500 L 220 337 210 337 L 200 337 200 328.500 L 200 320 195 320 L 190 320 190 342 M 242 342 L 242 364 260 364 L 278 364 278 360.031 L 278 356.062 265.750 355.781 L 253.50Line truncated
|
||||
fill={color}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default HezTokenLogo;
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import Svg, { Path } from 'react-native-svg';
|
||||
|
||||
interface PezTokenLogoProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
const PezTokenLogo: React.FC<PezTokenLogoProps> = ({ size = 56, color = '#E91E8C' }) => {
|
||||
return (
|
||||
<Svg width={size} height={size} viewBox="0 0 438 432">
|
||||
<Path
|
||||
d="M 208.901 25.091 C 191.281 26.521, 171.341 32.757, 162.127 39.718 C 144.423 53.094, 142.934 71.787, 158.464 85.684 C 164.067 90.697, 173.626 96.040, 180.500 97.999 C 182.700 98.626, 185.400 99.507, 186.500 99.956 C 191.458 101.982, 203.602 103.367, 216.075 103.328 C 228.468 103.290, 242.003 101.684, 244.500 99.954 C 245.050 99.573, 247.119 98.970, 249.097 98.614 C 251.076 98.258, 255.126 96.822, 258.097 95.424 C 261.069 94.025, 264.637 92.345, 266.027 91.690 C 273.628 88.110, 280.085 81.181, 283.750 72.672 C 286.780 65.638, 283.900 53.747, 277.296 46.033 C 269.226 36.605, 250.594 28.338, 232 25.936 C 219.802 24.360, 218.492 24.312, 208.901 25.091 M 96.077 76.530 C 59.862 86.663, 29.574 136.071, 38.521 170.420 C 42.739 186.612, 56.103 194.651, 72.022 190.573 C 108.479 181.233, 139.544 131.382, 130.513 96.711 C 126.181 80.078, 112.355 71.976, 96.077 76.530 M 319.500 79.928 C 316.035 80.763, 309.278 84.869, 306.797 87.647 C 299.895 95.374, 297.270 112.165, 300.487 128 C 305.453 152.445, 325.298 179.051, 346.662 189.908 C 360.444 196.911, 371.703 197.506, 380.558 191.698 C 403.034 176.956, 396.637 132.378, 367.563 101.133 C 353.343 85.851, 332.703 76.745, 319.500 79.928 M 275.044 122.461 C 281.020 125.575, 288 133.158, 288 136.537 C 288 139.936, 286.042 138.703, 285.864 135.191 C 285.749 132.917, 285.662 132.840, 285.302 134.695 C 284.756 137.502, 282.006 136.630, 281.985 133.643 C 281.973 132.059, 281.745 131.854, 281.110 132.857 C 279.832 134.874, 276.555 133.410, 275.258 130.243 L 274.136 127.500 274.676 130.250 C 275.127 132.543, 274.871 133, 273.134 133 C 271.841 133, 270.475 131.886, 269.533 130.063 C 268.698 128.448, 267.560 126.846, 267.005 126.503 C 266.451 126.160, 266.932 127.465, 268.075 129.402 L 270.152 132.924 267.563 133.573 C 266.032 133.958, 264.357 133.711, 263.464 132.970 C 262.217 131.935, 262.057 131.985, 262.544 133.255 C 262.904 134.192, 262.249 135.413, 260.866 136.381 C 258.747 137.865, 258.430 137.823, 256.056 135.735 L 253.514 133.500 255.395 135.731 C 256.936 137.559, 257.048 138.237, 256.016 139.481 C 254.410 141.416, 252.589 141.414, 250.980 139.476 C 250.284 138.638, 249.482 138.185, 249.197 138.470 C 248.912 138.755, 249.430 139.817, 250.348 140.832 C 251.909 142.557, 251.897 142.783, 250.153 144.362 C 248.396 145.952, 248.038 145.905, 243.895 143.536 C 237.755 140.027, 236.611 140.368, 242.339 144 C 246.492 146.633, 246.939 147.245, 246 149 C 244.671 151.484, 243.949 151.490, 239.807 149.056 C 235.517 146.534, 227.813 144.787, 226.550 146.050 C 225.950 146.650, 226.687 147.004, 228.550 147.010 C 232.407 147.023, 241.667 151.358, 241.667 153.151 C 241.667 155.111, 235.335 154.833, 231.300 152.695 C 227.908 150.899, 222.490 150.366, 223.453 151.924 C 224.327 153.337, 218.262 157.224, 216.251 156.540 C 213.131 155.478, 210.562 152.536, 207.500 146.520 C 203.736 139.124, 193.138 127.694, 186.529 123.903 C 183.763 122.317, 181.050 121.035, 180.500 121.056 C 179.950 121.076, 181.548 122.160, 184.050 123.464 C 189.829 126.475, 198.203 133.981, 202.095 139.638 C 205.189 144.134, 205.200 146, 202.135 146 C 201.174 146, 197.589 146.945, 194.168 148.101 C 189.003 149.845, 187.682 149.981, 186.381 148.901 C 184.994 147.750, 185.198 147.268, 188.157 144.704 L 191.500 141.807 187.663 144.039 L 183.826 146.271 181.726 144.171 C 179.644 142.089, 179.643 142.051, 181.563 139.785 L 183.500 137.500 181.250 139.405 C 179.071 141.250, 178.937 141.253, 176.984 139.486 L 174.969 137.662 177.234 135.081 L 179.500 132.500 176.890 134.792 C 174.622 136.785, 173.940 136.930, 171.672 135.896 C 170.237 135.242, 169.343 134.254, 169.686 133.699 C 170.050 133.110, 169.806 133.002, 169.098 133.440 C 166.955 134.764, 163.008 133.181, 163.611 131.240 C 164.119 129.602, 164.085 129.603, 163.026 131.250 C 162.407 132.213, 160.831 133, 159.524 133 C 158.101 133, 156.963 132.298, 156.689 131.250 C 156.280 129.685, 156.220 129.678, 156.116 131.183 C 155.991 133.001, 152.651 134.520, 151.009 133.506 C 150.454 133.163, 150 133.535, 150 134.334 C 150 136.816, 147.170 137.125, 146.698 134.695 C 146.346 132.880, 146.249 132.976, 146.136 135.250 C 145.980 138.411, 144 139.051, 144 135.941 C 144 134.801, 143.546 134.162, 142.984 134.510 C 142.425 134.856, 142.226 135.557, 142.543 136.069 C 142.859 136.581, 142.656 137, 142.090 137 C 141.525 137, 141.350 137.749, 141.701 138.664 C 142.089 139.674, 141.937 140.079, 141.316 139.695 C 139.856 138.793, 138.137 143.109, 136.456 151.895 C 132.902 170.467, 136.211 188.338, 145.075 198.432 C 149.354 203.306, 158.145 207.528, 160.920 206.043 C 163.721 204.544, 163.538 203.331, 160.250 201.621 C 147.804 195.146, 143.947 167.785, 153.530 153.956 C 156.642 149.466, 159.665 147.999, 165.797 148.004 C 173.187 148.010, 180.759 153.738, 185.025 162.552 C 186.846 166.313, 187.049 167.596, 186.141 169.591 L 185.029 172.029 180.978 167.978 C 178.750 165.750, 176.525 164.176, 176.033 164.480 C 175.541 164.784, 174.813 164.506, 174.415 163.862 C 173.963 163.131, 174.124 162.959, 174Line truncated
|
||||
fill={color}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default PezTokenLogo;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as HezTokenLogo } from './HezTokenLogo';
|
||||
export { default as PezTokenLogo } from './PezTokenLogo';
|
||||
Reference in new issue
Block a user